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 +167 -25 4.3.7 → 4.4.9 View file →
@@ -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>`);
@@ -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 });
@@ -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,9 +2872,10 @@
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 2879 /**
2874 2880 * Utils functions
2875 2881 *
@@ -2876,9 +2882,9 @@
2876 2882 * @param url
2877 2883 * @param data
2878 2884 * @param functions
2879 2885 * @since 4.2.5.1
2880 - * @version 1.0.6
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();
@@ -3201,8 +3210,141 @@
3201 3210 return args => {
3202 3211 clearTimeout(timer);
3203 3212 timer = setTimeout(() => func(args), wait);
3204 3213 };
3214 +};
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 + }]);
3205 3347 };
3206 3348
3207 3349 /***/ },
3208 3350