PageSourceSearch

https://www.santaprisca.it/media/vendor/bootstrap/js/tab.js?5.3.8

js santaprisca.it collected 2026-09-24 21:54:43 UTC 11,159 bytes, 332 lines download raw bytes

vendor: 7,041 bytes, lines 1-195
1import { E as EventHandler, f as isDisabled, S as SelectorEngine, d as defineJQueryPlugin, B as BaseComponent, b as getNextActiveElement } from './dom.js?5.3.8';
2
3/**
4 * --------------------------------------------------------------------------
5 * Bootstrap tab.js
6 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
7 * --------------------------------------------------------------------------
8 */
9
10
11/**
12 * Constants
13 */
14
15const NAME = 'tab';
16const DATA_KEY = 'bs.tab';
17const EVENT_KEY = `.${DATA_KEY}`;
18const EVENT_HIDE = `hide${EVENT_KEY}`;
19const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
20const EVENT_SHOW = `show${EVENT_KEY}`;
21const EVENT_SHOWN = `shown${EVENT_KEY}`;
22const EVENT_CLICK_DATA_API = `click${EVENT_KEY}`;
23const EVENT_KEYDOWN = `keydown${EVENT_KEY}`;
24const EVENT_LOAD_DATA_API = `load${EVENT_KEY}`;
25const ARROW_LEFT_KEY = 'ArrowLeft';
26const ARROW_RIGHT_KEY = 'ArrowRight';
27const ARROW_UP_KEY = 'ArrowUp';
28const ARROW_DOWN_KEY = 'ArrowDown';
29const HOME_KEY = 'Home';
30const END_KEY = 'End';
31const CLASS_NAME_ACTIVE = 'active';
32const CLASS_NAME_FADE = 'fade';
33const CLASS_NAME_SHOW = 'show';
34const CLASS_DROPDOWN = 'dropdown';
35const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
36const SELECTOR_DROPDOWN_MENU = '.dropdown-menu';
37const NOT_SELECTOR_DROPDOWN_TOGGLE = `:not(${SELECTOR_DROPDOWN_TOGGLE})`;
38const SELECTOR_TAB_PANEL = '.list-group, .nav, [role="tablist"]';
39const SELECTOR_OUTER = '.nav-item, .list-group-item';
40const SELECTOR_INNER = `.nav-link${NOT_SELECTOR_DROPDOWN_TOGGLE}, .list-group-item${NOT_SELECTOR_DROPDOWN_TOGGLE}, [role="tab"]${NOT_SELECTOR_DROPDOWN_TOGGLE}`;
41const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]'; // TODO: could only be `tab` in v6
42const SELECTOR_INNER_ELEM = `${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`;
43const SELECTOR_DATA_TOGGLE_ACTIVE = `.${CLASS_NAME_ACTIVE}[data-bs-toggle="tab"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="pill"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="list"]`;
44
45/**
46 * Class definition
47 */
48
49class Tab extends BaseComponent {
50  constructor(element) {
51    super(element);
52    this._parent = this._element.closest(SELECTOR_TAB_PANEL);
53    if (!this._parent) {
54      return;
55      // TODO: should throw exception in v6
56      // throw new TypeError(`${element.outerHTML} has not a valid parent ${SELECTOR_INNER_ELEM}`)
57    }
58
59    // Set up initial aria attributes
60    this._setInitialAttributes(this._parent, this._getChildren());
61    EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event));
62  }
63
64  // Getters
65  static get NAME() {
66    return NAME;
67  }
68
69  // Public
70  show() {
71    // Shows this elem and deactivate the active sibling if exists
72    const innerElem = this._element;
73    if (this._elemIsActive(innerElem)) {
74      return;
75    }
76
77    // Search for active tab on same parent to deactivate it
78    const active = this._getActiveElem();
79    const hideEvent = active ? EventHandler.trigger(active, EVENT_HIDE, {
80      relatedTarget: innerElem
81    }) : null;
82    const showEvent = EventHandler.trigger(innerElem, EVENT_SHOW, {
83      relatedTarget: active
84    });
85    if (showEvent.defaultPrevented || hideEvent && hideEvent.defaultPrevented) {
86      return;
87    }
88    this._deactivate(active, innerElem);
89    this._activate(innerElem, active);
90  }
91
92  // Private
93  _activate(element, relatedElem) {
94    if (!element) {
95      return;
96    }
97    element.classList.add(CLASS_NAME_ACTIVE);
98    this._activate(SelectorEngine.getElementFromSelector(element)); // Search and activate/show the proper section
99
100    const complete = () => {
101      if (element.getAttribute('role') !== 'tab') {
102        element.classList.add(CLASS_NAME_SHOW);
103        return;
104      }
105      element.removeAttribute('tabindex');
106      element.setAttribute('aria-selected', true);
107      this._toggleDropDown(element, true);
108      EventHandler.trigger(element, EVENT_SHOWN, {
109        relatedTarget: relatedElem
110      });
111    };
112    this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE));
113  }
114  _deactivate(element, relatedElem) {
115    if (!element) {
116      return;
117    }
118    element.classList.remove(CLASS_NAME_ACTIVE);
119    element.blur();
120    this._deactivate(SelectorEngine.getElementFromSelector(element)); // Search and deactivate the shown section too
121
122    const complete = () => {
123      if (element.getAttribute('role') !== 'tab') {
124        element.classList.remove(CLASS_NAME_SHOW);
125        return;
126      }
127      element.setAttribute('aria-selected', false);
128      element.setAttribute('tabindex', '-1');
129      this._toggleDropDown(element, false);
130      EventHandler.trigger(element, EVENT_HIDDEN, {
131        relatedTarget: relatedElem
132      });
133    };
134    this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE));
135  }
136  _keydown(event) {
137    if (![ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY, HOME_KEY, END_KEY].includes(event.key)) {
138      return;
139    }
140    event.stopPropagation(); // stopPropagation/preventDefault both added to support up/down keys without scrolling the page
141    event.preventDefault();
142    const children = this._getChildren().filter(element => !isDisabled(element));
143    let nextActiveElement;
144    if ([HOME_KEY, END_KEY].includes(event.key)) {
145      nextActiveElement = children[event.key === HOME_KEY ? 0 : children.length - 1];
146    } else {
147      const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key);
148      nextActiveElement = getNextActiveElement(children, event.target, isNext, true);
149    }
150    if (nextActiveElement) {
151      nextActiveElement.focus({
152        preventScroll: true
153      });
154      Tab.getOrCreateInstance(nextActiveElement).show();
155    }
156  }
157  _getChildren() {
158    // collection of inner elements
159    return SelectorEngine.find(SELECTOR_INNER_ELEM, this._parent);
160  }
161  _getActiveElem() {
162    return this._getChildren().find(child => this._elemIsActive(child)) || null;
163  }
164  _setInitialAttributes(parent, children) {
165    this._setAttributeIfNotExists(parent, 'role', 'tablist');
166    for (const child of children) {
167      this._setInitialAttributesOnChild(child);
168    }
169  }
170  _setInitialAttributesOnChild(child) {
171    child = this._getInnerElement(child);
172    const isActive = this._elemIsActive(child);
173    const outerElem = this._getOuterElement(child);
174    child.setAttribute('aria-selected', isActive);
175    if (outerElem !== child) {
176      this._setAttributeIfNotExists(outerElem, 'role', 'presentation');
177    }
178    if (!isActive) {
179      child.setAttribute('tabindex', '-1');
180    }
181    this._setAttributeIfNotExists(child, 'role', 'tab');
182
183    // set attributes to the related panel too
184    this._setInitialAttributesOnTargetPanel(child);
185  }
186  _setInitialAttributesOnTargetPanel(child) {
187    const target = SelectorEngine.getElementFromSelector(child);
188    if (!target) {
189      return;
190    }
191    this._setAttributeIfNotExists(target, 'role', 'tabpanel');
192    if (child.id) {
193      this._setAttributeIfNotExists(target, 'aria-labelledby', `${child.id}`);
194    }
195  }
196  _toggleDropDown(element, open) {
197    const outerElem = this._getOuterElement(element);
198    if (!outerElem.classList.contains(CLASS_DROPDOWN)) {
199      return;
200    }
201    const toggle = (selector, className) => {
202      const element = SelectorEngine.findOne(selector, outerElem);
203      if (element) {
204        element.classList.toggle(className, open);
205      }
206    };
207    toggle(SELECTOR_DROPDOWN_TOGGLE, CLASS_NAME_ACTIVE);
208    toggle(SELECTOR_DROPDOWN_MENU, CLASS_NAME_SHOW);
209    outerElem.setAttribute('aria-expanded', open);
210  }
211  _setAttributeIfNotExists(element, attribute, value) {
212    if (!element.hasAttribute(attribute)) {
213      element.setAttribute(attribute, value);
214    }
215  }
216  _elemIsActive(elem) {
217    return elem.classList.contains(CLASS_NAME_ACTIVE);
218  }
219
220  // Try to get the inner element (usually the .nav-link)
221  _getInnerElement(elem) {
222    return elem.matches(SELECTOR_INNER_ELEM) ? elem : SelectorEngine.findOne(SELECTOR_INNER_ELEM, elem);
223  }
224
225  // Try to get the outer element (usually the .nav-item)
226  _getOuterElement(elem) {
227    return elem.closest(SELECTOR_OUTER) || elem;
228  }
229
230  // Static
231  static jQueryInterface(config) {
232    return this.each(function () {
233      const data = Tab.getOrCreateInstance(this);
234      if (typeof config !== 'string') {
235        return;
236      }
237      if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
238        throw new TypeError(`No method named "${config}"`);
239      }
240      data[config]();
241    });
242  }
243}
244
245/**
246 * Data API implementation
247 */
248
249EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
250  if (['A', 'AREA'].includes(this.tagName)) {
251    event.preventDefault();
252  }
253  if (isDisabled(this)) {
254    return;
255  }
256  Tab.getOrCreateInstance(this).show();
257});
258
259/**
260 * Initialize on focus
261 */
262EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
263  for (const element of SelectorEngine.find(SELECTOR_DATA_TOGGLE_ACTIVE)) {
264    Tab.getOrCreateInstance(element);
265  }
266});
267/**
268 * jQuery
269 */
270
271defineJQueryPlugin(Tab);
272
273window.Joomla = window.Joomla || {};
274window.bootstrap = window.bootstrap || {};
275window.bootstrap.Tab = Tab;
276
277/**
278 * Initialise the Tabs interactivity
279 *
280 * @param {HTMLElement} el The element that will become a collapse
281 * @param {object} options The options for this collapse
282 */
283Joomla.initialiseTabs = (el, options) => {
284  if (!(el instanceof Element) && options.isJoomla) {
285    const tab = document.querySelector(`${el}Content`);
286    if (tab) {
287      const related = Array.from(tab.children);
288
289      // Build the navigation
290      if (related.length) {
291        related.forEach(element => {
292          if (!element.classList.contains('tab-pane')) {
293            return;
294          }
295          const isActive = element.dataset.active !== '';
296          const ul = document.querySelector(`${el}Tabs`);
297          if (ul) {
298            const link = document.createElement('a');
299            link.href = `#${element.dataset.id}`;
300            link.classList.add('nav-link');
301            if (isActive) {
302              link.classList.add('active');
303            }
304            link.dataset.bsToggle = 'tab';
305            link.setAttribute('role', 'tab');
306            link.setAttribute('aria-controls', element.dataset.id);
307            link.setAttribute('aria-selected', element.dataset.id);
308            link.innerHTML = Joomla.sanitizeHtml(element.dataset.title);
309            const li = document.createElement('li');
310            li.classList.add('nav-item');
311            li.setAttribute('role', 'presentation');
312            li.appendChild(link);
313            ul.appendChild(li);
314            new window.bootstrap.Tab(li);
315          }
316        });
317      }
318    }
319  } else {
320    document.querySelectorAll(`${el} a`).forEach(tab => new window.bootstrap.Tab(tab, options));
321  }
322};
323if (Joomla && Joomla.getOptions) {
324  // Get the elements/configurations from the PHP
325  const tabs = Joomla.getOptions('bootstrap.tabs');
326  // Initialise the elements
327  if (typeof tabs === 'object' && tabs !== null) {
328    Object.keys(tabs).map(tab => Joomla.initialiseTabs(tab, tabs[tab]));
329  }
330}
331
332export { Tab as T };

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.