PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
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 4.2.0 All 139 releases
learnpress / assets / js / dist / admin / learnpress.js

learnpress.js in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.8, at assets/js/dist/admin/learnpress.js

1,334 lines 42.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /******/ (() => { // webpackBootstrap
2 /******/ "use strict";
3 /******/ var __webpack_modules__ = ({
4
5 /***/ "./assets/src/js/utils.js"
6 /*!********************************!*\
7 !*** ./assets/src/js/utils.js ***!
8 \********************************/
9 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
10
11 __webpack_require__.r(__webpack_exports__);
12 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
13 /* harmony export */ debounce: () => (/* binding */ debounce),
14 /* harmony export */ eventHandlers: () => (/* binding */ eventHandlers),
15 /* harmony export */ fullScreenView: () => (/* binding */ fullScreenView),
16 /* harmony export */ getDataOfForm: () => (/* binding */ getDataOfForm),
17 /* harmony export */ getFieldKeysOfForm: () => (/* binding */ getFieldKeysOfForm),
18 /* harmony export */ listenElementCreated: () => (/* binding */ listenElementCreated),
19 /* harmony export */ listenElementViewed: () => (/* binding */ listenElementViewed),
20 /* harmony export */ lpAddQueryArgs: () => (/* binding */ lpAddQueryArgs),
21 /* harmony export */ lpAjaxParseJsonOld: () => (/* binding */ lpAjaxParseJsonOld),
22 /* harmony export */ lpClassName: () => (/* binding */ lpClassName),
23 /* harmony export */ lpFetchAPI: () => (/* binding */ lpFetchAPI),
24 /* harmony export */ lpGetCurrentURLNoParam: () => (/* binding */ lpGetCurrentURLNoParam),
25 /* harmony export */ lpOnElementReady: () => (/* binding */ lpOnElementReady),
26 /* harmony export */ lpSetLoadingEl: () => (/* binding */ lpSetLoadingEl),
27 /* harmony export */ lpShowHideEl: () => (/* binding */ lpShowHideEl),
28 /* harmony export */ mergeDataWithDatForm: () => (/* binding */ mergeDataWithDatForm),
29 /* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse),
30 /* harmony export */ toggleEnable: () => (/* binding */ toggleEnable)
31 /* harmony export */ });
32 /**
33 * Utils functions
34 *
35 * @param url
36 * @param data
37 * @param functions
38 * @since 4.2.5.1
39 * @version 1.0.7
40 */
41 const lpClassName = {
42 hidden: 'lp-hidden',
43 loading: 'loading',
44 elCollapse: 'lp-collapse',
45 elSectionToggle: '.lp-section-toggle',
46 elTriggerToggle: '.lp-trigger-toggle',
47 elBtnFullScreen: '.lp-btn-full-screen-view',
48 elFullScreen: 'lp-full-screen-view',
49 elBtnFullScreenClose: 'lp-full-screen-view__close'
50 };
51 const lpFetchAPI = (url, data = {}, functions = {}) => {
52 if ('function' === typeof functions.before) {
53 functions.before();
54 }
55 fetch(url, {
56 method: 'GET',
57 ...data
58 }).then(response => response.json()).then(response => {
59 if ('function' === typeof functions.success) {
60 functions.success(response);
61 }
62 }).catch(err => {
63 if ('function' === typeof functions.error) {
64 functions.error(err);
65 }
66 }).finally(() => {
67 if ('function' === typeof functions.completed) {
68 functions.completed();
69 }
70 });
71 };
72
73 /**
74 * Get current URL without params.
75 *
76 * @since 4.2.5.1
77 */
78 const lpGetCurrentURLNoParam = () => {
79 let currentUrl = window.location.href;
80 const hasParams = currentUrl.includes('?');
81 if (hasParams) {
82 currentUrl = currentUrl.split('?')[0];
83 }
84 return currentUrl;
85 };
86 const lpAddQueryArgs = (endpoint, args) => {
87 const url = new URL(endpoint);
88 Object.keys(args).forEach(arg => {
89 url.searchParams.set(arg, args[arg]);
90 });
91 return url;
92 };
93
94 /**
95 * Listen element viewed.
96 *
97 * @param el
98 * @param callback
99 * @since 4.2.5.8
100 */
101 const listenElementViewed = (el, callback) => {
102 const observerSeeItem = new IntersectionObserver(function (entries) {
103 for (const entry of entries) {
104 if (entry.isIntersecting) {
105 callback(entry);
106 }
107 }
108 });
109 observerSeeItem.observe(el);
110 };
111
112 /**
113 * Listen element created.
114 *
115 * @param callback
116 * @since 4.2.5.8
117 */
118 const listenElementCreated = callback => {
119 const observerCreateItem = new MutationObserver(function (mutations) {
120 mutations.forEach(function (mutation) {
121 if (mutation.addedNodes) {
122 mutation.addedNodes.forEach(function (node) {
123 if (node.nodeType === 1) {
124 callback(node);
125 }
126 });
127 }
128 });
129 });
130 observerCreateItem.observe(document, {
131 childList: true,
132 subtree: true
133 });
134 // End.
135 };
136
137 /**
138 * Listen element created.
139 *
140 * @param selector
141 * @param callback
142 * @since 4.2.7.1
143 */
144 const lpOnElementReady = (selector, callback) => {
145 const element = document.querySelector(selector);
146 if (element) {
147 callback(element);
148 return;
149 }
150 const observer = new MutationObserver((mutations, obs) => {
151 const element = document.querySelector(selector);
152 if (element) {
153 obs.disconnect();
154 callback(element);
155 }
156 });
157 observer.observe(document.documentElement, {
158 childList: true,
159 subtree: true
160 });
161 };
162
163 // Parse JSON from string with content include LP_AJAX_START.
164 const lpAjaxParseJsonOld = data => {
165 if (typeof data !== 'string') {
166 return data;
167 }
168 const m = String.raw({
169 raw: data
170 }).match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/s);
171 try {
172 if (m) {
173 data = JSON.parse(m[1].replace(/(?:\r\n|\r|\n)/g, ''));
174 } else {
175 data = JSON.parse(data);
176 }
177 } catch (e) {
178 data = {};
179 }
180 return data;
181 };
182
183 // status 0: hide, 1: show
184 const lpShowHideEl = (el, status = 0) => {
185 if (!el) {
186 return;
187 }
188 if (!status) {
189 el.classList.add(lpClassName.hidden);
190 } else {
191 el.classList.remove(lpClassName.hidden);
192 }
193 };
194
195 // status 0: hide, 1: show
196 const lpSetLoadingEl = (el, status) => {
197 if (!el) {
198 return;
199 }
200 if (!status) {
201 el.classList.remove(lpClassName.loading);
202 } else {
203 el.classList.add(lpClassName.loading);
204 }
205 };
206
207 // Toggle collapse section
208 const toggleCollapse = (e, target, elTriggerClassName = '', elsExclude = [], callback) => {
209 if (!elTriggerClassName) {
210 elTriggerClassName = lpClassName.elTriggerToggle;
211 }
212
213 // Exclude elements, which should not trigger the collapse toggle
214 if (elsExclude && elsExclude.length > 0) {
215 for (const elExclude of elsExclude) {
216 if (target.closest(elExclude)) {
217 return;
218 }
219 }
220 }
221 const elTrigger = target.closest(elTriggerClassName);
222 if (!elTrigger) {
223 return;
224 }
225
226 //console.log( 'elTrigger', elTrigger );
227
228 const elSectionToggle = elTrigger.closest(`${lpClassName.elSectionToggle}`);
229 if (!elSectionToggle) {
230 return;
231 }
232 elSectionToggle.classList.toggle(`${lpClassName.elCollapse}`);
233 if ('function' === typeof callback) {
234 callback(elSectionToggle);
235 }
236 };
237
238 // Get data of form
239 const getDataOfForm = form => {
240 const dataSend = {};
241 const formData = new FormData(form);
242 for (const pair of formData.entries()) {
243 const key = pair[0];
244 const value = formData.getAll(key);
245 if (!dataSend.hasOwnProperty(key)) {
246 // Convert value array to string.
247 dataSend[key] = value.join(',');
248 }
249 }
250 return dataSend;
251 };
252
253 // Get field keys of form
254 const getFieldKeysOfForm = form => {
255 const keys = [];
256 const elements = form.elements;
257 for (let i = 0; i < elements.length; i++) {
258 const name = elements[i].name;
259 if (name && !keys.includes(name)) {
260 keys.push(name);
261 }
262 }
263 return keys;
264 };
265
266 // Merge data handle with data form.
267 const mergeDataWithDatForm = (elForm, dataHandle) => {
268 const dataForm = getDataOfForm(elForm);
269 const keys = getFieldKeysOfForm(elForm);
270 keys.forEach(key => {
271 if (!dataForm.hasOwnProperty(key)) {
272 delete dataHandle[key];
273 } else if (dataForm[key][0] === '') {
274 delete dataForm[key];
275 delete dataHandle[key];
276 }
277 });
278 dataHandle = {
279 ...dataHandle,
280 ...dataForm
281 };
282 return dataHandle;
283 };
284
285 /**
286 * Event trigger
287 * For each list of event handlers, listen event on document.
288 *
289 * eventName: 'click', 'change', ...
290 * eventHandlers = [ { selector: '.lp-button', callBack: function(){}, class: object } ]
291 *
292 * @param eventName
293 * @param eventHandlers
294 */
295 const eventHandlers = (eventName, eventHandlers) => {
296 document.addEventListener(eventName, e => {
297 const target = e.target;
298 let args = {
299 e,
300 target
301 };
302 eventHandlers.forEach(eventHandler => {
303 args = {
304 ...args,
305 ...eventHandler
306 };
307
308 //console.log( args );
309
310 // Check condition before call back
311 if (eventHandler.conditionBeforeCallBack) {
312 if (eventHandler.conditionBeforeCallBack(args) !== true) {
313 return;
314 }
315 }
316
317 // Special check for keydown event with checkIsEventEnter = true
318 if (eventName === 'keydown' && eventHandler.checkIsEventEnter) {
319 if (e.key !== 'Enter') {
320 return;
321 }
322 }
323 if (target.closest(eventHandler.selector)) {
324 if (eventHandler.class) {
325 // Call method of class, function callBack will understand exactly {this} is class object.
326 eventHandler.class[eventHandler.callBack](args);
327 } else {
328 // For send args is objected, {this} is eventHandler object, not class object.
329 eventHandler.callBack(args);
330 }
331 }
332 });
333 });
334 };
335
336 /**
337 * Debounce - delays function execution until after `wait` ms of inactivity.
338 *
339 * Each call resets the timer. Only the last call in a burst executes.
340 *
341 * USE CASES:
342 * - Search inputs, form validation, window resize
343 * - Multiple elements need independent timers
344 * - When you need to call with different arguments
345 *
346 * EXAMPLES:
347 * const debouncedSearch = debounce( (query) => fetchResults(query), 300 );
348 * searchInput.addEventListener('input', (e) => debouncedSearch(e.target.value));
349 *
350 * const debouncedResize = debounce( recalculateLayout, 250 );
351 * window.addEventListener('resize', debouncedResize);
352 *
353 * ⚠️ Create ONCE outside event handlers, not inside.
354 *
355 * @param {Function} func - Function to debounce (can be anonymous)
356 * @param {number} wait - Milliseconds to wait (default: 500)
357 * @return {Function} Debounced wrapper function
358 * @since 4.3.7
359 * @version 1.0.0
360 */
361 const debounce = (func, wait = 500) => {
362 let timer;
363 return args => {
364 clearTimeout(timer);
365 timer = setTimeout(() => func(args), wait);
366 };
367 };
368
369 /**
370 * Initialize lp-toggle-enable components.
371 *
372 * Finds all `.lp-toggle-enable` elements and wires up toggle behavior.
373 * Reads initial state from `data-enabled` attribute ("true"/"false").
374 * Calls `data-on-toggle` callback (if provided via options) on state change.
375 *
376 * HTML structure:
377 * <label class="lp-toggle-enable" data-enabled="true">
378 * <input type="checkbox" class="lp-toggle-enable__input" />
379 * <span class="lp-toggle-enable__track"></span>
380 * </label>
381 *
382 * @param {string} selector CSS selector for toggle elements (default: '.lp-toggle-enable')
383 * @param {Function} onToggle Optional callback( el, isEnabled ) called on state change
384 * @since 4.4.5
385 * @version 1.0.0
386 */
387 window.lpToggleEnableInit = 0;
388 const toggleEnable = (onToggle = null) => {
389 if (window.lpToggleEnableInit) {
390 return;
391 }
392 window.lpToggleEnableInit = 1;
393 const selector = '.lp-toggle-enable';
394 const updateUI = (toggle, isEnabled) => {
395 toggle.classList.toggle('is-enabled', isEnabled);
396 const input = toggle.querySelector('.lp-toggle-enable__input');
397 if (input) {
398 input.checked = isEnabled;
399 input.value = isEnabled ? '1' : '0';
400 }
401 };
402
403 // Delegate click handling via eventHandlers.
404 eventHandlers('click', [{
405 selector,
406 callBack: args => {
407 const {
408 e,
409 target
410 } = args;
411 const toggle = target.closest(selector);
412 if (!toggle || toggle.classList.contains('is-disabled')) {
413 return;
414 }
415 e.preventDefault();
416 const isEnabled = !toggle.classList.contains('is-enabled');
417 updateUI(toggle, isEnabled);
418 if ('function' === typeof onToggle) {
419 onToggle(toggle, isEnabled);
420 }
421 }
422 }]);
423 };
424
425 /**
426 * Initialize custom fullscreen view buttons.
427 *
428 * Delegates clicks on `.lp-btn-full-screen-view` buttons to
429 * `lpToggleFullscreenView`. Reads the `data-target` attribute to find the
430 * target element. Falls back to the button's parent element when
431 * `data-target` is not provided.
432 *
433 * @since 4.4.5
434 * @version 1.0.0
435 */
436 window.lpFullScreenViewInit = 0;
437 const fullScreenView = () => {
438 if (window.lpFullScreenViewInit) {
439 return;
440 }
441 window.lpFullScreenViewInit = 1;
442 let lastScrollY = 0;
443 const lpToggleFullscreenView = (elTarget, elBtnFullScreen = null) => {
444 const isFullscreen = elTarget.classList.contains(lpClassName.elFullScreen);
445 if (isFullscreen) {
446 elTarget.classList.remove(lpClassName.elFullScreen);
447 document.documentElement.classList.remove('lp-full-screen-active');
448 window.scrollTo(0, lastScrollY);
449 } else {
450 lastScrollY = window.scrollY;
451 elTarget.classList.add(lpClassName.elFullScreen);
452 document.documentElement.classList.add('lp-full-screen-active');
453 }
454 if (!isFullscreen) {
455 if (!elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`)) {
456 const closeButton = document.createElement('button');
457 closeButton.type = 'button';
458 closeButton.className = lpClassName.elBtnFullScreenClose;
459 closeButton.setAttribute('aria-label', 'Close');
460 closeButton.innerHTML = lpData.i18n.closeButtonFullScreen || 'Close &times;';
461 closeButton.addEventListener('click', e => {
462 e.preventDefault();
463 lpToggleFullscreenView(elTarget);
464 });
465 elTarget.appendChild(closeButton);
466 }
467 } else {
468 const closeButton = elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`);
469 if (closeButton) {
470 closeButton.remove();
471 }
472 }
473 };
474 eventHandlers('click', [{
475 selector: lpClassName.elBtnFullScreen,
476 callBack: args => {
477 const {
478 e,
479 target
480 } = args;
481 const elBtnFullScreen = target.closest(lpClassName.elBtnFullScreen);
482 if (!elBtnFullScreen) {
483 console.log('No full screen button found');
484 return;
485 }
486 e.preventDefault();
487 let elTarget = null;
488 const targetSelector = elBtnFullScreen.dataset.targetFullscreen;
489 console.log(targetSelector);
490 if (targetSelector) {
491 elTarget = document.querySelector(targetSelector);
492 }
493 if (!elTarget) {
494 console.log('No target element found');
495 return;
496 }
497 lpToggleFullscreenView(elTarget, elBtnFullScreen);
498 }
499 }]);
500 };
501
502 /***/ }
503
504 /******/ });
505 /************************************************************************/
506 /******/ // The module cache
507 /******/ const __webpack_module_cache__ = {};
508 /******/
509 /******/ // The require function
510 /******/ function __webpack_require__(moduleId) {
511 /******/ // Check if module is in cache
512 /******/ const cachedModule = __webpack_module_cache__[moduleId];
513 /******/ if (cachedModule !== undefined) {
514 /******/ return cachedModule.exports;
515 /******/ }
516 /******/ // Create a new module (and put it into the cache)
517 /******/ const module = __webpack_module_cache__[moduleId] = {
518 /******/ // no module.id needed
519 /******/ // no module.loaded needed
520 /******/ exports: {}
521 /******/ };
522 /******/
523 /******/ // Execute the module function
524 /******/ if (!(moduleId in __webpack_modules__)) {
525 /******/ delete __webpack_module_cache__[moduleId];
526 /******/ const e = new Error("Cannot find module '" + moduleId + "'");
527 /******/ e.code = 'MODULE_NOT_FOUND';
528 /******/ throw e;
529 /******/ }
530 /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
531 /******/
532 /******/ // Return the exports of the module
533 /******/ return module.exports;
534 /******/ }
535 /******/
536 /************************************************************************/
537 /******/ /* webpack/runtime/define property getters */
538 /******/ (() => {
539 /******/ // define getter/value functions for harmony exports
540 /******/ __webpack_require__.d = (exports, definition) => {
541 /******/ if(Array.isArray(definition)) {
542 /******/ var i = 0;
543 /******/ while(i < definition.length) {
544 /******/ var key = definition[i++];
545 /******/ var binding = definition[i++];
546 /******/ if(!__webpack_require__.o(exports, key)) {
547 /******/ if(binding === 0) {
548 /******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
549 /******/ } else {
550 /******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
551 /******/ }
552 /******/ } else if(binding === 0) { i++; }
553 /******/ }
554 /******/ } else {
555 /******/ for(var key in definition) {
556 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
557 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
558 /******/ }
559 /******/ }
560 /******/ }
561 /******/ };
562 /******/ })();
563 /******/
564 /******/ /* webpack/runtime/hasOwnProperty shorthand */
565 /******/ (() => {
566 /******/ __webpack_require__.o = (obj, prop) => (Object.hasOwn(obj, prop))
567 /******/ })();
568 /******/
569 /******/ /* webpack/runtime/make namespace object */
570 /******/ (() => {
571 /******/ // define __esModule on exports
572 /******/ __webpack_require__.r = (exports) => {
573 /******/ if(Symbol.toStringTag) {
574 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
575 /******/ }
576 /******/ Object.defineProperty(exports, '__esModule', { value: true });
577 /******/ };
578 /******/ })();
579 /******/
580 /************************************************************************/
581 let __webpack_exports__ = {};
582 // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
583 (() => {
584 /*!*******************************************!*\
585 !*** ./assets/src/js/admin/learnpress.js ***!
586 \*******************************************/
587 __webpack_require__.r(__webpack_exports__);
588 /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils */ "./assets/src/js/utils.js");
589
590 const $ = jQuery;
591 const $doc = $(document);
592 const makePaymentsSortable = function makePaymentsSortable() {
593 // Make payments sortable
594 $('.learn-press-payments.sortable tbody').sortable({
595 handle: '.dashicons-menu',
596 helper(e, ui) {
597 ui.children().each(function () {
598 $(this).width($(this).width());
599 });
600 return ui;
601 },
602 axis: 'y',
603 start(event, ui) {},
604 stop(event, ui) {},
605 update(event, ui) {
606 const order = $(this).children().map(function () {
607 return $(this).find('input[name="payment-order"]').val();
608 }).get();
609 $.post({
610 url: '',
611 data: {
612 'lp-ajax': 'update-payment-order',
613 order,
614 nonce: $('input[name=lp-settings-nonce]').val()
615 },
616 success(response) {}
617 });
618 }
619 });
620 };
621
622 /** Start Nhamdv code */
623
624 const lpMetaboxCustomFields = () => {
625 $('.lp-metabox__custom-fields').on('click', '.lp-metabox-custom-field-button', function () {
626 const row = $(this).data('row').replace(/lp_metabox_custom_fields_key/gi, Math.floor(Math.random() * 1000) + 1);
627 $(this).closest('table').find('tbody').append(row);
628 updateSort($(this).closest('.lp-metabox__custom-fields'));
629 return false;
630 });
631 $('.lp-metabox__custom-fields').on('click', 'a.delete', function () {
632 $(this).closest('tr').remove();
633 updateSort($(this).closest('.lp-metabox__custom-fields'));
634 return false;
635 });
636 $('.lp-metabox__custom-fields tbody').sortable({
637 items: 'tr',
638 cursor: 'move',
639 axis: 'y',
640 handle: 'td.sort',
641 scrollSensitivity: 40,
642 forcePlaceholderSize: true,
643 helper: 'clone',
644 opacity: 0.65,
645 update(event, ui) {
646 updateSort($(this).closest('.lp-metabox__custom-fields'));
647 }
648 });
649 const updateSort = element => {
650 const items = element.find('tbody tr');
651 items.each(function (i, item) {
652 $(this).find('.sort .count').val(i);
653 });
654 };
655 };
656 const lpMetaboxRepeaterField = () => {
657 const updateSort = element => {
658 const items = element.find('.lp_repeater_meta_box__field');
659 items.each(function (i, item) {
660 $(this).find('.lp_repeater_meta_box__field__count').val(i);
661 $(this).find('.lp_repeater_meta_box__title__title > span').text(i + 1);
662 });
663 };
664 $('.lp_repeater_meta_box__add').on('click', function () {
665 const row = $(this).data('add').replace(/lp_metabox_repeater_key/gi, Math.floor(Math.random() * 1000) + 1);
666 $(this).closest('.lp_repeater_meta_box__wrapper').find('.lp_repeater_meta_box__fields').append(row);
667 updateSort($(this).closest('.lp_repeater_meta_box__wrapper'));
668 $(this).closest('.lp_repeater_meta_box__wrapper').find('.lp_repeater_meta_box__fields').last().find('input').trigger('focus');
669 return false;
670 });
671 $('.lp_repeater_meta_box__wrapper').on('click', 'a.lp_repeater_meta_box__title__delete', function () {
672 $(this).closest('.lp_repeater_meta_box__field').remove();
673 updateSort($(this).closest('.lp_repeater_meta_box__wrapper'));
674 return false;
675 });
676 $('.lp_repeater_meta_box__fields').on('click', '.lp_repeater_meta_box__title__toggle, .lp_repeater_meta_box__title__title', function () {
677 const field = $(this).closest('.lp_repeater_meta_box__field');
678 if (field.hasClass('lp_repeater_meta_box__field_active')) {
679 field.removeClass('lp_repeater_meta_box__field_active');
680 } else {
681 field.addClass('lp_repeater_meta_box__field_active');
682 }
683 return false;
684 });
685 $('.lp_repeater_meta_box__fields').sortable({
686 items: '.lp_repeater_meta_box__field',
687 cursor: 'grab',
688 axis: 'y',
689 handle: '.lp_repeater_meta_box__title__sort',
690 scrollSensitivity: 40,
691 forcePlaceholderSize: true,
692 helper: 'clone',
693 opacity: 0.65,
694 update(event, ui) {
695 updateSort($(this).closest('.lp_repeater_meta_box__wrapper'));
696 }
697 });
698 };
699 const lpMetaboxExtraInfo = () => {
700 $('.lp_course_extra_meta_box__add').on('click', function () {
701 $(this).closest('.lp_course_extra_meta_box__content').find('.lp_course_extra_meta_box__fields').append($(this).data('add'));
702 $(this).closest('.lp_course_extra_meta_box__content').find('.lp_course_extra_meta_box__field').last().find('input').trigger('focus');
703 return false;
704 });
705
706 /*document.querySelectorAll( '.lp_course_extra_meta_box__fields' ).forEach( ( ele ) => {
707 ele.addEventListener( 'keydown', ( e ) => {
708 const inputs = ele.querySelectorAll( '.lp_course_extra_meta_box__input' );
709 if ( e.keyCode === 13 ) {
710 e.preventDefault();
711 inputs.forEach( ( input ) => {
712 input.blur();
713 } );
714 return false;
715 }
716 } );
717 } );*/
718
719 $('.lp_course_extra_meta_box__fields').on('click', 'a.delete', function () {
720 $(this).closest('.lp_course_extra_meta_box__field').remove();
721 return false;
722 });
723 $('.lp_course_extra_meta_box__fields').sortable({
724 items: '.lp_course_extra_meta_box__field',
725 cursor: 'grab',
726 axis: 'y',
727 handle: '.sort',
728 scrollSensitivity: 40,
729 forcePlaceholderSize: true,
730 helper: 'clone',
731 opacity: 0.65
732 });
733
734 // FAQs metabox.
735 $('.lp_course_faq_meta_box__add').on('click', function () {
736 $(this).closest('.lp_course_faq_meta_box__content').find('.lp_course_faq_meta_box__fields').append($(this).data('add'));
737 return false;
738 });
739
740 /*document.querySelectorAll( '.lp_course_faq_meta_box__fields' ).forEach( ( ele ) => {
741 ele.addEventListener( 'keydown', ( e ) => {
742 const inputs = ele.querySelectorAll( '.lp_course_faq_meta_box__field input' );
743 const textareas = ele.querySelectorAll( '.lp_course_faq_meta_box__field textarea' );
744 if ( e.keyCode === 13 ) {
745 e.preventDefault();
746 [ ...inputs, ...textareas ].forEach( ( input ) => {
747 input.blur();
748 } );
749 return false;
750 }
751 } );
752 } );*/
753
754 $('.lp_course_faq_meta_box__fields').on('click', 'a.delete', function () {
755 $(this).closest('.lp_course_faq_meta_box__field').remove();
756 return false;
757 });
758 $('.lp_course_faq_meta_box__fields').sortable({
759 items: '.lp_course_faq_meta_box__field',
760 cursor: 'grab',
761 axis: 'y',
762 handle: '.sort',
763 scrollSensitivity: 40,
764 forcePlaceholderSize: true,
765 helper: 'clone',
766 opacity: 0.65
767 });
768 };
769
770 // Nhamdv.
771 const lpGetFinalQuiz = () => {
772 const btns = document.querySelectorAll('.lp-metabox-get-final-quiz');
773 [...btns].map(btn => {
774 btn.addEventListener('click', e => {
775 e.preventDefault();
776 const text = btn.textContent,
777 loading = btn.dataset.loading,
778 message = document.querySelector('.lp-metabox-evaluate-final_quiz');
779 if (message) {
780 message.remove();
781 }
782 btn.textContent = loading;
783 getResponse(btn).then(data => {
784 const {
785 message,
786 data: responseData
787 } = data;
788 btn.textContent = text;
789 const newNode = document.createElement('div');
790 newNode.className = 'lp-metabox-evaluate-final_quiz';
791 newNode.innerHTML = responseData || message;
792 btn.parentNode.insertBefore(newNode, btn.nextSibling);
793 });
794 });
795 });
796 const getResponse = async btn => {
797 const response = await wp.apiFetch({
798 path: 'lp/v1/admin/course/get_final_quiz',
799 method: 'POST',
800 data: {
801 courseId: btn.dataset.postid || ''
802 }
803 });
804 return response;
805 };
806 };
807 const lpMetaboxColorPicker = () => {
808 $('.lp-metabox__colorpick').iris({
809 change(event, ui) {
810 $(this).parent().find('.colorpickpreview').css({
811 backgroundColor: ui.color.toString()
812 });
813 },
814 hide: true,
815 border: true
816 }).on('click focus', function (event) {
817 event.stopPropagation();
818 $('.iris-picker').hide();
819 $(this).closest('td').find('.iris-picker').show();
820 $(this).data('original-value', $(this).val());
821 }).on('change', function () {
822 if ($(this).is('.iris-error')) {
823 const originalValue = $(this).data('original-value');
824 if (originalValue.match(/^\#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/)) {
825 $(this).val($(this).data('original-value')).trigger('change');
826 } else {
827 $(this).val('').trigger('change');
828 }
829 }
830 });
831 $('body').on('click', function () {
832 $('.iris-picker').hide();
833 });
834 };
835 const lpMetaboxImage = () => {
836 $('.lp-metabox-field__image').each((i, ele) => {
837 let lpImageFrame;
838 const addImage = $(ele).find('.lp-metabox-field__image--add');
839 const delImage = $(ele).find('.lp-metabox-field__image--delete');
840 const image = $(ele).find('.lp-metabox-field__image--image');
841 const inputVal = $(ele).find('.lp-metabox-field__image--id');
842 if (!inputVal.val()) {
843 addImage.show();
844 delImage.hide();
845 } else {
846 addImage.hide();
847 delImage.show();
848 }
849 addImage.on('click', event => {
850 event.preventDefault();
851 if (lpImageFrame) {
852 lpImageFrame.open();
853 return;
854 }
855 lpImageFrame = wp.media({
856 title: addImage.data('choose'),
857 button: {
858 text: addImage.data('update')
859 },
860 multiple: false
861 });
862 lpImageFrame.on('select', function () {
863 const attachment = lpImageFrame.state().get('selection').first().toJSON();
864 const attachmentImage = attachment.sizes && attachment.sizes.thumbnail ? attachment.sizes.thumbnail.url : attachment.url;
865 image.append('<div class="lp-metabox-field__image--inner"><img src="' + attachmentImage + '" alt="" style="max-width:100%;"/></div>');
866 inputVal.val(attachment.id);
867 addImage.hide();
868 delImage.show();
869 });
870 lpImageFrame.open();
871 });
872 delImage.on('click', event => {
873 event.preventDefault();
874 image.html('');
875 addImage.show();
876 delImage.hide();
877 inputVal.val('');
878 });
879 });
880 };
881 const lpMetaboxImageAdvanced = () => {
882 $('.lp-metabox-field__image-advanced').each((i, element) => {
883 let lpImageFrame;
884 const imageGalleryIds = $(element).find('#lp-gallery-images-ids');
885 const listImages = $(element).find('.lp-metabox-field__image-advanced-images');
886 const btnUpload = $(element).find('.lp-metabox-field__image-advanced-upload > a');
887 $(btnUpload).on('click', event => {
888 event.preventDefault();
889 if (lpImageFrame) {
890 lpImageFrame.open();
891 return;
892 }
893 lpImageFrame = wp.media({
894 title: btnUpload.data('choose'),
895 button: {
896 text: btnUpload.data('update')
897 },
898 states: [new wp.media.controller.Library({
899 title: btnUpload.data('choose'),
900 filterable: 'all',
901 multiple: true
902 })]
903 });
904 lpImageFrame.on('select', function () {
905 const selection = lpImageFrame.state().get('selection');
906 let attachmentIds = imageGalleryIds.val();
907 selection.forEach(function (attachment) {
908 attachment = attachment.toJSON();
909 if (attachment.id) {
910 attachmentIds = attachmentIds ? attachmentIds + ',' + attachment.id : attachment.id;
911 const attachmentImage = attachment.sizes && attachment.sizes.thumbnail ? attachment.sizes.thumbnail.url : attachment.url;
912 listImages.append('<li class="image" data-attachment_id="' + attachment.id + '"><img src="' + attachmentImage + '" /><ul class="actions"><li><a href="#" class="delete" title="' + btnUpload.data('delete') + '">' + btnUpload.data('text') + '</a></li></ul></li>');
913 }
914 });
915 imageGalleryIds.val(attachmentIds);
916 });
917 lpImageFrame.open();
918 });
919 listImages.sortable({
920 items: 'li.image',
921 cursor: 'move',
922 scrollSensitivity: 40,
923 forcePlaceholderSize: true,
924 forceHelperSize: false,
925 helper: 'clone',
926 opacity: 0.65,
927 placeholder: 'lp-metabox-sortable-placeholder',
928 start(event, ui) {
929 ui.item.css('background-color', '#f6f6f6');
930 },
931 stop(event, ui) {
932 ui.item.removeAttr('style');
933 },
934 update() {
935 let attachmentIds = '';
936 listImages.find('li.image').css('cursor', 'default').each(function () {
937 const attachmentId = $(this).attr('data-attachment_id');
938 attachmentIds = attachmentIds + attachmentId + ',';
939 });
940 imageGalleryIds.val(attachmentIds);
941 }
942 });
943 $(listImages).find('li.image').each((i, ele) => {
944 const del = $(ele).find('a.delete');
945 del.on('click', () => {
946 $(ele).remove();
947 let attachmentIds = '';
948 $(listImages).find('li.image').css('cursor', 'default').each(function () {
949 const attachmentId = $(this).attr('data-attachment_id');
950 attachmentIds = attachmentIds + attachmentId + ',';
951 });
952 imageGalleryIds.val(attachmentIds);
953 return false;
954 });
955 });
956 });
957 };
958 const lpMetaboxCourseTabs = () => {
959 $(document.body).on('lp-metabox-course-tab-panels', function () {
960 $('ul.lp-meta-box__course-tab__tabs').show();
961 $('ul.lp-meta-box__course-tab__tabs a').on('click', function (e) {
962 e.preventDefault();
963 const panelWrap = $(this).closest('div.lp-meta-box__course-tab');
964 $('ul.lp-meta-box__course-tab__tabs li', panelWrap).removeClass('active');
965 $(this).parent().addClass('active');
966 $('div.lp-meta-box-course-panels', panelWrap).hide();
967 $($(this).attr('href')).show();
968 });
969 $('div.lp-meta-box__course-tab').each(function () {
970 $(this).find('ul.lp-meta-box__course-tab__tabs li').eq(0).find('a').trigger('click');
971 });
972 }).trigger('lp-metabox-course-tab-panels');
973 };
974
975 // use to show and hide field condition logic metabox.
976 /*const lpMetaboxCondition = () => {
977 const fields = document.querySelectorAll( '.lp-meta-box .form-field' );
978
979 fields.forEach( ( field ) => {
980 if ( field.hasAttribute( 'data-show' ) && field.dataset.show ) {
981 lpMetaboxConditionType( field, field.dataset.show, 'show' );
982 } else if ( field.hasAttribute( 'data-hide' ) && field.dataset.hide ) {
983 lpMetaboxConditionType( field, field.dataset.hide, 'hide' );
984 }
985 } );
986 };*/
987
988 /*const lpMetaboxConditionType = ( field, conditions, typeCondition = 'show' ) => {
989 const condition = JSON.parse( conditions ),
990 eles = document.querySelectorAll( `input[id^="${ condition[ 0 ] }"]` ),
991 logic = condition[ 1 ] === '=' ? '=' : '!=',
992 dataLogic = condition[ 2 ];
993
994 const switchCase = ( type, ele, target ) => {
995 switch ( type ) {
996 case 'checkbox':
997 let val = dataLogic;
998
999 if ( dataLogic === 'yes' || dataLogic === '1' || dataLogic === 1 || dataLogic === 'true' ) {
1000 val = true;
1001 } else if ( dataLogic === 'no' || dataLogic === '0' || dataLogic === 0 || dataLogic === 'false' ) {
1002 val = false;
1003 }
1004
1005 if ( logic == '!=' && val !== Boolean( target ? target.checked : ele.checked ) ) {
1006 field.style.display = typeCondition === 'show' ? '' : 'none';
1007 } else if ( logic == '=' && val == Boolean( target ? target.checked : ele.checked ) ) {
1008 field.style.display = typeCondition === 'show' ? '' : 'none';
1009 } else {
1010 field.style.display = typeCondition === 'show' ? 'none' : '';
1011 }
1012 break;
1013 }
1014 };
1015
1016 eles.forEach( ( ele ) => {
1017 const type = ele.getAttribute( 'type' );
1018
1019 switchCase( type, ele );
1020
1021 ele.addEventListener( 'change', ( e ) => {
1022 const target = e.target;
1023
1024 switchCase( type, ele, target );
1025 } );
1026 } );
1027 };*/
1028
1029 /** End Nhamdv code */
1030
1031 const initTooltips = function initTooltips() {
1032 $('.learn-press-tooltip').each(function () {
1033 const $el = $(this),
1034 args = $.extend({
1035 title: 'data-tooltip',
1036 offset: 10,
1037 gravity: 's'
1038 }, $el.data());
1039 $el.tipsy(args);
1040 });
1041 };
1042 const initSelect2 = function initSelect2() {
1043 if ($.fn.select2) {
1044 const elSelect2 = $('.lp-select-2 select');
1045 elSelect2.select2({
1046 placeholder: 'Select a value'
1047 });
1048 elSelect2.on('change.select2', function (e) {
1049 const el = $(e.target);
1050 const val = el.val();
1051 if (!val.length) {
1052 el.val(null);
1053 }
1054 });
1055 $('.lp_autocomplete_metabox_field').each(function () {
1056 const dataAtts = $(this).data('atts');
1057 let action = dataAtts.action;
1058 if (!action) {
1059 switch (dataAtts.data) {
1060 case 'users':
1061 action = dataAtts.rest_url + 'wp/v2/users';
1062 break;
1063 default:
1064 action = dataAtts.rest_url + 'wp/v2/' + dataAtts.data;
1065 break;
1066 }
1067 }
1068 $(this).find('select').select2({
1069 placeholder: dataAtts.placeholder ? dataAtts.placeholder : 'Select',
1070 ajax: {
1071 url: action,
1072 dataType: 'json',
1073 delay: 250,
1074 beforeSend(xhr) {
1075 xhr.setRequestHeader('X-WP-Nonce', dataAtts.nonce);
1076 },
1077 data(params) {
1078 return {
1079 search: params.term
1080 };
1081 },
1082 processResults(data) {
1083 return {
1084 results: data.map(item => {
1085 return {
1086 id: item.id,
1087 text: item.title && item.title.rendered ? item.title.rendered : item.name
1088 };
1089 })
1090 };
1091 },
1092 cache: true
1093 },
1094 minimumInputLength: 2
1095 });
1096 });
1097 }
1098 };
1099 const initSingleCoursePermalink = function initSingleCoursePermalink() {
1100 $doc.on('change', '.learn-press-single-course-permalink input[type="radio"]', function () {
1101 const $check = $(this),
1102 $row = $check.closest('.learn-press-single-course-permalink');
1103 if ($row.hasClass('custom-base')) {
1104 $row.find('input[type="text"]').prop('readonly', false);
1105 } else {
1106 $row.siblings('.custom-base').find('input[type="text"]').prop('readonly', true);
1107 }
1108 }).on('change', 'input.learn-press-course-base', function () {
1109 $('#course_permalink_structure').val($(this).val());
1110 }).on('focus', '#course_permalink_structure', function () {
1111 $('#learn_press_custom_permalink').click();
1112 }).on('change', '#learn_press_courses_page_id', function () {
1113 $('tr.learn-press-courses-page-id').toggleClass('hide-if-js', !parseInt(this.value));
1114 });
1115 };
1116 const togglePaymentStatus = function togglePaymentStatus(e) {
1117 e.preventDefault();
1118 const $row = $(this).closest('tr'),
1119 $button = $(this),
1120 status = $row.find('.status').hasClass('enabled') ? 'no' : 'yes';
1121 $.ajax({
1122 url: '',
1123 data: {
1124 'lp-ajax': 'update-payment-status',
1125 status,
1126 id: $row.data('payment'),
1127 nonce: $('input[name=lp-settings-nonce]').val()
1128 },
1129 success(response) {
1130 response = (0,_utils__WEBPACK_IMPORTED_MODULE_0__.lpAjaxParseJsonOld)(response);
1131 for (const i in response) {
1132 $('#payment-' + i + ' .status').toggleClass('enabled', response[i]);
1133 }
1134 }
1135 });
1136 };
1137 const updateEmailStatus = function updateEmailStatus() {
1138 (function () {
1139 $.post({
1140 url: window.location.href,
1141 data: {
1142 'lp-ajax': 'update_email_status',
1143 status: $(this).parent().hasClass('enabled') ? 'no' : 'yes',
1144 id: $(this).data('id'),
1145 nonce: $('input[name=lp-settings-nonce]').val()
1146 },
1147 dataType: 'text',
1148 success: $.proxy(function (res) {
1149 res = (0,_utils__WEBPACK_IMPORTED_MODULE_0__.lpAjaxParseJsonOld)(res);
1150 for (const i in res) {
1151 $('#email-' + i + ' .status').toggleClass('enabled', res[i]);
1152 }
1153 }, this)
1154 });
1155 }).apply(this);
1156 };
1157 const lpMetaboxsalePriceDate = () => {
1158 // Don't run in LearnPress Frontend Editor Add-on.
1159 if (!$('#course-settings').length) {
1160 return;
1161 }
1162 $('.lp_sale_dates_fields').each(function () {
1163 const wrap = $(this).closest('#price_course_data');
1164 let saleScheduleSet = false;
1165 $(this).find('input').each(function () {
1166 if ('' !== $(this).val()) {
1167 saleScheduleSet = true;
1168 }
1169 });
1170 if (saleScheduleSet) {
1171 wrap.find('.lp_sale_price_schedule').hide();
1172 wrap.find('.lp_sale_dates_fields').show();
1173 } else {
1174 wrap.find('.lp_sale_price_schedule').show();
1175 wrap.find('.lp_sale_dates_fields').hide();
1176 }
1177 });
1178 $('.lp-meta-box-course-panels').on('click', '.lp_sale_price_schedule', function () {
1179 const wrap = $(this).closest('#price_course_data');
1180 $(this).hide();
1181 wrap.find('.lp_cancel_sale_schedule').show();
1182 wrap.find('.lp_sale_dates_fields').show();
1183 return false;
1184 });
1185 $('.lp-meta-box-course-panels').on('click', '.lp_cancel_sale_schedule', function () {
1186 const wrap = $(this).closest('div.lp-meta-box-course-panels');
1187 $(this).hide();
1188 wrap.find('.lp_sale_price_schedule').show();
1189 wrap.find('.lp_sale_dates_fields').hide();
1190 wrap.find('.lp_sale_dates_fields').find('input').val('');
1191 return false;
1192 });
1193 $(document).on('input', '#price_course_data', function (e) {
1194 const $this = $(this),
1195 regularPrice = $('.lp_meta_box_regular_price'),
1196 salePrice = $('.lp_meta_box_sale_price'),
1197 $target = $(e.target).attr('id');
1198 $this.find('.learn-press-tip-floating').remove();
1199 if (parseInt(salePrice.val()) > parseInt(regularPrice.val())) {
1200 if ($target === '_lp_price') {
1201 regularPrice.parent('.form-field').append('<div class="learn-press-tip-floating">' + lpAdminCourseEditorSettings.i18n.notice_price + '</div>');
1202 } else if ($target === '_lp_sale_price') {
1203 salePrice.parent('.form-field').append('<div class="learn-press-tip-floating">' + lpAdminCourseEditorSettings.i18n.notice_sale_price + '</div>');
1204 }
1205 }
1206 });
1207
1208 /*const datePickerSelect = function( datepicker ) {
1209 const option = $( datepicker ).is( '#_lp_sale_start' ) ? 'minDate' : 'maxDate',
1210 otherDateField = 'minDate' === option ? $( '#_lp_sale_end' ) : $( '#_lp_sale_start' ),
1211 date = $( datepicker ).datetimepicker( 'getDate' );
1212 $( otherDateField ).datetimepicker( 'option', option, date );
1213 $( datepicker ).trigger( 'change' );
1214 };
1215 $( '.lp_sale_dates_fields' ).each( function() {
1216 $( this ).find( 'input' ).datetimepicker( {
1217 timeFormat: 'HH:mm',
1218 separator: ' ',
1219 dateFormat: 'yy-mm-dd',
1220 showButtonPanel: true,
1221 onSelect() {
1222 datePickerSelect( $( this ) );
1223 },
1224 } );
1225 $( this ).find( 'input' ).each( function() {
1226 datePickerSelect( $( this ) );
1227 } );
1228 } );*/
1229 };
1230 const lpHidePassingGrade = () => {
1231 const listHides = ['evaluate_final_quiz', 'evaluate_final_assignment'];
1232 const inputLists = document.querySelectorAll('input[type=radio][name=_lp_course_result]');
1233 [...inputLists].map((ele, i) => {
1234 if (ele.checked && listHides.includes(ele.value)) {
1235 $('._lp_passing_condition_field').hide();
1236 }
1237 return null;
1238 });
1239 $('input[type=radio][name=_lp_course_result]').on('change', function (e) {
1240 if (listHides.includes(e.target.value)) {
1241 $('._lp_passing_condition_field').hide();
1242 } else {
1243 $('._lp_passing_condition_field').show();
1244 }
1245 });
1246 };
1247 const callbackFilterTemplates = function callbackFilterTemplates() {
1248 const $link = $(this);
1249 if ($link.hasClass('current')) {
1250 return false;
1251 }
1252 const $templatesList = $('#learn-press-template-files'),
1253 $templates = $templatesList.find('tr[data-template]'),
1254 template = $link.data('template'),
1255 filter = $link.data('filter');
1256 $link.addClass('current').siblings('a').removeClass('current');
1257 if (!template) {
1258 if (!filter) {
1259 $templates.removeClass('hide-if-js');
1260 } else {
1261 $templates.map(function () {
1262 $(this).toggleClass('hide-if-js', $(this).data('filter-' + filter) !== 'yes');
1263 });
1264 }
1265 } else {
1266 $templates.map(function () {
1267 $(this).toggleClass('hide-if-js', $(this).data('template') !== template);
1268 });
1269 }
1270 $('#learn-press-no-templates').toggleClass('hide-if-js', !!$templatesList.find('tr.template-row:not(.hide-if-js):first').length);
1271 return false;
1272 };
1273 const toggleEmails = function toggleEmails(e) {
1274 e.preventDefault();
1275 const $button = $(this),
1276 status = $button.data('status');
1277 $.ajax({
1278 url: '',
1279 data: {
1280 'lp-ajax': 'update_email_status',
1281 nonce: $('input[name=lp-settings-nonce]').val(),
1282 status
1283 },
1284 success(response) {
1285 response = (0,_utils__WEBPACK_IMPORTED_MODULE_0__.lpAjaxParseJsonOld)(response);
1286 for (const i in response) {
1287 $('#email-' + i + ' .status').toggleClass('enabled', response[i]);
1288 }
1289 }
1290 });
1291 };
1292 const onReady = function onReady() {
1293 makePaymentsSortable();
1294 initSelect2();
1295 initTooltips();
1296 initSingleCoursePermalink();
1297
1298 // lp Metabox in LP4.
1299 lpMetaboxCourseTabs();
1300 lpMetaboxCustomFields();
1301 lpMetaboxColorPicker();
1302 lpMetaboxImageAdvanced();
1303 lpMetaboxImage();
1304 lpMetaboxsalePriceDate();
1305 lpMetaboxExtraInfo();
1306 lpHidePassingGrade();
1307 lpGetFinalQuiz();
1308 //lpMetaboxCondition();
1309 lpMetaboxRepeaterField();
1310 $(document).on('click', '.learn-press-payments .status .dashicons', togglePaymentStatus).on('click', '.change-email-status', updateEmailStatus).on('click', '.learn-press-filter-template', callbackFilterTemplates).on('click', '#learn-press-enable-emails, #learn-press-disable-emails', toggleEmails);
1311 };
1312 $(document).ready(onReady);
1313
1314 // Events
1315 document.addEventListener('keydown', function (e) {
1316 const target = e.target;
1317 if (e.key === 'Enter' || e.keyCode === 13) {
1318 // When enter on input on Extra information Options, blur it.
1319 if (target.classList.contains('lp_course_extra_meta_box__input')) {
1320 e.preventDefault();
1321 target.blur();
1322 } else if (target.tagName === 'INPUT') {
1323 if (target.closest('.lp_course_faq_meta_box__field')) {
1324 e.preventDefault();
1325 target.blur();
1326 }
1327 }
1328 }
1329 });
1330 })();
1331
1332 /******/ })()
1333 ;
1334 //# sourceMappingURL=learnpress.js.map