478 lines
No EOL
18 KiB
JavaScript
478 lines
No EOL
18 KiB
JavaScript
/*! elementor - v3.26.0 - 22-12-2024 */
|
|
"use strict";
|
|
(self["webpackChunkelementor"] = self["webpackChunkelementor"] || []).push([["nested-accordion"],{
|
|
|
|
/***/ "../assets/dev/js/frontend/handlers/accessibility/nested-title-keyboard-handler.js":
|
|
/*!*****************************************************************************************!*\
|
|
!*** ../assets/dev/js/frontend/handlers/accessibility/nested-title-keyboard-handler.js ***!
|
|
\*****************************************************************************************/
|
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
|
|
|
|
|
|
var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js");
|
|
Object.defineProperty(exports, "__esModule", ({
|
|
value: true
|
|
}));
|
|
exports["default"] = void 0;
|
|
__webpack_require__(/*! core-js/modules/es.array.includes.js */ "../node_modules/core-js/modules/es.array.includes.js");
|
|
var _base = _interopRequireDefault(__webpack_require__(/*! ../base */ "../assets/dev/js/frontend/handlers/base.js"));
|
|
class NestedTitleKeyboardHandler extends _base.default {
|
|
__construct(settings) {
|
|
super.__construct(settings);
|
|
this.directionNext = 'next';
|
|
this.directionPrevious = 'previous';
|
|
this.focusableElementSelector = 'audio, button, canvas, details, iframe, input, select, summary, textarea, video, [accesskey], [contenteditable], [href], [tabindex]:not([tabindex="-1"])';
|
|
}
|
|
getWidgetNumber() {
|
|
return this.$element.find('> .elementor-widget-container > .e-n-tabs, > .e-n-tabs').attr('data-widget-number');
|
|
}
|
|
getDefaultSettings() {
|
|
return {
|
|
selectors: {
|
|
itemTitle: `[id*="e-n-tab-title-${this.getWidgetNumber()}"]`,
|
|
itemContainer: `[id*="e-n-tab-content-${this.getWidgetNumber()}"]`
|
|
},
|
|
ariaAttributes: {
|
|
titleStateAttribute: 'aria-selected',
|
|
activeTitleSelector: '[aria-selected="true"]'
|
|
},
|
|
datasets: {
|
|
titleIndex: 'data-tab-index'
|
|
},
|
|
keyDirection: {
|
|
ArrowLeft: elementorFrontendConfig.is_rtl ? this.directionNext : this.directionPrevious,
|
|
ArrowUp: this.directionPrevious,
|
|
ArrowRight: elementorFrontendConfig.is_rtl ? this.directionPrevious : this.directionNext,
|
|
ArrowDown: this.directionNext
|
|
}
|
|
};
|
|
}
|
|
getDefaultElements() {
|
|
const selectors = this.getSettings('selectors');
|
|
return {
|
|
$itemTitles: this.findElement(selectors.itemTitle),
|
|
$itemContainers: this.findElement(selectors.itemContainer),
|
|
$focusableContainerElements: this.getFocusableElements(this.findElement(selectors.itemContainer))
|
|
};
|
|
}
|
|
getFocusableElements($elements) {
|
|
return $elements.find(this.focusableElementSelector).not('[disabled], [inert]');
|
|
}
|
|
getKeyDirectionValue(event) {
|
|
const direction = this.getSettings('keyDirection')[event.key];
|
|
return this.directionNext === direction ? 1 : -1;
|
|
}
|
|
|
|
/**
|
|
* @param {HTMLElement} itemTitleElement
|
|
*
|
|
* @return {string}
|
|
*/
|
|
getTitleIndex(itemTitleElement) {
|
|
const {
|
|
titleIndex: indexAttribute
|
|
} = this.getSettings('datasets');
|
|
return itemTitleElement.getAttribute(indexAttribute);
|
|
}
|
|
|
|
/**
|
|
* @param {string|number} titleIndex
|
|
*
|
|
* @return {string}
|
|
*/
|
|
getTitleFilterSelector(titleIndex) {
|
|
const {
|
|
titleIndex: indexAttribute
|
|
} = this.getSettings('datasets');
|
|
return `[${indexAttribute}="${titleIndex}"]`;
|
|
}
|
|
getActiveTitleElement() {
|
|
const activeTitleFilter = this.getSettings('ariaAttributes').activeTitleSelector;
|
|
return this.elements.$itemTitles.filter(activeTitleFilter);
|
|
}
|
|
onInit() {
|
|
super.onInit(...arguments);
|
|
}
|
|
bindEvents() {
|
|
this.elements.$itemTitles.on(this.getTitleEvents());
|
|
this.elements.$focusableContainerElements.on(this.getContentElementEvents());
|
|
}
|
|
unbindEvents() {
|
|
this.elements.$itemTitles.off(this.getTitleEvents());
|
|
this.elements.$focusableContainerElements.children().off(this.getContentElementEvents());
|
|
}
|
|
getTitleEvents() {
|
|
return {
|
|
keydown: this.handleTitleKeyboardNavigation.bind(this)
|
|
};
|
|
}
|
|
getContentElementEvents() {
|
|
return {
|
|
keydown: this.handleContentElementKeyboardNavigation.bind(this)
|
|
};
|
|
}
|
|
isDirectionKey(event) {
|
|
const directionKeys = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End'];
|
|
return directionKeys.includes(event.key);
|
|
}
|
|
isActivationKey(event) {
|
|
const activationKeys = ['Enter', ' '];
|
|
return activationKeys.includes(event.key);
|
|
}
|
|
handleTitleKeyboardNavigation(event) {
|
|
if (this.isDirectionKey(event)) {
|
|
event.preventDefault();
|
|
const currentTitleIndex = parseInt(this.getTitleIndex(event.currentTarget)) || 1,
|
|
numberOfTitles = this.elements.$itemTitles.length,
|
|
titleIndexUpdated = this.getTitleIndexFocusUpdated(event, currentTitleIndex, numberOfTitles);
|
|
this.changeTitleFocus(titleIndexUpdated);
|
|
event.stopPropagation();
|
|
} else if (this.isActivationKey(event)) {
|
|
event.preventDefault();
|
|
if (this.handeTitleLinkEnterOrSpaceEvent(event)) {
|
|
return;
|
|
}
|
|
const titleIndex = this.getTitleIndex(event.currentTarget);
|
|
elementorFrontend.elements.$window.trigger('elementor/nested-elements/activate-by-keyboard', {
|
|
widgetId: this.getID(),
|
|
titleIndex
|
|
});
|
|
} else if ('Escape' === event.key) {
|
|
this.handleTitleEscapeKeyEvents(event);
|
|
}
|
|
}
|
|
handeTitleLinkEnterOrSpaceEvent(event) {
|
|
const isLinkElement = 'a' === event?.currentTarget?.tagName?.toLowerCase();
|
|
if (!elementorFrontend.isEditMode() && isLinkElement) {
|
|
event?.currentTarget?.click();
|
|
event.stopPropagation();
|
|
}
|
|
return isLinkElement;
|
|
}
|
|
getTitleIndexFocusUpdated(event, currentTitleIndex, numberOfTitles) {
|
|
let titleIndexUpdated = 0;
|
|
switch (event.key) {
|
|
case 'Home':
|
|
titleIndexUpdated = 1;
|
|
break;
|
|
case 'End':
|
|
titleIndexUpdated = numberOfTitles;
|
|
break;
|
|
default:
|
|
const directionValue = this.getKeyDirectionValue(event),
|
|
isEndReached = numberOfTitles < currentTitleIndex + directionValue,
|
|
isStartReached = 0 === currentTitleIndex + directionValue;
|
|
if (isEndReached) {
|
|
titleIndexUpdated = 1;
|
|
} else if (isStartReached) {
|
|
titleIndexUpdated = numberOfTitles;
|
|
} else {
|
|
titleIndexUpdated = currentTitleIndex + directionValue;
|
|
}
|
|
}
|
|
return titleIndexUpdated;
|
|
}
|
|
changeTitleFocus(titleIndexUpdated) {
|
|
const $newTitle = this.elements.$itemTitles.filter(this.getTitleFilterSelector(titleIndexUpdated));
|
|
this.setTitleTabindex(titleIndexUpdated);
|
|
$newTitle.trigger('focus');
|
|
}
|
|
setTitleTabindex(titleIndex) {
|
|
this.elements.$itemTitles.attr('tabindex', '-1');
|
|
const $newTitle = this.elements.$itemTitles.filter(this.getTitleFilterSelector(titleIndex));
|
|
$newTitle.attr('tabindex', '0');
|
|
}
|
|
handleTitleEscapeKeyEvents() {}
|
|
handleContentElementKeyboardNavigation(event) {
|
|
if ('Tab' === event.key && !event.shiftKey) {
|
|
this.handleContentElementTabEvents(event);
|
|
} else if ('Escape' === event.key) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
this.handleContentElementEscapeEvents(event);
|
|
}
|
|
}
|
|
handleContentElementEscapeEvents() {
|
|
this.getActiveTitleElement().trigger('focus');
|
|
}
|
|
handleContentElementTabEvents() {}
|
|
}
|
|
exports["default"] = NestedTitleKeyboardHandler;
|
|
|
|
/***/ }),
|
|
|
|
/***/ "../modules/nested-accordion/assets/js/frontend/handlers/nested-accordion-title-keyboard-handler.js":
|
|
/*!**********************************************************************************************************!*\
|
|
!*** ../modules/nested-accordion/assets/js/frontend/handlers/nested-accordion-title-keyboard-handler.js ***!
|
|
\**********************************************************************************************************/
|
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
|
|
|
|
|
|
var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js");
|
|
Object.defineProperty(exports, "__esModule", ({
|
|
value: true
|
|
}));
|
|
exports["default"] = void 0;
|
|
var _nestedTitleKeyboardHandler = _interopRequireDefault(__webpack_require__(/*! elementor-frontend/handlers/accessibility/nested-title-keyboard-handler */ "../assets/dev/js/frontend/handlers/accessibility/nested-title-keyboard-handler.js"));
|
|
class NestedAccordionTitleKeyboardHandler extends _nestedTitleKeyboardHandler.default {
|
|
__construct() {
|
|
super.__construct(...arguments);
|
|
const config = arguments.length <= 0 ? undefined : arguments[0];
|
|
this.toggleTitle = config.toggleTitle;
|
|
}
|
|
getDefaultSettings() {
|
|
const parentSettings = super.getDefaultSettings();
|
|
return {
|
|
...parentSettings,
|
|
selectors: {
|
|
itemTitle: '.e-n-accordion-item-title',
|
|
itemContainer: '.e-n-accordion-item > .e-con'
|
|
},
|
|
ariaAttributes: {
|
|
titleStateAttribute: 'aria-expanded',
|
|
activeTitleSelector: '[aria-expanded="true"]'
|
|
},
|
|
datasets: {
|
|
titleIndex: 'data-accordion-index'
|
|
}
|
|
};
|
|
}
|
|
handeTitleLinkEnterOrSpaceEvent(event) {
|
|
this.toggleTitle(event);
|
|
}
|
|
handleContentElementEscapeEvents(event) {
|
|
this.getActiveTitleElement().trigger('focus');
|
|
this.toggleTitle(event);
|
|
}
|
|
handleTitleEscapeKeyEvents(event) {
|
|
const detailsNode = event?.currentTarget?.parentElement,
|
|
isOpen = detailsNode?.open;
|
|
if (isOpen) {
|
|
this.toggleTitle(event);
|
|
}
|
|
}
|
|
}
|
|
exports["default"] = NestedAccordionTitleKeyboardHandler;
|
|
|
|
/***/ }),
|
|
|
|
/***/ "../modules/nested-accordion/assets/js/frontend/handlers/nested-accordion.js":
|
|
/*!***********************************************************************************!*\
|
|
!*** ../modules/nested-accordion/assets/js/frontend/handlers/nested-accordion.js ***!
|
|
\***********************************************************************************/
|
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
|
|
|
|
|
|
var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js");
|
|
Object.defineProperty(exports, "__esModule", ({
|
|
value: true
|
|
}));
|
|
exports["default"] = void 0;
|
|
var _base = _interopRequireDefault(__webpack_require__(/*! elementor-frontend/handlers/base */ "../assets/dev/js/frontend/handlers/base.js"));
|
|
var _nestedAccordionTitleKeyboardHandler = _interopRequireDefault(__webpack_require__(/*! ./nested-accordion-title-keyboard-handler */ "../modules/nested-accordion/assets/js/frontend/handlers/nested-accordion-title-keyboard-handler.js"));
|
|
class NestedAccordion extends _base.default {
|
|
constructor() {
|
|
super(...arguments);
|
|
this.animations = new Map();
|
|
}
|
|
getDefaultSettings() {
|
|
return {
|
|
selectors: {
|
|
accordion: '.e-n-accordion',
|
|
accordionContentContainers: '.e-n-accordion > .e-con',
|
|
accordionItems: '.e-n-accordion-item',
|
|
accordionItemTitles: '.e-n-accordion-item-title',
|
|
accordionItemTitlesText: '.e-n-accordion-item-title-text',
|
|
accordionContent: '.e-n-accordion-item > .e-con',
|
|
directAccordionItems: ':scope > .e-n-accordion-item',
|
|
directAccordionItemTitles: ':scope > .e-n-accordion-item > .e-n-accordion-item-title'
|
|
},
|
|
default_state: 'expanded',
|
|
attributes: {
|
|
index: 'data-accordion-index',
|
|
ariaLabelledBy: 'aria-labelledby'
|
|
}
|
|
};
|
|
}
|
|
getDefaultElements() {
|
|
const selectors = this.getSettings('selectors');
|
|
return {
|
|
$accordion: this.findElement(selectors.accordion),
|
|
$contentContainers: this.findElement(selectors.accordionContentContainers),
|
|
$accordionItems: this.findElement(selectors.accordionItems),
|
|
$accordionTitles: this.findElement(selectors.accordionItemTitles),
|
|
$accordionContent: this.findElement(selectors.accordionContent)
|
|
};
|
|
}
|
|
onInit() {
|
|
super.onInit(...arguments);
|
|
if (elementorFrontend.isEditMode() && !elementorCommon.config.experimentalFeatures.e_nested_atomic_repeaters) {
|
|
this.interlaceContainers();
|
|
}
|
|
this.injectKeyboardHandler();
|
|
}
|
|
injectKeyboardHandler() {
|
|
if ('nested-accordion.default' === this.getSettings('elementName')) {
|
|
new _nestedAccordionTitleKeyboardHandler.default({
|
|
$element: this.$element,
|
|
toggleTitle: this.clickListener.bind(this)
|
|
});
|
|
}
|
|
}
|
|
interlaceContainers() {
|
|
const {
|
|
$contentContainers,
|
|
$accordionItems
|
|
} = this.getDefaultElements();
|
|
$contentContainers.each((index, element) => {
|
|
$accordionItems[index].appendChild(element);
|
|
});
|
|
}
|
|
linkContainer(event) {
|
|
const {
|
|
container,
|
|
index,
|
|
targetContainer,
|
|
action: {
|
|
type
|
|
}
|
|
} = event.detail,
|
|
view = container.view.$el,
|
|
id = container.model.get('id'),
|
|
currentId = this.$element.data('id');
|
|
if (id === currentId) {
|
|
const {
|
|
$accordionItems
|
|
} = this.getDefaultElements();
|
|
let accordionItem, contentContainer;
|
|
switch (type) {
|
|
case 'move':
|
|
[accordionItem, contentContainer] = this.move(view, index, targetContainer, $accordionItems);
|
|
break;
|
|
case 'duplicate':
|
|
[accordionItem, contentContainer] = this.duplicate(view, index, targetContainer, $accordionItems);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (undefined !== accordionItem) {
|
|
accordionItem.appendChild(contentContainer);
|
|
}
|
|
this.updateIndexValues();
|
|
this.updateListeners(view);
|
|
elementor.$preview[0].contentWindow.dispatchEvent(new CustomEvent('elementor/elements/link-data-bindings'));
|
|
}
|
|
}
|
|
move(view, index, targetContainer, accordionItems) {
|
|
return [accordionItems[index], targetContainer.view.$el[0]];
|
|
}
|
|
duplicate(view, index, targetContainer, accordionItems) {
|
|
return [accordionItems[index + 1], targetContainer.view.$el[0]];
|
|
}
|
|
updateIndexValues() {
|
|
const {
|
|
$accordionContent,
|
|
$accordionItems
|
|
} = this.getDefaultElements(),
|
|
settings = this.getSettings(),
|
|
itemIdBase = $accordionItems[0].getAttribute('id').slice(0, -1);
|
|
$accordionItems.each((index, element) => {
|
|
element.setAttribute('id', `${itemIdBase}${index}`);
|
|
element.querySelector(settings.selectors.accordionItemTitles).setAttribute(settings.attributes.index, index + 1);
|
|
element.querySelector(settings.selectors.accordionItemTitles).setAttribute('aria-controls', `${itemIdBase}${index}`);
|
|
element.querySelector(settings.selectors.accordionItemTitlesText).setAttribute('data-binding-index', index + 1);
|
|
$accordionContent[index].setAttribute(settings.attributes.ariaLabelledBy, `${itemIdBase}${index}`);
|
|
});
|
|
}
|
|
updateListeners(view) {
|
|
this.elements.$accordionTitles = view.find(this.getSettings('selectors.accordionItemTitles'));
|
|
this.elements.$accordionItems = view.find(this.getSettings('selectors.accordionItems'));
|
|
this.elements.$accordionTitles.on('click', this.clickListener.bind(this));
|
|
}
|
|
bindEvents() {
|
|
this.elements.$accordionTitles.on('click', this.clickListener.bind(this));
|
|
elementorFrontend.elements.$window.on('elementor/nested-container/atomic-repeater', this.linkContainer.bind(this));
|
|
}
|
|
unbindEvents() {
|
|
this.elements.$accordionTitles.off();
|
|
}
|
|
clickListener(event) {
|
|
event.preventDefault();
|
|
this.elements = this.getDefaultElements();
|
|
const settings = this.getSettings(),
|
|
accordionItem = event?.currentTarget?.closest(settings.selectors.accordionItems),
|
|
accordion = event?.currentTarget?.closest(settings.selectors.accordion),
|
|
itemSummary = accordionItem.querySelector(settings.selectors.accordionItemTitles),
|
|
accordionContent = accordionItem.querySelector(settings.selectors.accordionContent),
|
|
{
|
|
max_items_expended: maxItemsExpended
|
|
} = this.getElementSettings(),
|
|
directAccordionItems = accordion.querySelectorAll(settings.selectors.directAccordionItems),
|
|
directAccordionItemTitles = accordion.querySelectorAll(settings.selectors.directAccordionItemTitles);
|
|
if ('one' === maxItemsExpended) {
|
|
this.closeAllItems(directAccordionItems, directAccordionItemTitles);
|
|
}
|
|
if (!accordionItem.open) {
|
|
this.prepareOpenAnimation(accordionItem, itemSummary, accordionContent);
|
|
} else {
|
|
this.closeAccordionItem(accordionItem, itemSummary);
|
|
}
|
|
}
|
|
animateItem(accordionItem, startHeight, endHeight, isOpen) {
|
|
accordionItem.style.overflow = 'hidden';
|
|
let animation = this.animations.get(accordionItem);
|
|
if (animation) {
|
|
animation.cancel();
|
|
}
|
|
animation = accordionItem.animate({
|
|
height: [startHeight, endHeight]
|
|
}, {
|
|
duration: this.getAnimationDuration()
|
|
});
|
|
animation.onfinish = () => this.onAnimationFinish(accordionItem, isOpen);
|
|
this.animations.set(accordionItem, animation);
|
|
accordionItem.querySelector('summary')?.setAttribute('aria-expanded', isOpen);
|
|
}
|
|
closeAccordionItem(accordionItem, accordionItemTitle) {
|
|
const startHeight = `${accordionItem.offsetHeight}px`,
|
|
endHeight = `${accordionItemTitle.offsetHeight}px`;
|
|
this.animateItem(accordionItem, startHeight, endHeight, false);
|
|
}
|
|
prepareOpenAnimation(accordionItem, accordionItemTitle, accordionItemContent) {
|
|
accordionItem.style.overflow = 'hidden';
|
|
accordionItem.style.height = `${accordionItem.offsetHeight}px`;
|
|
accordionItem.open = true;
|
|
window.requestAnimationFrame(() => this.openAccordionItem(accordionItem, accordionItemTitle, accordionItemContent));
|
|
}
|
|
openAccordionItem(accordionItem, accordionItemTitle, accordionItemContent) {
|
|
const startHeight = `${accordionItem.offsetHeight}px`,
|
|
endHeight = `${accordionItemTitle.offsetHeight + accordionItemContent.offsetHeight}px`;
|
|
this.animateItem(accordionItem, startHeight, endHeight, true);
|
|
}
|
|
onAnimationFinish(accordionItem, isOpen) {
|
|
accordionItem.open = isOpen;
|
|
this.animations.set(accordionItem, null);
|
|
accordionItem.style.height = accordionItem.style.overflow = '';
|
|
}
|
|
closeAllItems(items, titles) {
|
|
titles.forEach((title, index) => {
|
|
this.closeAccordionItem(items[index], title);
|
|
});
|
|
}
|
|
getAnimationDuration() {
|
|
const {
|
|
size,
|
|
unit
|
|
} = this.getElementSettings('n_accordion_animation_duration');
|
|
return size * ('ms' === unit ? 1 : 1000);
|
|
}
|
|
}
|
|
exports["default"] = NestedAccordion;
|
|
|
|
/***/ })
|
|
|
|
}]);
|
|
//# sourceMappingURL=nested-accordion.b15477b3c5d0de743d83.bundle.js.map
|