PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.9
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.9
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 4.1.7.3.1 4.1.7.3.2 All 140 releases
← All changes | assets/dist/js/admin/edit-course.js +286 -144 4.3.9.1 → 4.4.9 View file →
@@ -14,13 +14,13 @@
14 14 /* harmony export */ });
15 15 /* harmony import */ var _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./edit-curriculum/edit-section.js */ "./assets/src/js/admin/edit-course/edit-curriculum/edit-section.js");
16 16 /* harmony import */ var _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./edit-curriculum/edit-section-item.js */ "./assets/src/js/admin/edit-course/edit-curriculum/edit-section-item.js");
17 17 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
18 -/**
19 - * Edit Curriculum JS handler.
20 - *
21 - * @since 4.2.8.6
22 - * @version 1.0.2
18 +/**
19 + * Edit Curriculum JS handler.
20 + *
21 + * @since 4.2.8.6
22 + * @version 1.0.2
23 23 */
24 24
25 25
26 26
@@ -67,10 +67,10 @@
67 67 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_2__);
68 68 /* harmony import */ var _edit_section_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./edit-section.js */ "./assets/src/js/admin/edit-course/edit-curriculum/edit-section.js");
69 69 /* harmony import */ var _edit_section_item_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./edit-section-item.js */ "./assets/src/js/admin/edit-course/edit-curriculum/edit-section-item.js");
70 70 /* harmony import */ var lpAssetsJsPath_admin_edit_course_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! lpAssetsJsPath/admin/edit-course/edit-curriculum.js */ "./assets/src/js/admin/edit-course/edit-curriculum.js");
71 -/**
72 - * Generate data with OpenAI
71 +/**
72 + * Generate data with OpenAI
73 73 */
74 74
75 75
76 76
@@ -189,11 +189,11 @@
189 189 });
190 190 }
191 191 }
192 192
193 - /**
194 - * Update section description after create new section
195 - * @param args
193 + /**
194 + * Update section description after create new section
195 + * @param args
196 196 */
197 197 updateSectionDescription(args) {
198 198 const {
199 199 sectionData,
@@ -318,13 +318,13 @@
318 318 /* harmony import */ var lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify.js */ "./assets/src/js/lpToastify.js");
319 319 /* harmony import */ var _edit_curriculum_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../edit-curriculum.js */ "./assets/src/js/admin/edit-course/edit-curriculum.js");
320 320 /* harmony import */ var _edit_section_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./edit-section.js */ "./assets/src/js/admin/edit-course/edit-curriculum/edit-section.js");
321 321 /* harmony import */ var lpAssetsJsPath_lpPopupSelectItemToAdd_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! lpAssetsJsPath/lpPopupSelectItemToAdd.js */ "./assets/src/js/lpPopupSelectItemToAdd.js");
322 -/**
323 - * Edit Section item Script on Curriculum
324 - *
325 - * @version 1.0.3
326 - * @since 4.2.8.6
322 +/**
323 + * Edit Section item Script on Curriculum
324 + *
325 + * @version 1.0.3
326 + * @since 4.2.8.6
327 327 */
328 328
329 329
330 330
@@ -1050,15 +1050,15 @@
1050 1050 elSectionItemsCount.dataset.count = itemsCount;
1051 1051 elSectionItemsCount.querySelector('.count').textContent = itemsCount;
1052 1052 }
1053 1053
1054 - /**
1055 - * Add popup attributes to item element for Course Builder context.
1056 - * Only applies when in Course Builder (not admin edit course page).
1057 - *
1058 - * @param {HTMLElement} elItem - The item element
1059 - * @param {number} itemId - The item ID
1060 - * @param {string} itemType - The item type (lp_lesson, lp_quiz, lp_assignment)
1054 + /**
1055 + * Add popup attributes to item element for Course Builder context.
1056 + * Only applies when in Course Builder (not admin edit course page).
1057 + *
1058 + * @param {HTMLElement} elItem - The item element
1059 + * @param {number} itemId - The item ID
1060 + * @param {string} itemType - The item type (lp_lesson, lp_quiz, lp_assignment)
1061 1061 */
1062 1062 addPopupAttributesToItem(elItem, itemId, itemType) {
1063 1063 // Check if we're in Course Builder context
1064 1064 const isCourseBuilder = document.querySelector('#lp-course-builder') !== null;
@@ -1125,13 +1125,13 @@
1125 1125 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
1126 1126 /* harmony import */ var lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify.js */ "./assets/src/js/lpToastify.js");
1127 1127 /* harmony import */ var _edit_section_item_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./edit-section-item.js */ "./assets/src/js/admin/edit-course/edit-curriculum/edit-section-item.js");
1128 1128 /* harmony import */ var _edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../edit-curriculum.js */ "./assets/src/js/admin/edit-course/edit-curriculum.js");
1129 -/**
1130 - * Edit Section Script on Curriculum
1131 - *
1132 - * @since 4.2.8.6
1133 - * @version 1.0.3
1129 +/**
1130 + * Edit Section Script on Curriculum
1131 + *
1132 + * @since 4.2.8.6
1133 + * @version 1.0.3
1134 1134 */
1135 1135
1136 1136
1137 1137
@@ -1803,10 +1803,10 @@
1803 1803 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./../utils.js */ "./assets/src/js/utils.js");
1804 1804 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
1805 1805 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_1__);
1806 1806 /* harmony import */ var lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify.js */ "./assets/src/js/lpToastify.js");
1807 -/**
1808 - * Generate data with OpenAI
1807 +/**
1808 + * Generate data with OpenAI
1809 1809 */
1810 1810
1811 1811
1812 1812
@@ -1850,9 +1850,8 @@
1850 1850 </button>`);
1851 1851 });
1852 1852 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady('#wp-content-media-buttons', el => {
1853 1853 el.insertAdjacentHTML('beforeend', `<button type="button"
1854 - style="padding: 5px 10px; justify-content: center;"
1855 1854 class="lp-btn-generate-with-ai lp-btn-ai-style"
1856 1855 data-template="#lp-tmpl-edit-description-ai">
1857 1856 <i class="lp-ico-ai"></i><span>Generate description with AI</span>
1858 1857 </button>`);
@@ -1859,9 +1858,8 @@
1859 1858 });
1860 1859 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady('#postimagediv', el => {
1861 1860 const elInside = el.querySelector('.postbox-header');
1862 1861 elInside.insertAdjacentHTML('afterend', `<button type="button"
1863 - style="padding: 5px 10px; justify-content: center;"
1864 1862 class="lp-btn-generate-with-ai lp-btn-ai-style"
1865 1863 data-template="#lp-tmpl-edit-image-ai">
1866 1864 <i class="lp-ico-ai"></i><span>${lpData.i18n.generate_with_ai}</span>
1867 1865 </button>`);
@@ -1886,9 +1884,8 @@
1886 1884
1887 1885 // For layout Gutenberg - button for description
1888 1886 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady('.editor-post-featured-image', el => {
1889 1887 el.insertAdjacentHTML('beforebegin', `<button type="button"
1890 - style="padding: 5px 10px; justify-content: center;"
1891 1888 class="lp-btn-generate-with-ai"
1892 1889 data-template="#lp-tmpl-edit-description-ai">
1893 1890 <i class="lp-ico-ai"></i><span>Generate description with AI</span>
1894 1891 </button>`);
@@ -1896,9 +1893,8 @@
1896 1893
1897 1894 // For layout Gutenberg - button for image
1898 1895 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady('.editor-post-featured-image', el => {
1899 1896 el.insertAdjacentHTML('afterend', `<button type="button"
1900 - style="padding: 5px 10px; justify-content: center;"
1901 1897 class="lp-btn-generate-with-ai"
1902 1898 data-template="#lp-tmpl-edit-image-ai">
1903 1899 <i class="lp-ico-ai"></i><span>${lpData.i18n.generate_with_ai}</span>
1904 1900 </button>`);
@@ -1991,10 +1987,10 @@
1991 1987 sweetalert2__WEBPACK_IMPORTED_MODULE_1___default().close();
1992 1988 }
1993 1989
1994 1990 // Testing custom confirm box
1995 - /*if ( confirm( message ) ) {
1996 - SweetAlert.close();
1991 + /*if ( confirm( message ) ) {
1992 + SweetAlert.close();
1997 1993 }*/
1998 1994 }
1999 1995 }]);
2000 1996 }
@@ -2147,11 +2143,11 @@
2147 2143 }
2148 2144 });
2149 2145 }
2150 2146
2151 - /**
2152 - * Create prompt from data config
2153 - * @param args
2147 + /**
2148 + * Create prompt from data config
2149 + * @param args
2154 2150 */
2155 2151 generatePrompt(args) {
2156 2152 const {
2157 2153 e,
@@ -2190,11 +2186,11 @@
2190 2186 };
2191 2187 window.lpAJAXG.fetchAJAX(dataSend, callBack);
2192 2188 }
2193 2189
2194 - /**
2195 - * Submit prompt to OpenAI to generate course data
2196 - * @param args
2190 + /**
2191 + * Submit prompt to OpenAI to generate course data
2192 + * @param args
2197 2193 */
2198 2194 generateData(args) {
2199 2195 const {
2200 2196 e,
@@ -2308,12 +2304,12 @@
2308 2304 }
2309 2305 document.body.removeChild(textarea);
2310 2306 }
2311 2307
2312 - /*navigator.clipboard.writeText( dataCopy ).then( () => {
2313 - lpToastify.show( 'Copied to clipboard!', 'success' );
2314 - } ).catch( ( err ) => {
2315 - lpToastify.show( 'Failed to copy text: ' + err, 'error' );
2308 + /*navigator.clipboard.writeText( dataCopy ).then( () => {
2309 + lpToastify.show( 'Copied to clipboard!', 'success' );
2310 + } ).catch( ( err ) => {
2311 + lpToastify.show( 'Failed to copy text: ' + err, 'error' );
2316 2312 } );*/
2317 2313 }
2318 2314 setWPEditorContent(htmlContent) {
2319 2315 const editorId = this.getEditorId();
@@ -2399,12 +2395,12 @@
2399 2395 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
2400 2396 /* harmony import */ var lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify.js */ "./assets/src/js/lpToastify.js");
2401 2397 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
2402 2398 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_2__);
2403 -/**
2404 - * LearnPress Popup Select Item
2405 - *
2406 - * Handles load(search) item from API, show in popup and select item.
2399 +/**
2400 + * LearnPress Popup Select Item
2401 + *
2402 + * Handles load(search) item from API, show in popup and select item.
2407 2403 */
2408 2404
2409 2405
2410 2406
@@ -2491,9 +2487,9 @@
2491 2487 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
2492 2488 html: modalTemplate.innerHTML,
2493 2489 showConfirmButton: false,
2494 2490 showCloseButton: true,
2495 - width: '60%',
2491 + width: 'max(350px, 65vw)',
2496 2492 customClass: {
2497 2493 popup: 'lp-select-items-popup',
2498 2494 htmlContainer: 'lp-select-items-html-container',
2499 2495 container: 'lp-select-items-container'
@@ -2500,25 +2496,33 @@
2500 2496 },
2501 2497 willOpen: () => {
2502 2498 elPopup = sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().getPopup();
2503 2499 const elLPTarget = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
2504 - if (elLPTarget) {
2505 - const dataSend = window.lpAJAXG.getDataSetCurrent(elLPTarget);
2506 - dataSend.args.paged = 1;
2507 - dataSend.args.item_selecting = itemsSelectedData || [];
2508 - window.lpAJAXG.setDataSetCurrent(elLPTarget, dataSend);
2509 - window.lpAJAXG.fetchAJAX(dataSend, {
2510 - success: response => {
2511 - const {
2512 - data
2513 - } = response;
2514 - const elSkeleton = elPopup.querySelector('.lp-skeleton-animation');
2515 - elSkeleton.remove();
2516 - elLPTarget.innerHTML = data.content || '';
2517 - this.watchItemsSelectedDataChange();
2518 - }
2519 - });
2520 - }
2500 +
2501 + // Avoid duplicate AJAX: loadAJAX.js handles fresh elements; skip if already loaded. Set timeout to ensure DOM is ready handle.
2502 + setTimeout(() => {
2503 + const elLoadAjaxElement = elLPTarget.closest('.lp-load-ajax-element:not(.loaded)');
2504 + if (!elLoadAjaxElement) {
2505 + return;
2506 + }
2507 + if (elLPTarget) {
2508 + const dataSend = window.lpAJAXG.getDataSetCurrent(elLPTarget);
2509 + dataSend.args.paged = 1;
2510 + dataSend.args.item_selecting = itemsSelectedData || [];
2511 + window.lpAJAXG.setDataSetCurrent(elLPTarget, dataSend);
2512 + window.lpAJAXG.fetchAJAX(dataSend, {
2513 + success: response => {
2514 + const {
2515 + data
2516 + } = response;
2517 + const elSkeleton = elPopup.querySelector('.lp-skeleton-animation');
2518 + elSkeleton.remove();
2519 + elLPTarget.innerHTML = data.content || '';
2520 + this.watchItemsSelectedDataChange();
2521 + }
2522 + });
2523 + }
2524 + }, 1);
2521 2525 }
2522 2526 }).then(result => {
2523 2527 if (result.isDismissed) {}
2524 2528 });
@@ -2803,16 +2807,16 @@
2803 2807 /* harmony export */ });
2804 2808 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js");
2805 2809 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_0__);
2806 2810 /* harmony import */ var toastify_js_src_toastify_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! toastify-js/src/toastify.css */ "./node_modules/toastify-js/src/toastify.css");
2807 -/**
2808 - * Utils functions
2809 - *
2810 - * @param url
2811 - * @param data
2812 - * @param functions
2813 - * @since 4.3.0
2814 - * @version 1.0.0
2811 +/**
2812 + * Utils functions
2813 + *
2814 + * @param url
2815 + * @param data
2816 + * @param functions
2817 + * @since 4.3.0
2818 + * @version 1.0.0
2815 2819 */
2816 2820
2817 2821
2818 2822 const argsToastify = {
@@ -2854,8 +2858,9 @@
2854 2858 __webpack_require__.r(__webpack_exports__);
2855 2859 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2856 2860 /* harmony export */ debounce: () => (/* binding */ debounce),
2857 2861 /* harmony export */ eventHandlers: () => (/* binding */ eventHandlers),
2862 +/* harmony export */ fullScreenView: () => (/* binding */ fullScreenView),
2858 2863 /* harmony export */ getDataOfForm: () => (/* binding */ getDataOfForm),
2859 2864 /* harmony export */ getFieldKeysOfForm: () => (/* binding */ getFieldKeysOfForm),
2860 2865 /* harmony export */ listenElementCreated: () => (/* binding */ listenElementCreated),
2861 2866 /* harmony export */ listenElementViewed: () => (/* binding */ listenElementViewed),
@@ -2867,18 +2872,19 @@
2867 2872 /* harmony export */ lpOnElementReady: () => (/* binding */ lpOnElementReady),
2868 2873 /* harmony export */ lpSetLoadingEl: () => (/* binding */ lpSetLoadingEl),
2869 2874 /* harmony export */ lpShowHideEl: () => (/* binding */ lpShowHideEl),
2870 2875 /* harmony export */ mergeDataWithDatForm: () => (/* binding */ mergeDataWithDatForm),
2871 -/* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse)
2876 +/* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse),
2877 +/* harmony export */ toggleEnable: () => (/* binding */ toggleEnable)
2872 2878 /* harmony export */ });
2873 -/**
2874 - * Utils functions
2875 - *
2876 - * @param url
2877 - * @param data
2878 - * @param functions
2879 - * @since 4.2.5.1
2880 - * @version 1.0.6
2879 +/**
2880 + * Utils functions
2881 + *
2882 + * @param url
2883 + * @param data
2884 + * @param functions
2885 + * @since 4.2.5.1
2886 + * @version 1.0.7
2881 2887 */
2882 2888 const lpClassName = {
2883 2889 hidden: 'lp-hidden',
2884 2890 loading: 'loading',
@@ -2883,9 +2889,12 @@
2883 2889 hidden: 'lp-hidden',
2884 2890 loading: 'loading',
2885 2891 elCollapse: 'lp-collapse',
2886 2892 elSectionToggle: '.lp-section-toggle',
2887 - elTriggerToggle: '.lp-trigger-toggle'
2893 + elTriggerToggle: '.lp-trigger-toggle',
2894 + elBtnFullScreen: '.lp-btn-full-screen-view',
2895 + elFullScreen: 'lp-full-screen-view',
2896 + elBtnFullScreenClose: 'lp-full-screen-view__close'
2888 2897 };
2889 2898 const lpFetchAPI = (url, data = {}, functions = {}) => {
2890 2899 if ('function' === typeof functions.before) {
2891 2900 functions.before();
@@ -2907,12 +2916,12 @@
2907 2916 }
2908 2917 });
2909 2918 };
2910 2919
2911 -/**
2912 - * Get current URL without params.
2913 - *
2914 - * @since 4.2.5.1
2920 +/**
2921 + * Get current URL without params.
2922 + *
2923 + * @since 4.2.5.1
2915 2924 */
2916 2925 const lpGetCurrentURLNoParam = () => {
2917 2926 let currentUrl = window.location.href;
2918 2927 const hasParams = currentUrl.includes('?');
@@ -2928,14 +2937,14 @@
2928 2937 });
2929 2938 return url;
2930 2939 };
2931 2940
2932 -/**
2933 - * Listen element viewed.
2934 - *
2935 - * @param el
2936 - * @param callback
2937 - * @since 4.2.5.8
2941 +/**
2942 + * Listen element viewed.
2943 + *
2944 + * @param el
2945 + * @param callback
2946 + * @since 4.2.5.8
2938 2947 */
2939 2948 const listenElementViewed = (el, callback) => {
2940 2949 const observerSeeItem = new IntersectionObserver(function (entries) {
2941 2950 for (const entry of entries) {
@@ -2946,13 +2955,13 @@
2946 2955 });
2947 2956 observerSeeItem.observe(el);
2948 2957 };
2949 2958
2950 -/**
2951 - * Listen element created.
2952 - *
2953 - * @param callback
2954 - * @since 4.2.5.8
2959 +/**
2960 + * Listen element created.
2961 + *
2962 + * @param callback
2963 + * @since 4.2.5.8
2955 2964 */
2956 2965 const listenElementCreated = callback => {
2957 2966 const observerCreateItem = new MutationObserver(function (mutations) {
2958 2967 mutations.forEach(function (mutation) {
@@ -2971,14 +2980,14 @@
2971 2980 });
2972 2981 // End.
2973 2982 };
2974 2983
2975 -/**
2976 - * Listen element created.
2977 - *
2978 - * @param selector
2979 - * @param callback
2980 - * @since 4.2.7.1
2984 +/**
2985 + * Listen element created.
2986 + *
2987 + * @param selector
2988 + * @param callback
2989 + * @since 4.2.7.1
2981 2990 */
2982 2991 const lpOnElementReady = (selector, callback) => {
2983 2992 const element = document.querySelector(selector);
2984 2993 if (element) {
@@ -3119,17 +3128,17 @@
3119 3128 };
3120 3129 return dataHandle;
3121 3130 };
3122 3131
3123 -/**
3124 - * Event trigger
3125 - * For each list of event handlers, listen event on document.
3126 - *
3127 - * eventName: 'click', 'change', ...
3128 - * eventHandlers = [ { selector: '.lp-button', callBack: function(){}, class: object } ]
3129 - *
3130 - * @param eventName
3131 - * @param eventHandlers
3132 +/**
3133 + * Event trigger
3134 + * For each list of event handlers, listen event on document.
3135 + *
3136 + * eventName: 'click', 'change', ...
3137 + * eventHandlers = [ { selector: '.lp-button', callBack: function(){}, class: object } ]
3138 + *
3139 + * @param eventName
3140 + * @param eventHandlers
3132 3141 */
3133 3142 const eventHandlers = (eventName, eventHandlers) => {
3134 3143 document.addEventListener(eventName, e => {
3135 3144 const target = e.target;
@@ -3170,32 +3179,32 @@
3170 3179 });
3171 3180 });
3172 3181 };
3173 3182
3174 -/**
3175 - * Debounce - delays function execution until after `wait` ms of inactivity.
3176 - *
3177 - * Each call resets the timer. Only the last call in a burst executes.
3178 - *
3179 - * USE CASES:
3180 - * - Search inputs, form validation, window resize
3181 - * - Multiple elements need independent timers
3182 - * - When you need to call with different arguments
3183 - *
3184 - * EXAMPLES:
3185 - * const debouncedSearch = debounce( (query) => fetchResults(query), 300 );
3186 - * searchInput.addEventListener('input', (e) => debouncedSearch(e.target.value));
3187 - *
3188 - * const debouncedResize = debounce( recalculateLayout, 250 );
3189 - * window.addEventListener('resize', debouncedResize);
3190 - *
3191 - * ⚠️ Create ONCE outside event handlers, not inside.
3192 - *
3193 - * @param {Function} func - Function to debounce (can be anonymous)
3194 - * @param {number} wait - Milliseconds to wait (default: 500)
3195 - * @return {Function} Debounced wrapper function
3196 - * @since 4.3.7
3197 - * @version 1.0.0
3183 +/**
3184 + * Debounce - delays function execution until after `wait` ms of inactivity.
3185 + *
3186 + * Each call resets the timer. Only the last call in a burst executes.
3187 + *
3188 + * USE CASES:
3189 + * - Search inputs, form validation, window resize
3190 + * - Multiple elements need independent timers
3191 + * - When you need to call with different arguments
3192 + *
3193 + * EXAMPLES:
3194 + * const debouncedSearch = debounce( (query) => fetchResults(query), 300 );
3195 + * searchInput.addEventListener('input', (e) => debouncedSearch(e.target.value));
3196 + *
3197 + * const debouncedResize = debounce( recalculateLayout, 250 );
3198 + * window.addEventListener('resize', debouncedResize);
3199 + *
3200 + * ⚠️ Create ONCE outside event handlers, not inside.
3201 + *
3202 + * @param {Function} func - Function to debounce (can be anonymous)
3203 + * @param {number} wait - Milliseconds to wait (default: 500)
3204 + * @return {Function} Debounced wrapper function
3205 + * @since 4.3.7
3206 + * @version 1.0.0
3198 3207 */
3199 3208 const debounce = (func, wait = 500) => {
3200 3209 let timer;
3201 3210 return args => {
@@ -3203,8 +3212,141 @@
3203 3212 timer = setTimeout(() => func(args), wait);
3204 3213 };
3205 3214 };
3206 3215
3216 +/**
3217 + * Initialize lp-toggle-enable components.
3218 + *
3219 + * Finds all `.lp-toggle-enable` elements and wires up toggle behavior.
3220 + * Reads initial state from `data-enabled` attribute ("true"/"false").
3221 + * Calls `data-on-toggle` callback (if provided via options) on state change.
3222 + *
3223 + * HTML structure:
3224 + * <label class="lp-toggle-enable" data-enabled="true">
3225 + * <input type="checkbox" class="lp-toggle-enable__input" />
3226 + * <span class="lp-toggle-enable__track"></span>
3227 + * </label>
3228 + *
3229 + * @param {string} selector CSS selector for toggle elements (default: '.lp-toggle-enable')
3230 + * @param {Function} onToggle Optional callback( el, isEnabled ) called on state change
3231 + * @since 4.4.5
3232 + * @version 1.0.0
3233 + */
3234 +window.lpToggleEnableInit = 0;
3235 +const toggleEnable = (onToggle = null) => {
3236 + if (window.lpToggleEnableInit) {
3237 + return;
3238 + }
3239 + window.lpToggleEnableInit = 1;
3240 + const selector = '.lp-toggle-enable';
3241 + const updateUI = (toggle, isEnabled) => {
3242 + toggle.classList.toggle('is-enabled', isEnabled);
3243 + const input = toggle.querySelector('.lp-toggle-enable__input');
3244 + if (input) {
3245 + input.checked = isEnabled;
3246 + input.value = isEnabled ? '1' : '0';
3247 + }
3248 + };
3249 +
3250 + // Delegate click handling via eventHandlers.
3251 + eventHandlers('click', [{
3252 + selector,
3253 + callBack: args => {
3254 + const {
3255 + e,
3256 + target
3257 + } = args;
3258 + const toggle = target.closest(selector);
3259 + if (!toggle || toggle.classList.contains('is-disabled')) {
3260 + return;
3261 + }
3262 + e.preventDefault();
3263 + const isEnabled = !toggle.classList.contains('is-enabled');
3264 + updateUI(toggle, isEnabled);
3265 + if ('function' === typeof onToggle) {
3266 + onToggle(toggle, isEnabled);
3267 + }
3268 + }
3269 + }]);
3270 +};
3271 +
3272 +/**
3273 + * Initialize custom fullscreen view buttons.
3274 + *
3275 + * Delegates clicks on `.lp-btn-full-screen-view` buttons to
3276 + * `lpToggleFullscreenView`. Reads the `data-target` attribute to find the
3277 + * target element. Falls back to the button's parent element when
3278 + * `data-target` is not provided.
3279 + *
3280 + * @since 4.4.5
3281 + * @version 1.0.0
3282 + */
3283 +window.lpFullScreenViewInit = 0;
3284 +const fullScreenView = () => {
3285 + if (window.lpFullScreenViewInit) {
3286 + return;
3287 + }
3288 + window.lpFullScreenViewInit = 1;
3289 + let lastScrollY = 0;
3290 + const lpToggleFullscreenView = (elTarget, elBtnFullScreen = null) => {
3291 + const isFullscreen = elTarget.classList.contains(lpClassName.elFullScreen);
3292 + if (isFullscreen) {
3293 + elTarget.classList.remove(lpClassName.elFullScreen);
3294 + document.documentElement.classList.remove('lp-full-screen-active');
3295 + window.scrollTo(0, lastScrollY);
3296 + } else {
3297 + lastScrollY = window.scrollY;
3298 + elTarget.classList.add(lpClassName.elFullScreen);
3299 + document.documentElement.classList.add('lp-full-screen-active');
3300 + }
3301 + if (!isFullscreen) {
3302 + if (!elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`)) {
3303 + const closeButton = document.createElement('button');
3304 + closeButton.type = 'button';
3305 + closeButton.className = lpClassName.elBtnFullScreenClose;
3306 + closeButton.setAttribute('aria-label', 'Close');
3307 + closeButton.innerHTML = lpData.i18n.closeButtonFullScreen || 'Close &times;';
3308 + closeButton.addEventListener('click', e => {
3309 + e.preventDefault();
3310 + lpToggleFullscreenView(elTarget);
3311 + });
3312 + elTarget.appendChild(closeButton);
3313 + }
3314 + } else {
3315 + const closeButton = elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`);
3316 + if (closeButton) {
3317 + closeButton.remove();
3318 + }
3319 + }
3320 + };
3321 + eventHandlers('click', [{
3322 + selector: lpClassName.elBtnFullScreen,
3323 + callBack: args => {
3324 + const {
3325 + e,
3326 + target
3327 + } = args;
3328 + const elBtnFullScreen = target.closest(lpClassName.elBtnFullScreen);
3329 + if (!elBtnFullScreen) {
3330 + console.log('No full screen button found');
3331 + return;
3332 + }
3333 + e.preventDefault();
3334 + let elTarget = null;
3335 + const targetSelector = elBtnFullScreen.dataset.targetFullscreen;
3336 + console.log(targetSelector);
3337 + if (targetSelector) {
3338 + elTarget = document.querySelector(targetSelector);
3339 + }
3340 + if (!elTarget) {
3341 + console.log('No target element found');
3342 + return;
3343 + }
3344 + lpToggleFullscreenView(elTarget, elBtnFullScreen);
3345 + }
3346 + }]);
3347 +};
3348 +
3207 3349 /***/ },
3208 3350
3209 3351 /***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css"
3210 3352 /*!*****************************************************************************************!*\
@@ -12525,13 +12667,13 @@
12525 12667 __webpack_require__.r(__webpack_exports__);
12526 12668 /* harmony import */ var _edit_course_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./edit-course/edit-curriculum.js */ "./assets/src/js/admin/edit-course/edit-curriculum.js");
12527 12669 /* harmony import */ var _generate_with_openai_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./generate-with-openai.js */ "./assets/src/js/admin/generate-with-openai.js");
12528 12670 /* harmony import */ var _edit_course_edit_curriculum_edit_curriculum_ai_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./edit-course/edit-curriculum/edit-curriculum-ai.js */ "./assets/src/js/admin/edit-course/edit-curriculum/edit-curriculum-ai.js");
12529 -/**
12530 - * Edit course JS handler.
12531 - *
12532 - * @since 4.3.0
12533 - * @version 1.0.0
12671 +/**
12672 + * Edit course JS handler.
12673 + *
12674 + * @since 4.3.0
12675 + * @version 1.0.0
12534 12676 */
12535 12677
12536 12678
12537 12679