PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.9.1
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.9.1
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 4.1.7.3.1 All 141 releases
← All changes | assets/js/dist/frontend/single-course.js +215 -54 4.3.7 → 4.4.9.1 View file →
@@ -942,8 +942,9 @@
942 942 __webpack_require__.r(__webpack_exports__);
943 943 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
944 944 /* harmony export */ debounce: () => (/* binding */ debounce),
945 945 /* harmony export */ eventHandlers: () => (/* binding */ eventHandlers),
946 +/* harmony export */ fullScreenView: () => (/* binding */ fullScreenView),
946 947 /* harmony export */ getDataOfForm: () => (/* binding */ getDataOfForm),
947 948 /* harmony export */ getFieldKeysOfForm: () => (/* binding */ getFieldKeysOfForm),
948 949 /* harmony export */ listenElementCreated: () => (/* binding */ listenElementCreated),
949 950 /* harmony export */ listenElementViewed: () => (/* binding */ listenElementViewed),
@@ -955,9 +956,10 @@
955 956 /* harmony export */ lpOnElementReady: () => (/* binding */ lpOnElementReady),
956 957 /* harmony export */ lpSetLoadingEl: () => (/* binding */ lpSetLoadingEl),
957 958 /* harmony export */ lpShowHideEl: () => (/* binding */ lpShowHideEl),
958 959 /* harmony export */ mergeDataWithDatForm: () => (/* binding */ mergeDataWithDatForm),
959 -/* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse)
960 +/* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse),
961 +/* harmony export */ toggleEnable: () => (/* binding */ toggleEnable)
960 962 /* harmony export */ });
961 963 /**
962 964 * Utils functions
963 965 *
@@ -964,9 +966,9 @@
964 966 * @param url
965 967 * @param data
966 968 * @param functions
967 969 * @since 4.2.5.1
968 - * @version 1.0.6
970 + * @version 1.0.7
969 971 */
970 972 const lpClassName = {
971 973 hidden: 'lp-hidden',
972 974 loading: 'loading',
@@ -971,9 +973,12 @@
971 973 hidden: 'lp-hidden',
972 974 loading: 'loading',
973 975 elCollapse: 'lp-collapse',
974 976 elSectionToggle: '.lp-section-toggle',
975 - elTriggerToggle: '.lp-trigger-toggle'
977 + elTriggerToggle: '.lp-trigger-toggle',
978 + elBtnFullScreen: '.lp-btn-full-screen-view',
979 + elFullScreen: 'lp-full-screen-view',
980 + elBtnFullScreenClose: 'lp-full-screen-view__close'
976 981 };
977 982 const lpFetchAPI = (url, data = {}, functions = {}) => {
978 983 if ('function' === typeof functions.before) {
979 984 functions.before();
@@ -1291,8 +1296,141 @@
1291 1296 timer = setTimeout(() => func(args), wait);
1292 1297 };
1293 1298 };
1294 1299
1300 +/**
1301 + * Initialize lp-toggle-enable components.
1302 + *
1303 + * Finds all `.lp-toggle-enable` elements and wires up toggle behavior.
1304 + * Reads initial state from `data-enabled` attribute ("true"/"false").
1305 + * Calls `data-on-toggle` callback (if provided via options) on state change.
1306 + *
1307 + * HTML structure:
1308 + * <label class="lp-toggle-enable" data-enabled="true">
1309 + * <input type="checkbox" class="lp-toggle-enable__input" />
1310 + * <span class="lp-toggle-enable__track"></span>
1311 + * </label>
1312 + *
1313 + * @param {string} selector CSS selector for toggle elements (default: '.lp-toggle-enable')
1314 + * @param {Function} onToggle Optional callback( el, isEnabled ) called on state change
1315 + * @since 4.4.5
1316 + * @version 1.0.0
1317 + */
1318 +window.lpToggleEnableInit = 0;
1319 +const toggleEnable = (onToggle = null) => {
1320 + if (window.lpToggleEnableInit) {
1321 + return;
1322 + }
1323 + window.lpToggleEnableInit = 1;
1324 + const selector = '.lp-toggle-enable';
1325 + const updateUI = (toggle, isEnabled) => {
1326 + toggle.classList.toggle('is-enabled', isEnabled);
1327 + const input = toggle.querySelector('.lp-toggle-enable__input');
1328 + if (input) {
1329 + input.checked = isEnabled;
1330 + input.value = isEnabled ? '1' : '0';
1331 + }
1332 + };
1333 +
1334 + // Delegate click handling via eventHandlers.
1335 + eventHandlers('click', [{
1336 + selector,
1337 + callBack: args => {
1338 + const {
1339 + e,
1340 + target
1341 + } = args;
1342 + const toggle = target.closest(selector);
1343 + if (!toggle || toggle.classList.contains('is-disabled')) {
1344 + return;
1345 + }
1346 + e.preventDefault();
1347 + const isEnabled = !toggle.classList.contains('is-enabled');
1348 + updateUI(toggle, isEnabled);
1349 + if ('function' === typeof onToggle) {
1350 + onToggle(toggle, isEnabled);
1351 + }
1352 + }
1353 + }]);
1354 +};
1355 +
1356 +/**
1357 + * Initialize custom fullscreen view buttons.
1358 + *
1359 + * Delegates clicks on `.lp-btn-full-screen-view` buttons to
1360 + * `lpToggleFullscreenView`. Reads the `data-target` attribute to find the
1361 + * target element. Falls back to the button's parent element when
1362 + * `data-target` is not provided.
1363 + *
1364 + * @since 4.4.5
1365 + * @version 1.0.0
1366 + */
1367 +window.lpFullScreenViewInit = 0;
1368 +const fullScreenView = () => {
1369 + if (window.lpFullScreenViewInit) {
1370 + return;
1371 + }
1372 + window.lpFullScreenViewInit = 1;
1373 + let lastScrollY = 0;
1374 + const lpToggleFullscreenView = (elTarget, elBtnFullScreen = null) => {
1375 + const isFullscreen = elTarget.classList.contains(lpClassName.elFullScreen);
1376 + if (isFullscreen) {
1377 + elTarget.classList.remove(lpClassName.elFullScreen);
1378 + document.documentElement.classList.remove('lp-full-screen-active');
1379 + window.scrollTo(0, lastScrollY);
1380 + } else {
1381 + lastScrollY = window.scrollY;
1382 + elTarget.classList.add(lpClassName.elFullScreen);
1383 + document.documentElement.classList.add('lp-full-screen-active');
1384 + }
1385 + if (!isFullscreen) {
1386 + if (!elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`)) {
1387 + const closeButton = document.createElement('button');
1388 + closeButton.type = 'button';
1389 + closeButton.className = lpClassName.elBtnFullScreenClose;
1390 + closeButton.setAttribute('aria-label', 'Close');
1391 + closeButton.innerHTML = lpData.i18n.closeButtonFullScreen || 'Close &times;';
1392 + closeButton.addEventListener('click', e => {
1393 + e.preventDefault();
1394 + lpToggleFullscreenView(elTarget);
1395 + });
1396 + elTarget.appendChild(closeButton);
1397 + }
1398 + } else {
1399 + const closeButton = elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`);
1400 + if (closeButton) {
1401 + closeButton.remove();
1402 + }
1403 + }
1404 + };
1405 + eventHandlers('click', [{
1406 + selector: lpClassName.elBtnFullScreen,
1407 + callBack: args => {
1408 + const {
1409 + e,
1410 + target
1411 + } = args;
1412 + const elBtnFullScreen = target.closest(lpClassName.elBtnFullScreen);
1413 + if (!elBtnFullScreen) {
1414 + console.log('No full screen button found');
1415 + return;
1416 + }
1417 + e.preventDefault();
1418 + let elTarget = null;
1419 + const targetSelector = elBtnFullScreen.dataset.targetFullscreen;
1420 + console.log(targetSelector);
1421 + if (targetSelector) {
1422 + elTarget = document.querySelector(targetSelector);
1423 + }
1424 + if (!elTarget) {
1425 + console.log('No target element found');
1426 + return;
1427 + }
1428 + lpToggleFullscreenView(elTarget, elBtnFullScreen);
1429 + }
1430 + }]);
1431 +};
1432 +
1295 1433 /***/ },
1296 1434
1297 1435 /***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css"
1298 1436 /*!*****************************************************************************************!*\
@@ -2356,19 +2494,19 @@
2356 2494
2357 2495 /******/ });
2358 2496 /************************************************************************/
2359 2497 /******/ // The module cache
2360 -/******/ var __webpack_module_cache__ = {};
2498 +/******/ const __webpack_module_cache__ = {};
2361 2499 /******/
2362 2500 /******/ // The require function
2363 2501 /******/ function __webpack_require__(moduleId) {
2364 2502 /******/ // Check if module is in cache
2365 -/******/ var cachedModule = __webpack_module_cache__[moduleId];
2503 +/******/ const cachedModule = __webpack_module_cache__[moduleId];
2366 2504 /******/ if (cachedModule !== undefined) {
2367 2505 /******/ return cachedModule.exports;
2368 2506 /******/ }
2369 2507 /******/ // Create a new module (and put it into the cache)
2370 -/******/ var module = __webpack_module_cache__[moduleId] = {
2508 +/******/ const module = __webpack_module_cache__[moduleId] = {
2371 2509 /******/ id: moduleId,
2372 2510 /******/ // no module.loaded needed
2373 2511 /******/ exports: {}
2374 2512 /******/ };
@@ -2375,9 +2513,9 @@
2375 2513 /******/
2376 2514 /******/ // Execute the module function
2377 2515 /******/ if (!(moduleId in __webpack_modules__)) {
2378 2516 /******/ delete __webpack_module_cache__[moduleId];
2379 -/******/ var e = new Error("Cannot find module '" + moduleId + "'");
2517 +/******/ const e = new Error("Cannot find module '" + moduleId + "'");
2380 2518 /******/ e.code = 'MODULE_NOT_FOUND';
2381 2519 /******/ throw e;
2382 2520 /******/ }
2383 2521 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
@@ -2390,9 +2528,9 @@
2390 2528 /******/ /* webpack/runtime/compat get default export */
2391 2529 /******/ (() => {
2392 2530 /******/ // getDefaultExport function for compatibility with non-harmony modules
2393 2531 /******/ __webpack_require__.n = (module) => {
2394 -/******/ var getter = module && module.__esModule ?
2532 +/******/ const getter = module && module.__esModule ?
2395 2533 /******/ () => (module['default']) :
2396 2534 /******/ () => (module);
2397 2535 /******/ __webpack_require__.d(getter, { a: getter });
2398 2536 /******/ return getter;
@@ -2400,14 +2538,29 @@
2400 2538 /******/ })();
2401 2539 /******/
2402 2540 /******/ /* webpack/runtime/define property getters */
2403 2541 /******/ (() => {
2404 -/******/ // define getter functions for harmony exports
2542 +/******/ // define getter/value functions for harmony exports
2405 2543 /******/ __webpack_require__.d = (exports, definition) => {
2406 -/******/ for(var key in definition) {
2407 -/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
2408 -/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
2544 +/******/ if(Array.isArray(definition)) {
2545 +/******/ var i = 0;
2546 +/******/ while(i < definition.length) {
2547 +/******/ var key = definition[i++];
2548 +/******/ var binding = definition[i++];
2549 +/******/ if(!__webpack_require__.o(exports, key)) {
2550 +/******/ if(binding === 0) {
2551 +/******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
2552 +/******/ } else {
2553 +/******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
2554 +/******/ }
2555 +/******/ } else if(binding === 0) { i++; }
2409 2556 /******/ }
2557 +/******/ } else {
2558 +/******/ for(var key in definition) {
2559 +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
2560 +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
2561 +/******/ }
2562 +/******/ }
2410 2563 /******/ }
2411 2564 /******/ };
2412 2565 /******/ })();
2413 2566 /******/
@@ -2412,9 +2565,9 @@
2412 2565 /******/ })();
2413 2566 /******/
2414 2567 /******/ /* webpack/runtime/hasOwnProperty shorthand */
2415 2568 /******/ (() => {
2416 -/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
2569 +/******/ __webpack_require__.o = (obj, prop) => (Object.hasOwn(obj, prop))
2417 2570 /******/ })();
2418 2571 /******/
2419 2572 /******/ /* webpack/runtime/make namespace object */
2420 2573 /******/ (() => {
@@ -2419,9 +2572,9 @@
2419 2572 /******/ /* webpack/runtime/make namespace object */
2420 2573 /******/ (() => {
2421 2574 /******/ // define __esModule on exports
2422 2575 /******/ __webpack_require__.r = (exports) => {
2423 -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
2576 +/******/ if(Symbol.toStringTag) {
2424 2577 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2425 2578 /******/ }
2426 2579 /******/ Object.defineProperty(exports, '__esModule', { value: true });
2427 2580 /******/ };
@@ -2432,9 +2585,9 @@
2432 2585 /******/ __webpack_require__.nc = undefined;
2433 2586 /******/ })();
2434 2587 /******/
2435 2588 /************************************************************************/
2436 -var __webpack_exports__ = {};
2589 +let __webpack_exports__ = {};
2437 2590 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
2438 2591 (() => {
2439 2592 "use strict";
2440 2593 /*!******************************************************!*\
@@ -2738,46 +2891,54 @@
2738 2891 });
2739 2892 };
2740 2893
2741 2894 // Rest API load content course progress - Nhamdv.
2742 -const courseProgress = () => {
2743 - const elements = document.querySelectorAll('.lp-course-progress-wrapper');
2744 - if (!elements.length) {
2745 - return;
2746 - }
2747 - if ('IntersectionObserver' in window) {
2748 - const eleObserver = new IntersectionObserver((entries, observer) => {
2749 - entries.forEach(entry => {
2750 - if (entry.isIntersecting) {
2751 - const ele = entry.target;
2752 - setTimeout(function () {
2753 - getResponse(ele);
2754 - }, 600);
2755 - eleObserver.unobserve(ele);
2756 - }
2757 - });
2758 - });
2759 - [...elements].map(ele => eleObserver.observe(ele));
2760 - }
2761 - const getResponse = async ele => {
2762 - let url = 'lp/v1/lazy-load/course-progress';
2763 - if (lpData.urlParams.hasOwnProperty('lang')) {
2764 - url += '?lang=' + lpData.urlParams.lang;
2765 - }
2766 - const response = await wp.apiFetch({
2767 - path: url,
2768 - method: 'POST',
2769 - data: {
2770 - courseId: lpGlobalSettings.post_id || '',
2771 - userId: lpData.user_id || ''
2772 - }
2773 - });
2774 - const {
2775 - data
2776 - } = response;
2777 - ele.innerHTML = data;
2778 - };
2779 -};
2895 +/*const courseProgress = () => {
2896 + const elements = document.querySelectorAll( '.lp-course-progress-wrapper' );
2897 +
2898 + if ( ! elements.length ) {
2899 + return;
2900 + }
2901 +
2902 + if ( 'IntersectionObserver' in window ) {
2903 + const eleObserver = new IntersectionObserver( ( entries, observer ) => {
2904 + entries.forEach( ( entry ) => {
2905 + if ( entry.isIntersecting ) {
2906 + const ele = entry.target;
2907 +
2908 + setTimeout( function() {
2909 + getResponse( ele );
2910 + }, 600 );
2911 +
2912 + eleObserver.unobserve( ele );
2913 + }
2914 + } );
2915 + } );
2916 +
2917 + [ ...elements ].map( ( ele ) => eleObserver.observe( ele ) );
2918 + }
2919 +
2920 + const getResponse = async ( ele ) => {
2921 + let url = 'lp/v1/lazy-load/course-progress';
2922 + if ( lpData.urlParams.hasOwnProperty( 'lang' ) ) {
2923 + url += '?lang=' + lpData.urlParams.lang;
2924 + }
2925 +
2926 + const response = await wp.apiFetch( {
2927 + path: url,
2928 + method: 'POST',
2929 + data: {
2930 + courseId: lpGlobalSettings.post_id || '',
2931 + userId: lpData.user_id || '',
2932 + },
2933 + } );
2934 +
2935 + const { data } = response;
2936 +
2937 + ele.innerHTML = data;
2938 + };
2939 +};*/
2940 +
2780 2941 const accordionExtraTab = () => {
2781 2942 const elements = document.querySelectorAll('.course-extra-box');
2782 2943 [...elements].map(ele => {
2783 2944 const title = ele.querySelector('.course-extra-box__title');
@@ -2836,9 +2997,9 @@
2836 2997 initCourseSidebar();
2837 2998 enrollCourse();
2838 2999 purchaseCourse();
2839 3000 retakeCourse();
2840 - courseProgress();
3001 + //courseProgress();
2841 3002 courseContinue();
2842 3003 _show_lp_overlay_complete_item__WEBPACK_IMPORTED_MODULE_2__["default"].init();
2843 3004 (0,_material__WEBPACK_IMPORTED_MODULE_5__["default"])();
2844 3005 //courseCurriculumSkeleton();