PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / trunk
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses vtrunk
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 4.2.1 All 138 releases
learnpress / assets / src / js / utils / index.js

index.js in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses trunk, at assets/src/js/utils/index.js

568 lines 14.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Utility functions may use for both admin and frontend.
3 *
4 * @version 3.2.6
5 */
6
7 import extend from './extend';
8 import fn from './fn';
9 import QuickTip from './quick-tip';
10 import MessageBox from './message-box';
11 import Event_Callback from './event-callback';
12 import Hook from './hook';
13 import Cookies from './cookies';
14 import _localStorage from './local-storage';
15 import * as jplugins from './jquery.plugins';
16 import IframeSubmit from './iframe-submit';
17 import showPass from './show-password';
18
19 const $ = jQuery;
20
21 String.prototype.getQueryVar = function( name ) {
22 name = name.replace( /[\[]/, '\\[' ).replace( /[\]]/, '\\]' );
23 const regex = new RegExp( '[\\?&]' + name + '=([^&#]*)' ),
24 results = regex.exec( this );
25 return results === null ? '' : decodeURIComponent( results[ 1 ].replace( /\+/g, ' ' ) );
26 };
27
28 String.prototype.addQueryVar = function( name, value ) {
29 let url = this,
30 m = url.split( '#' );
31 url = m[ 0 ];
32 if ( name.match( /\[/ ) ) {
33 url += url.match( /\?/ ) ? '&' : '?';
34 url += name + '=' + value;
35 } else if ( ( url.indexOf( '&' + name + '=' ) != -1 ) || ( url.indexOf( '?' + name + '=' ) != -1 ) ) {
36 url = url.replace( new RegExp( name + '=([^&#]*)', 'g' ), name + '=' + value );
37 } else {
38 url += url.match( /\?/ ) ? '&' : '?';
39 url += name + '=' + value;
40 }
41 return url + ( m[ 1 ] ? '#' + m[ 1 ] : '' );
42 };
43
44 String.prototype.removeQueryVar = function( name ) {
45 let url = this;
46 const m = url.split( '#' );
47 url = m[ 0 ];
48 name = name.replace( /[\[]/, '\\[' ).replace( /[\]]/, '\\]' );
49 const regex = new RegExp( '[\\?&]' + name + '([\[][^=]*)?=([^&#]*)', 'g' );
50 url = url.replace( regex, '' );
51 return url + ( m[ 1 ] ? '#' + m[ 1 ] : '' );
52 };
53
54 // if ( $.isEmptyObject( '' ) == false ) {
55 // $.isEmptyObject = function( a ) {
56 // let prop;
57 // for ( prop in a ) {
58 // if ( a.hasOwnProperty( prop ) ) {
59 // return false;
60 // }
61 // }
62 // return true;
63 // };
64 // }
65
66 const _default = {
67 Hook,
68 setUrl( url, ember, title ) {
69 if ( url ) {
70 history.pushState( {}, title, url );
71 LP.Hook.doAction( 'learn_press_set_location_url', url );
72 }
73 },
74 toggleGroupSection( el, target ) {
75 const $el = $( el ),
76 isHide = $el.hasClass( 'hide-if-js' );
77 if ( isHide ) {
78 $el.hide().removeClass( 'hide-if-js' );
79 }
80 $el.removeClass( 'hide-if-js' ).slideToggle( function() {
81 const $this = $( this );
82 if ( $this.is( ':visible' ) ) {
83 $( target ).addClass( 'toggle-on' ).removeClass( 'toggle-off' );
84 } else {
85 $( target ).addClass( 'toggle-off' ).removeClass( 'toggle-on' );
86 }
87 } );
88 },
89 overflow( el, v ) {
90 const $el = $( el ),
91 overflow = $el.css( 'overflow' );
92 if ( v ) {
93 $el.css( 'overflow', v ).data( 'overflow', overflow );
94 } else {
95 $el.css( 'overflow', $el.data( 'overflow' ) );
96 }
97 },
98 getUrl() {
99 return window.location.href;
100 },
101 addQueryVar( name, value, url ) {
102 return ( url === undefined ? window.location.href : url ).addQueryVar( name, value );
103 },
104 removeQueryVar( name, url ) {
105 return ( url === undefined ? window.location.href : url ).removeQueryVar( name );
106 },
107 reload( url ) {
108 if ( ! url ) {
109 url = window.location.href;
110 }
111 window.location.href = url;
112 },
113
114 parseResponse( response, type ) {
115 const m = response.match( /<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/s );
116 if ( m ) {
117 response = m[ 1 ];
118 }
119 return ( type || 'json' ) === 'json' ? this.parseJSON( response ) : response;
120 },
121 parseJSON( data ) {
122 if ( typeof data !== 'string' ) {
123 return data;
124 }
125
126 const m = String.raw( { raw: data } ).match( /<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/s );
127
128 try {
129 if ( m ) {
130 data = JSON.parse( m[ 1 ].replace( /(?:\r\n|\r|\n)/g, '' ) );
131 } else {
132 data = JSON.parse( data );
133 }
134 } catch ( e ) {
135 data = {};
136 }
137 return data;
138 },
139 ajax( args ) {
140 const type = args.type || 'post',
141 dataType = args.dataType || 'json',
142 data = args.action ? $.extend( args.data, { 'lp-ajax': args.action } ) : args.data,
143 beforeSend = args.beforeSend || function() {
144 },
145 url = args.url || window.location.href;
146 // console.debug( beforeSend );
147 $.ajax( {
148 data,
149 url,
150 type,
151 dataType: 'html',
152 beforeSend: beforeSend.apply( null, args ),
153 success( raw ) {
154 const response = LP.parseResponse( raw, dataType );
155 typeof ( args.success ) === 'function' && args.success( response, raw );
156 },
157 error() {
158 typeof ( args.error ) === 'function' && args.error.apply( null, LP.funcArgs2Array() );
159 },
160 } );
161 },
162 doAjax( args ) {
163 const type = args.type || 'post',
164 dataType = args.dataType || 'json',
165 action = ( ( args.prefix === undefined ) || 'learnpress_' ) + args.action,
166 data = args.action ? $.extend( args.data, { action } ) : args.data;
167
168 $.ajax( {
169 data,
170 url: ( args.url || window.location.href ),
171 type,
172 dataType: 'html',
173 success( raw ) {
174 const response = LP.parseResponse( raw, dataType );
175 typeof ( args.success ) === 'function' && args.success( response, raw );
176 },
177 error() {
178 typeof ( args.error ) === 'function' && args.error.apply( null, LP.funcArgs2Array() );
179 },
180 } );
181 },
182
183 funcArgs2Array( args ) {
184 const arr = [];
185 for ( let i = 0; i < args.length; i++ ) {
186 arr.push( args[ i ] );
187 }
188 return arr;
189 },
190 addFilter( action, callback ) {
191 const $doc = $( document ),
192 event = 'LP.' + action;
193 $doc.on( event, callback );
194 LP.log( $doc.data( 'events' ) );
195 return this;
196 },
197 applyFilters() {
198 const $doc = $( document ),
199 action = arguments[ 0 ],
200 args = this.funcArgs2Array( arguments );
201 if ( $doc.hasEvent( action ) ) {
202 args[ 0 ] = 'LP.' + action;
203 return $doc.triggerHandler.apply( $doc, args );
204 }
205 return args[ 1 ];
206 },
207 addAction( action, callback ) {
208 return this.addFilter( action, callback );
209 },
210 doAction() {
211 const $doc = $( document ),
212 action = arguments[ 0 ],
213 args = this.funcArgs2Array( arguments );
214 if ( $doc.hasEvent( action ) ) {
215 args[ 0 ] = 'LP.' + action;
216 $doc.trigger.apply( $doc, args );
217 }
218 },
219 toElement( element, args ) {
220 if ( $( element ).length === 0 ) {
221 return;
222 }
223 args = $.extend( {
224 delay: 300,
225 duration: 'slow',
226 offset: 50,
227 container: null,
228 callback: null,
229 invisible: false,
230 }, args || {} );
231 let $container = $( args.container ),
232 rootTop = 0;
233 if ( $container.length === 0 ) {
234 $container = $( 'body, html' );
235 }
236 rootTop = $container.offset().top;
237 const to = ( $( element ).offset().top + $container.scrollTop() ) - rootTop - args.offset;
238
239 function isElementInView( element, fullyInView ) {
240 const pageTop = $container.scrollTop();
241 const pageBottom = pageTop + $container.height();
242 const elementTop = $( element ).offset().top - $container.offset().top;
243 const elementBottom = elementTop + $( element ).height();
244
245 if ( fullyInView === true ) {
246 return ( ( pageTop < elementTop ) && ( pageBottom > elementBottom ) );
247 }
248 return ( ( elementTop <= pageBottom ) && ( elementBottom >= pageTop ) );
249 }
250
251 if ( args.invisible && isElementInView( element, true ) ) {
252 return;
253 }
254 $container.fadeIn( 10 )
255 .delay( args.delay )
256 .animate( {
257 scrollTop: to,
258 }, args.duration, args.callback );
259 },
260 uniqueId( prefix, more_entropy ) {
261 if ( typeof prefix === 'undefined' ) {
262 prefix = '';
263 }
264
265 let retId;
266 const formatSeed = function( seed, reqWidth ) {
267 seed = parseInt( seed, 10 )
268 .toString( 16 ); // to hex str
269 if ( reqWidth < seed.length ) { // so long we split
270 return seed.slice( seed.length - reqWidth );
271 }
272 if ( reqWidth > seed.length ) { // so short we pad
273 return new Array( 1 + ( reqWidth - seed.length ) )
274 .join( '0' ) + seed;
275 }
276 return seed;
277 };
278
279 // BEGIN REDUNDANT
280 if ( ! this.php_js ) {
281 this.php_js = {};
282 }
283 // END REDUNDANT
284 if ( ! this.php_js.uniqidSeed ) { // init seed with big random int
285 this.php_js.uniqidSeed = Math.floor( Math.random() * 0x75bcd15 );
286 }
287 this.php_js.uniqidSeed++;
288
289 retId = prefix; // start with prefix, add current milliseconds hex string
290 retId += formatSeed( parseInt( new Date()
291 .getTime() / 1000, 10 ), 8 );
292 retId += formatSeed( this.php_js.uniqidSeed, 5 ); // add seed hex string
293 if ( more_entropy ) {
294 // for more entropy we add a float lower to 10
295 retId += ( Math.random() * 10 )
296 .toFixed( 8 )
297 .toString();
298 }
299
300 return retId;
301 },
302 log() {
303 //if (typeof LEARN_PRESS_DEBUG != 'undefined' && LEARN_PRESS_DEBUG && console) {
304 for ( let i = 0, n = arguments.length; i < n; i++ ) {
305 console.log( arguments[ i ] );
306 }
307 //}
308 },
309 blockContent() {
310 if ( $( '#learn-press-block-content' ).length === 0 ) {
311 $( LP.template( 'learn-press-template-block-content', {} ) ).appendTo( $( 'body' ) );
312 }
313 LP.hideMainScrollbar().addClass( 'block-content' );
314 $( document ).trigger( 'learn_press_block_content' );
315 },
316 unblockContent() {
317 setTimeout( function() {
318 LP.showMainScrollbar().removeClass( 'block-content' );
319 $( document ).trigger( 'learn_press_unblock_content' );
320 }, 350 );
321 },
322 hideMainScrollbar( el ) {
323 if ( ! el ) {
324 el = 'html, body';
325 }
326 const $el = $( el );
327 $el.each( function() {
328 const $root = $( this ),
329 overflow = $root.css( 'overflow' );
330 $root.css( 'overflow', 'hidden' ).attr( 'overflow', overflow );
331 } );
332 return $el;
333 },
334 showMainScrollbar( el ) {
335 if ( ! el ) {
336 el = 'html, body';
337 }
338 const $el = $( el );
339 $el.each( function() {
340 const $root = $( this ),
341 overflow = $root.attr( 'overflow' );
342 $root.css( 'overflow', overflow ).removeAttr( 'overflow' );
343 } );
344 return $el;
345 },
346 template: typeof _ !== 'undefined' ? _.memoize( function( id, data ) {
347 let compiled,
348 options = {
349 evaluate: /<#([\s\S]+?)#>/g,
350 interpolate: /\{\{\{([\s\S]+?)\}\}\}/g,
351 escape: /\{\{([^\}]+?)\}\}(?!\})/g,
352 variable: 'data',
353 };
354
355 const tmpl = function( data ) {
356 compiled = compiled || _.template( $( '#' + id ).html(), null, options );
357 return compiled( data );
358 };
359 return data ? tmpl( data ) : tmpl;
360 }, function( a, b ) {
361 return a + '-' + JSON.stringify( b );
362 } ) : function() {
363 return '';
364 },
365 alert( localize, callback ) {
366 let title = '',
367 message = '';
368 if ( typeof localize === 'string' ) {
369 message = localize;
370 } else {
371 if ( typeof localize.title !== 'undefined' ) {
372 title = localize.title;
373 }
374 if ( typeof localize.message !== 'undefined' ) {
375 message = localize.message;
376 }
377 }
378 $.alerts.alert( message, title, function( e ) {
379 LP._on_alert_hide();
380 callback && callback( e );
381 } );
382 this._on_alert_show();
383 },
384 confirm( localize, callback ) {
385 let title = '',
386 message = '';
387
388 if ( typeof localize === 'string' ) {
389 message = localize;
390 } else {
391 if ( typeof localize.title !== 'undefined' ) {
392 title = localize.title;
393 }
394 if ( typeof localize.message !== 'undefined' ) {
395 message = localize.message;
396 }
397 }
398 $.alerts.confirm( message, title, function( e ) {
399 LP._on_alert_hide();
400 callback && callback( e );
401 } );
402 this._on_alert_show();
403 },
404 _on_alert_show() {
405 const $container = $( '#popup_container' ),
406 $placeholder = $( '<span id="popup_container_placeholder" />' ).insertAfter( $container ).data( 'xxx', $container );
407 $container.stop().css( 'top', '-=50' ).css( 'opacity', '0' ).animate( {
408 top: '+=50',
409 opacity: 1,
410 }, 250 );
411 },
412 _on_alert_hide() {
413 const $holder = $( '#popup_container_placeholder' ),
414 $container = $holder.data( 'xxx' );
415 if ( $container ) {
416 $container.replaceWith( $holder );
417 }
418 $container.appendTo( $( document.body ) );
419 $container.stop().animate( {
420 top: '+=50',
421 opacity: 0,
422 }, 250, function() {
423 $( this ).remove();
424 } );
425 },
426 sendMessage( data, object, targetOrigin, transfer ) {
427 if ( $.isPlainObject( data ) ) {
428 data = JSON.stringify( data );
429 }
430 object = object || window;
431 targetOrigin = targetOrigin || '*';
432 object.postMessage( data, targetOrigin, transfer );
433 },
434 receiveMessage( event, b ) {
435 let target = event.origin || event.originalEvent.origin,
436 data = event.data || event.originalEvent.data || '';
437 if ( typeof data === 'string' || data instanceof String ) {
438 if ( data.indexOf( '{' ) === 0 ) {
439 data = LP.parseJSON( data );
440 }
441 }
442 LP.Hook.doAction( 'learn_press_receive_message', data, target );
443 },
444
445 camelCaseDashObjectKeys( obj, deep = true ) {
446 const self = LP;
447 const isArray = function( a ) {
448 return Array.isArray( a );
449 };
450 const isObject = function( o ) {
451 return o === Object( o ) && ! isArray( o ) && typeof o !== 'function';
452 };
453 const toCamel = ( s ) => {
454 return s.replace( /([-_][a-z])/ig, ( $1 ) => {
455 return $1.toUpperCase()
456 .replace( '-', '' )
457 .replace( '_', '' );
458 } );
459 };
460
461 if ( isObject( obj ) ) {
462 const n = {};
463
464 Object.keys( obj )
465 .forEach( ( k ) => {
466 n[ toCamel( k ) ] = deep ? self.camelCaseDashObjectKeys( obj[ k ] ) : obj[ k ];
467 } );
468
469 return n;
470 } else if ( isArray( obj ) ) {
471 return obj.map( ( i ) => {
472 return self.camelCaseDashObjectKeys( i );
473 } );
474 }
475
476 return obj;
477 },
478 IframeSubmit,
479 };
480
481 $( document ).ready( function() {
482 if ( typeof $.alerts !== 'undefined' ) {
483 $.alerts.overlayColor = '#000';
484 $.alerts.overlayOpacity = 0.5;
485 $.alerts.okButton = lpGlobalSettings.localize.button_ok;
486 $.alerts.cancelButton = lpGlobalSettings.localize.button_cancel;
487 }
488
489 $( '.learn-press-message.fixed' ).each( function() {
490 const $el = $( this ),
491 options = $el.data();
492 ( function( $el, options ) {
493 if ( options.delayIn ) {
494 setTimeout( function() {
495 $el.show().hide().fadeIn();
496 }, options.delayIn );
497 }
498 if ( options.delayOut ) {
499 setTimeout( function() {
500 $el.fadeOut();
501 }, options.delayOut + ( options.delayIn || 0 ) );
502 }
503 }( $el, options ) );
504 } );
505
506 setTimeout( function() {
507 $( '.learn-press-nav-tabs li.active:not(.default) a' ).trigger( 'click' );
508 }, 300 );
509
510 //$( 'body.course-item-popup' ).parent().css( 'overflow', 'hidden' );
511
512 ( function() {
513 let timer = null,
514 callback = function() {
515 $( '.auto-check-lines' ).checkLines( function( r ) {
516 if ( r > 1 ) {
517 $( this ).removeClass( 'single-lines' );
518 } else {
519 $( this ).addClass( 'single-lines' );
520 }
521 $( this ).attr( 'rows', r );
522 } );
523 };
524 $( window ).on( 'resize.check-lines', function() {
525 if ( timer ) {
526 timer && clearTimeout( timer );
527 timer = setTimeout( callback, 300 );
528 } else {
529 callback();
530 }
531 } );
532 }() );
533
534 $( '.learn-press-tooltip, .lp-passing-conditional' ).LP_Tooltip( { offset: [ 24, 24 ] } );
535
536 $( '.learn-press-icon' ).LP_Tooltip( { offset: [ 30, 30 ] } );
537
538 $( '.learn-press-message[data-autoclose]' ).each( function() {
539 const $el = $( this ),
540 delay = parseInt( $el.data( 'autoclose' ) );
541 if ( delay ) {
542 setTimeout( function( $el ) {
543 $el.fadeOut();
544 }, delay, $el );
545 }
546 } );
547
548 $( document ).on( 'click', function() {
549 $( document ).trigger( 'learn-press/close-all-quick-tip' );
550 } );
551 } );
552
553 extend( {
554 Event_Callback,
555 MessageBox,
556 Cookies,
557 localStorage: _localStorage,
558 ..._default,
559 } );
560
561 export default {
562 fn,
563 QuickTip,
564 Cookies,
565 localStorage: _localStorage,
566 showPass,
567 };
568