PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.10
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.10
4.4.10 4.4.9.1 4.4.9 4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 All 142 releases
← All changes | assets/js/dist/admin/addons.js +345 -37 4.4.9 → 4.4.10 View file →
@@ -1573,19 +1573,19 @@
1573 1573
1574 1574 /******/ });
1575 1575 /************************************************************************/
1576 1576 /******/ // The module cache
1577 -/******/ var __webpack_module_cache__ = {};
1577 +/******/ const __webpack_module_cache__ = {};
1578 1578 /******/
1579 1579 /******/ // The require function
1580 1580 /******/ function __webpack_require__(moduleId) {
1581 1581 /******/ // Check if module is in cache
1582 -/******/ var cachedModule = __webpack_module_cache__[moduleId];
1582 +/******/ const cachedModule = __webpack_module_cache__[moduleId];
1583 1583 /******/ if (cachedModule !== undefined) {
1584 1584 /******/ return cachedModule.exports;
1585 1585 /******/ }
1586 1586 /******/ // Create a new module (and put it into the cache)
1587 -/******/ var module = __webpack_module_cache__[moduleId] = {
1587 +/******/ const module = __webpack_module_cache__[moduleId] = {
1588 1588 /******/ id: moduleId,
1589 1589 /******/ // no module.loaded needed
1590 1590 /******/ exports: {}
1591 1591 /******/ };
@@ -1592,9 +1592,9 @@
1592 1592 /******/
1593 1593 /******/ // Execute the module function
1594 1594 /******/ if (!(moduleId in __webpack_modules__)) {
1595 1595 /******/ delete __webpack_module_cache__[moduleId];
1596 -/******/ var e = new Error("Cannot find module '" + moduleId + "'");
1596 +/******/ const e = new Error("Cannot find module '" + moduleId + "'");
1597 1597 /******/ e.code = 'MODULE_NOT_FOUND';
1598 1598 /******/ throw e;
1599 1599 /******/ }
1600 1600 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
@@ -1607,9 +1607,9 @@
1607 1607 /******/ /* webpack/runtime/compat get default export */
1608 1608 /******/ (() => {
1609 1609 /******/ // getDefaultExport function for compatibility with non-harmony modules
1610 1610 /******/ __webpack_require__.n = (module) => {
1611 -/******/ var getter = module && module.__esModule ?
1611 +/******/ const getter = module && module.__esModule ?
1612 1612 /******/ () => (module['default']) :
1613 1613 /******/ () => (module);
1614 1614 /******/ __webpack_require__.d(getter, { a: getter });
1615 1615 /******/ return getter;
@@ -1617,14 +1617,29 @@
1617 1617 /******/ })();
1618 1618 /******/
1619 1619 /******/ /* webpack/runtime/define property getters */
1620 1620 /******/ (() => {
1621 -/******/ // define getter functions for harmony exports
1621 +/******/ // define getter/value functions for harmony exports
1622 1622 /******/ __webpack_require__.d = (exports, definition) => {
1623 -/******/ for(var key in definition) {
1624 -/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
1625 -/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
1623 +/******/ if(Array.isArray(definition)) {
1624 +/******/ var i = 0;
1625 +/******/ while(i < definition.length) {
1626 +/******/ var key = definition[i++];
1627 +/******/ var binding = definition[i++];
1628 +/******/ if(!__webpack_require__.o(exports, key)) {
1629 +/******/ if(binding === 0) {
1630 +/******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
1631 +/******/ } else {
1632 +/******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
1633 +/******/ }
1634 +/******/ } else if(binding === 0) { i++; }
1626 1635 /******/ }
1636 +/******/ } else {
1637 +/******/ for(var key in definition) {
1638 +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
1639 +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
1640 +/******/ }
1641 +/******/ }
1627 1642 /******/ }
1628 1643 /******/ };
1629 1644 /******/ })();
1630 1645 /******/
@@ -1629,9 +1644,9 @@
1629 1644 /******/ })();
1630 1645 /******/
1631 1646 /******/ /* webpack/runtime/hasOwnProperty shorthand */
1632 1647 /******/ (() => {
1633 -/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
1648 +/******/ __webpack_require__.o = (obj, prop) => (Object.hasOwn(obj, prop))
1634 1649 /******/ })();
1635 1650 /******/
1636 1651 /******/ /* webpack/runtime/make namespace object */
1637 1652 /******/ (() => {
@@ -1636,9 +1651,9 @@
1636 1651 /******/ /* webpack/runtime/make namespace object */
1637 1652 /******/ (() => {
1638 1653 /******/ // define __esModule on exports
1639 1654 /******/ __webpack_require__.r = (exports) => {
1640 -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
1655 +/******/ if(Symbol.toStringTag) {
1641 1656 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1642 1657 /******/ }
1643 1658 /******/ Object.defineProperty(exports, '__esModule', { value: true });
1644 1659 /******/ };
@@ -1649,9 +1664,9 @@
1649 1664 /******/ __webpack_require__.nc = undefined;
1650 1665 /******/ })();
1651 1666 /******/
1652 1667 /************************************************************************/
1653 -var __webpack_exports__ = {};
1668 +let __webpack_exports__ = {};
1654 1669 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
1655 1670 (() => {
1656 1671 "use strict";
1657 1672 /*!***************************************!*\
@@ -1681,15 +1696,23 @@
1681 1696 this.urlParams = new URLSearchParams(window.location.search);
1682 1697 }
1683 1698 static selectors = {
1684 1699 elAddonsPage: '.lp-addons-page',
1700 + elToolbar: '.lp-addons-toolbar',
1685 1701 elLPAddons: '#lp-addons',
1686 1702 elAddonItem: '.lp-addon-item',
1687 1703 elBtnAction: '.btn-addon-action',
1688 1704 elNavTab: '.nav-tab',
1689 1705 elNavTabActive: '.nav-tab.nav-tab-active',
1706 + elFilter: '.lp-addons-filter',
1707 + elFilterToggle: '.lp-addons-filter__toggle',
1708 + elFilterMenu: '.lp-addons-filter__menu',
1690 1709 elCategory: '.lp-addons-category',
1691 1710 elCategoryActive: '.lp-addons-category.active',
1711 + elSearch: '.lp-addons-search',
1712 + elSearchBtn: '.lp-addons-search__btn',
1713 + elSearchBtnClear: '.lp-addons-search__btn-clear',
1714 + elSearchClose: '.lp-addons-search__close',
1692 1715 elSearchInput: '#lp-search-addons__input',
1693 1716 elItemPurchase: '.lp-addon-item__purchase',
1694 1717 elPurchaseInstall: '.purchase-install',
1695 1718 elPurchaseCode: '.enter-purchase-code',
@@ -1701,9 +1724,40 @@
1701 1724 this.elAddonsPage = document.querySelector(AdminAddons.selectors.elAddonsPage);
1702 1725 if (!this.elAddonsPage) {
1703 1726 return;
1704 1727 }
1728 + const selectors = AdminAddons.selectors;
1729 + const urlTab = this.urlParams.get('tab');
1730 + if (urlTab) {
1731 + const elMatchingTab = this.elAddonsPage.querySelector(`${selectors.elNavTab}[data-tab="${urlTab}"]`);
1732 + if (elMatchingTab) {
1733 + this.elAddonsPage.querySelectorAll(selectors.elNavTab).forEach(elTab => {
1734 + elTab.classList.remove('nav-tab-active');
1735 + elTab.setAttribute('aria-pressed', 'false');
1736 + });
1737 + elMatchingTab.classList.add('nav-tab-active');
1738 + elMatchingTab.setAttribute('aria-pressed', 'true');
1739 + }
1740 + }
1741 + let elActiveTab = this.elAddonsPage.querySelector(selectors.elNavTabActive);
1742 + if (!elActiveTab) {
1743 + elActiveTab = this.elAddonsPage.querySelector(`${selectors.elNavTab}[data-tab="all"]`) || this.elAddonsPage.querySelector(selectors.elNavTab);
1744 + if (elActiveTab) {
1745 + elActiveTab.classList.add('nav-tab-active');
1746 + elActiveTab.setAttribute('aria-pressed', 'true');
1747 + }
1748 + }
1749 + let elActiveCategory = this.elAddonsPage.querySelector(selectors.elCategoryActive);
1750 + if (!elActiveCategory) {
1751 + elActiveCategory = this.elAddonsPage.querySelector(`${selectors.elCategory}[data-category="all"]`) || this.elAddonsPage.querySelector(selectors.elCategory);
1752 + if (elActiveCategory) {
1753 + elActiveCategory.classList.add('active');
1754 + elActiveCategory.setAttribute('aria-pressed', 'true');
1755 + }
1756 + }
1705 1757 this.filterAddons();
1758 + this.updateSearchClearBtnState();
1759 + this.updateFilterToggleState();
1706 1760 this.events();
1707 1761 });
1708 1762 }
1709 1763
@@ -1725,11 +1779,23 @@
1725 1779 selector: AdminAddons.selectors.elCategory,
1726 1780 class: this,
1727 1781 callBack: this.handleCategoryClick.name
1728 1782 }, {
1729 - selector: AdminAddons.selectors.elPurchaseCode,
1783 + selector: AdminAddons.selectors.elFilterToggle,
1730 1784 class: this,
1731 - callBack: this.handlePurchaseCodeClick.name
1785 + callBack: this.handleFilterToggleClick.name
1786 + }, {
1787 + selector: AdminAddons.selectors.elSearchBtn,
1788 + class: this,
1789 + callBack: this.handleSearchBtnClick.name
1790 + }, {
1791 + selector: AdminAddons.selectors.elSearchBtnClear,
1792 + class: this,
1793 + callBack: this.handleSearchClearClick.name
1794 + }, {
1795 + selector: AdminAddons.selectors.elSearchClose,
1796 + class: this,
1797 + callBack: this.handleSearchCloseClick.name
1732 1798 }]);
1733 1799 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__.eventHandlers('input', [{
1734 1800 selector: AdminAddons.selectors.elSearchInput,
1735 1801 class: this,
@@ -1738,8 +1804,29 @@
1738 1804 selector: AdminAddons.selectors.elPurchaseCode,
1739 1805 class: this,
1740 1806 callBack: this.handlePurchaseCodeInput.name
1741 1807 }]);
1808 + lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__.eventHandlers('keydown', [{
1809 + selector: AdminAddons.selectors.elSearchInput,
1810 + class: this,
1811 + callBack: this.handleSearchKeydown.name
1812 + }]);
1813 + document.addEventListener('click', e => {
1814 + if (!this.elAddonsPage) {
1815 + return;
1816 + }
1817 + const elToolbar = this.elAddonsPage.querySelector(AdminAddons.selectors.elToolbar);
1818 + if (elToolbar && elToolbar.classList.contains('is-filter-open')) {
1819 + if (!elToolbar.contains(e.target)) {
1820 + this.toggleFilterMenu(false);
1821 + }
1822 + }
1823 + });
1824 + document.addEventListener('keydown', e => {
1825 + if ('Escape' === e.key) {
1826 + this.toggleFilterMenu(false);
1827 + }
1828 + });
1742 1829 }
1743 1830
1744 1831 /**
1745 1832 * Get addon data embedded on the item element.
@@ -1775,10 +1862,14 @@
1775 1862 addon,
1776 1863 purchase_code: data.purchase_code || '',
1777 1864 id_url: 'addon-action'
1778 1865 };
1866 + const releaseHandling = () => {
1867 + lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpSetLoadingEl(el, 0);
1868 + };
1779 1869 window.lpAJAXG.fetchAJAX(params, {
1780 1870 success: response => {
1871 + releaseHandling();
1781 1872 const {
1782 1873 status,
1783 1874 message,
1784 1875 data: resData
@@ -1795,12 +1886,11 @@
1795 1886 }
1796 1887 }
1797 1888
1798 1889 //this.filterAddons();
1799 - lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpSetLoadingEl(el, 0);
1800 1890 },
1801 1891 error: error => {
1802 - lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpSetLoadingEl(el, 0);
1892 + releaseHandling();
1803 1893 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_0__.show(`error js: ${error}`, 'error');
1804 1894 }
1805 1895 });
1806 1896 }
@@ -1873,28 +1963,8 @@
1873 1963 });
1874 1964 }
1875 1965
1876 1966 /**
1877 - * Handle click events.
1878 - *
1879 - * @param {Object} args Click event arguments.
1880 - * @return void
1881 - */
1882 - handlePurchaseCodeClick(args) {
1883 - const {
1884 - target: el
1885 - } = args;
1886 - if (!el.value.startsWith('***')) {
1887 - return;
1888 - }
1889 - el.value = '';
1890 - const elItemPurchase = el.closest(AdminAddons.selectors.elItemPurchase);
1891 - if (elItemPurchase) {
1892 - elItemPurchase.querySelector('input[name=purchase-code]').value = '';
1893 - }
1894 - }
1895 -
1896 - /**
1897 1967 * Handle addon action button click.
1898 1968 *
1899 1969 * @param {Object} args Click event arguments.
1900 1970 * @return void
@@ -1925,24 +1995,65 @@
1925 1995 if (action === 'purchase' || action === 'update-purchase-code') {
1926 1996 const elPurchaseInstall = elItemPurchase.querySelector(selectors.elPurchaseInstall);
1927 1997 const elPurchaseCode = elPurchaseInstall.querySelector(selectors.elPurchaseCode);
1928 1998 const elPurchaseSubmit = elPurchaseInstall.querySelector('.lp-addon-purchase__submit');
1999 + const elPurchaseClear = elPurchaseInstall.querySelector('.lp-addon-purchase__clear');
2000 + const elPurchaseCancelClear = elPurchaseInstall.querySelector('.lp-addon-purchase__cancel-clear');
2001 + let hasPurchaseCode = false;
1929 2002 if (action === 'update-purchase-code') {
1930 2003 const elLicense = elAddonItem.querySelector(selectors.elLicense);
1931 2004 elPurchaseCode.value = elLicense ? elLicense.dataset.purchaseCodeMasked || '' : '';
2005 + hasPurchaseCode = '' !== elPurchaseCode.value;
1932 2006 elPurchaseSubmit.dataset.action = 'update-purchase';
1933 2007 } else {
1934 2008 elPurchaseCode.value = '';
1935 2009 elPurchaseSubmit.dataset.action = 'install';
1936 2010 }
2011 + elPurchaseCode.disabled = hasPurchaseCode;
2012 + elPurchaseSubmit.classList.toggle('lp-hidden', hasPurchaseCode);
2013 + elPurchaseClear.classList.toggle('lp-hidden', !hasPurchaseCode);
2014 + elPurchaseCancelClear.classList.add('lp-hidden');
1937 2015 elPurchaseCode.classList.remove('is-error');
1938 2016 elPurchaseCode.removeAttribute('aria-invalid');
1939 2017 elItemPurchase.querySelector('input[name=purchase-code]').value = '';
1940 2018 elPurchaseInstall.style.display = 'flex';
1941 2019 elItemPurchase.style.display = 'block';
2020 + if (!hasPurchaseCode) {
2021 + elPurchaseCode.focus();
2022 + }
2023 + lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpSetLoadingEl(el, 0);
2024 + return;
2025 + } else if (action === 'clear-license') {
2026 + const elPurchaseCode = elItemPurchase.querySelector(selectors.elPurchaseCode);
2027 + const elPurchaseSubmit = elItemPurchase.querySelector('.lp-addon-purchase__submit');
2028 + const elPurchaseClear = elItemPurchase.querySelector('.lp-addon-purchase__clear');
2029 + const elPurchaseCancelClear = elItemPurchase.querySelector('.lp-addon-purchase__cancel-clear');
2030 + elPurchaseCode.value = '';
2031 + elPurchaseCode.disabled = false;
2032 + elPurchaseCode.classList.remove('is-error');
2033 + elPurchaseCode.removeAttribute('aria-invalid');
2034 + elItemPurchase.querySelector('input[name=purchase-code]').value = '';
2035 + elPurchaseSubmit.classList.remove('lp-hidden');
2036 + elPurchaseClear.classList.add('lp-hidden');
2037 + elPurchaseCancelClear.classList.remove('lp-hidden');
1942 2038 elPurchaseCode.focus();
1943 2039 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpSetLoadingEl(el, 0);
1944 2040 return;
2041 + } else if (action === 'cancel-clear-license') {
2042 + const elLicense = elAddonItem.querySelector(selectors.elLicense);
2043 + const elPurchaseCode = elItemPurchase.querySelector(selectors.elPurchaseCode);
2044 + const elPurchaseSubmit = elItemPurchase.querySelector('.lp-addon-purchase__submit');
2045 + const elPurchaseClear = elItemPurchase.querySelector('.lp-addon-purchase__clear');
2046 + elPurchaseCode.value = elLicense ? elLicense.dataset.purchaseCodeMasked || '' : '';
2047 + elPurchaseCode.disabled = true;
2048 + elPurchaseCode.classList.remove('is-error');
2049 + elPurchaseCode.removeAttribute('aria-invalid');
2050 + elItemPurchase.querySelector('input[name=purchase-code]').value = '';
2051 + elPurchaseSubmit.classList.add('lp-hidden');
2052 + elPurchaseClear.classList.remove('lp-hidden');
2053 + el.classList.add('lp-hidden');
2054 + lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpSetLoadingEl(el, 0);
2055 + return;
1945 2056 } else if (action === 'cancel') {
1946 2057 elItemPurchase.style.display = 'none';
1947 2058 elItemPurchase.querySelector(selectors.elPurchaseInstall).style.display = 'none';
1948 2059 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpSetLoadingEl(el, 0);
@@ -1982,11 +2093,28 @@
1982 2093 elTab.setAttribute('aria-pressed', 'false');
1983 2094 });
1984 2095 el.classList.add('nav-tab-active');
1985 2096 el.setAttribute('aria-pressed', 'true');
2097 + if (el.scrollIntoView) {
2098 + el.scrollIntoView({
2099 + inline: 'center',
2100 + block: 'nearest',
2101 + behavior: 'smooth'
2102 + });
2103 + }
1986 2104 const tabName = el.dataset.tab;
1987 2105 const elSearch = this.elAddonsPage.querySelector(selectors.elSearchInput);
1988 - elSearch.value = '';
2106 + if (elSearch) {
2107 + elSearch.value = '';
2108 + }
2109 + const elSearchContainer = this.elAddonsPage.querySelector(selectors.elSearch);
2110 + if (elSearchContainer) {
2111 + elSearchContainer.classList.remove('is-open');
2112 + const btn = elSearchContainer.querySelector(selectors.elSearchBtn);
2113 + if (btn) {
2114 + btn.setAttribute('aria-expanded', 'false');
2115 + }
2116 + }
1989 2117 this.elAddonsPage.querySelectorAll(selectors.elCategory).forEach(elCategory => {
1990 2118 const isActive = 'all' === elCategory.dataset.category;
1991 2119 elCategory.classList.toggle('active', isActive);
1992 2120 elCategory.setAttribute('aria-pressed', isActive ? 'true' : 'false');
@@ -1992,12 +2120,73 @@
1992 2120 elCategory.setAttribute('aria-pressed', isActive ? 'true' : 'false');
1993 2121 });
1994 2122 this.urlParams.set('tab', tabName);
1995 2123 window.history.pushState({}, '', `${window.location.pathname}?${this.urlParams.toString()}`);
2124 + this.updateFilterToggleState();
1996 2125 this.filterAddons();
1997 2126 }
1998 2127
1999 2128 /**
2129 + * Handle filter toggle button click.
2130 + *
2131 + * @param {Object} args Click event arguments.
2132 + * @return void
2133 + */
2134 + handleFilterToggleClick(args) {
2135 + const {
2136 + e
2137 + } = args;
2138 + e.preventDefault();
2139 + e.stopPropagation();
2140 + this.toggleFilterMenu();
2141 + }
2142 +
2143 + /**
2144 + * Toggle or set filter menu dropdown open state.
2145 + *
2146 + * @param {boolean|undefined} open Optional boolean to force state.
2147 + * @return void
2148 + */
2149 + toggleFilterMenu(open) {
2150 + const selectors = AdminAddons.selectors;
2151 + const elToolbar = this.elAddonsPage.querySelector(selectors.elToolbar);
2152 + const elFilter = this.elAddonsPage.querySelector(selectors.elFilter);
2153 + if (!elToolbar && !elFilter) {
2154 + return;
2155 + }
2156 + const toggleBtn = this.elAddonsPage.querySelector(selectors.elFilterToggle);
2157 + const shouldOpen = undefined !== open ? open : elToolbar ? !elToolbar.classList.contains('is-filter-open') : !elFilter.classList.contains('is-open');
2158 + if (elToolbar) {
2159 + elToolbar.classList.toggle('is-filter-open', shouldOpen);
2160 + }
2161 + if (elFilter) {
2162 + elFilter.classList.toggle('is-open', shouldOpen);
2163 + }
2164 + if (toggleBtn) {
2165 + toggleBtn.setAttribute('aria-expanded', shouldOpen ? 'true' : 'false');
2166 + }
2167 + }
2168 +
2169 + /**
2170 + * Update filter toggle button has-filter state.
2171 + *
2172 + * @return void
2173 + */
2174 + updateFilterToggleState() {
2175 + const selectors = AdminAddons.selectors;
2176 + const toggleBtn = this.elAddonsPage.querySelector(selectors.elFilterToggle);
2177 + if (!toggleBtn) {
2178 + return;
2179 + }
2180 + const elActiveTab = this.elAddonsPage.querySelector(selectors.elNavTabActive);
2181 + const elActiveCategory = this.elAddonsPage.querySelector(selectors.elCategoryActive);
2182 + const tabName = elActiveTab ? elActiveTab.dataset.tab : 'all';
2183 + const category = elActiveCategory ? elActiveCategory.dataset.category : 'all';
2184 + const hasFilter = 'all' !== tabName || 'all' !== category;
2185 + toggleBtn.classList.toggle('has-filter', hasFilter);
2186 + }
2187 +
2188 + /**
2000 2189 * Handle category click.
2001 2190 *
2002 2191 * @param {Object} args Click event arguments.
2003 2192 * @return void
@@ -2013,8 +2202,9 @@
2013 2202 const isActive = item === elCategory;
2014 2203 item.classList.toggle('active', isActive);
2015 2204 item.setAttribute('aria-pressed', isActive ? 'true' : 'false');
2016 2205 });
2206 + this.updateFilterToggleState();
2017 2207 this.filterAddons();
2018 2208 }
2019 2209
2020 2210 /**
@@ -2022,9 +2212,127 @@
2022 2212 *
2023 2213 * @return void
2024 2214 */
2025 2215 handleSearchInput() {
2216 + this.updateSearchClearBtnState();
2026 2217 this.filterAddons();
2218 + }
2219 +
2220 + /**
2221 + * Handle search button click to open search overlay.
2222 + *
2223 + * @param {Object} args Click event arguments.
2224 + * @return void
2225 + */
2226 + handleSearchBtnClick(args) {
2227 + const {
2228 + e
2229 + } = args;
2230 + e.preventDefault();
2231 + this.toggleFilterMenu(false);
2232 + const selectors = AdminAddons.selectors;
2233 + const elSearch = this.elAddonsPage.querySelector(selectors.elSearch);
2234 + const elSearchInput = this.elAddonsPage.querySelector(selectors.elSearchInput);
2235 + if (elSearch) {
2236 + elSearch.classList.add('is-open');
2237 + const btn = elSearch.querySelector(selectors.elSearchBtn);
2238 + if (btn) {
2239 + btn.setAttribute('aria-expanded', 'true');
2240 + }
2241 + }
2242 + if (elSearchInput) {
2243 + this.updateSearchClearBtnState();
2244 + elSearchInput.focus();
2245 + }
2246 + }
2247 +
2248 + /**
2249 + * Handle search clear button click.
2250 + *
2251 + * @param {Object} args Click event arguments.
2252 + * @return void
2253 + */
2254 + handleSearchClearClick(args) {
2255 + const {
2256 + e
2257 + } = args;
2258 + e.preventDefault();
2259 + const selectors = AdminAddons.selectors;
2260 + const elSearchInput = this.elAddonsPage.querySelector(selectors.elSearchInput);
2261 + if (elSearchInput) {
2262 + elSearchInput.value = '';
2263 + this.updateSearchClearBtnState();
2264 + this.filterAddons();
2265 + elSearchInput.focus();
2266 + }
2267 + }
2268 +
2269 + /**
2270 + * Update disabled state of clear search button.
2271 + *
2272 + * @return void
2273 + */
2274 + updateSearchClearBtnState() {
2275 + const selectors = AdminAddons.selectors;
2276 + const elSearchInput = this.elAddonsPage.querySelector(selectors.elSearchInput);
2277 + const elClearBtn = this.elAddonsPage.querySelector(selectors.elSearchBtnClear);
2278 + if (elClearBtn && elSearchInput) {
2279 + elClearBtn.disabled = !elSearchInput.value.trim();
2280 + }
2281 + }
2282 +
2283 + /**
2284 + * Handle search close button click.
2285 + *
2286 + * @param {Object} args Click event arguments.
2287 + * @return void
2288 + */
2289 + handleSearchCloseClick(args) {
2290 + const {
2291 + e
2292 + } = args;
2293 + e.preventDefault();
2294 + this.closeSearch();
2295 + }
2296 +
2297 + /**
2298 + * Handle search input keydown.
2299 + *
2300 + * @param {Object} args Keydown event arguments.
2301 + * @return void
2302 + */
2303 + handleSearchKeydown(args) {
2304 + const {
2305 + e
2306 + } = args;
2307 + if ('Escape' === e.key) {
2308 + e.preventDefault();
2309 + this.closeSearch();
2310 + }
2311 + }
2312 +
2313 + /**
2314 + * Close search overlay and reset query if needed.
2315 + *
2316 + * @return void
2317 + */
2318 + closeSearch() {
2319 + const selectors = AdminAddons.selectors;
2320 + const elSearch = this.elAddonsPage.querySelector(selectors.elSearch);
2321 + const elSearchInput = this.elAddonsPage.querySelector(selectors.elSearchInput);
2322 + if (elSearch) {
2323 + elSearch.classList.remove('is-open');
2324 + const btn = elSearch.querySelector(selectors.elSearchBtn);
2325 + if (btn) {
2326 + btn.setAttribute('aria-expanded', 'false');
2327 + btn.focus();
2328 + }
2329 + }
2330 + if (elSearchInput && elSearchInput.value) {
2331 + elSearchInput.value = '';
2332 + this.filterAddons();
2333 + }
2334 + this.updateSearchClearBtnState();
2027 2335 }
2028 2336
2029 2337 /**
2030 2338 * Handle purchase code input.