PageSourceSearch

https://pnri.org/wp-content/themes/hotpepper_v5/assets/js/hp-shared.js?ver=5.0.1790242210

js pnri.org collected 2026-09-24 09:30:58 UTC 38,976 bytes, 1,157 lines download raw bytes

1/*
2=====
3functions/detections:
4
5file_buttons()
6file_upload_delete()
7file_upload_reset()
8file_upload_set()
9form_submit() -- includes recaptcha validation
10generate_password()
11hide_featured_img()
12htmlentities
13js_back()
14local_storage_debug()
15move_form_labels()
16optimage()
17password_chars_showhide()
18pcp() -- password confirm password form submit
19prevent_double_click()
20slider()
21spinner_load()
22spinner_show()
23scrollto()
24tabs()
25validate_ajax()
26wrappers_inner()
27wrappers_outer()
28=====
29*/
30
31// GLOBALS ===============================================================
32if (typeof $jsphp_vars['current_rel_uri'] != 'undefined') {
33	$current_rel_uri = $jsphp_vars['current_rel_uri'];
34}
35// /GLOBALS ===============================================================
36
37// TRIGGER VARS ==========================================================
38// $enable_recaptcha = false;
39$enable_recaptcha = true;
40
41// also set in shortcodes-form-2.php [form2]
42// $recaptcha_v = 2;
43$recaptcha_v = 3;
44
45// $recaptcha_bot_level = 0.2;
46$recaptcha_bot_level = 0.3;
47// $recaptcha_bot_level = 0.4;
48// /TRIGGER VARS ==========================================================
49
50// MISC ===================================================================
51/**
52 * htmlentities
53 * modded from https://ourcodeworld.com/articles/read/188/encode-and-decode-html-entities-using-pure-javascript
54 * by DP
55 */
56window.htmlentities = {
57	/**
58	 * Converts a string to its html characters completely.
59	 *
60	 * @param {String} str String with unescaped HTML characters
61	 **/
62	encode : function(str) {
63		var buf = [];
64
65		for (var i=str.length-1;i>=0;i--) {
66		buf.unshift(['&#', str[i].charCodeAt(), ';'].join(''));
67		}
68
69		return buf.join('');
70	},
71	/**
72	 * Converts an html characterSet into its original character.
73	 *
74	 * @param {String} str htmlSet entities
75	 **/
76	decode : function(str) {
77		return str.replace(/&#(\d+);/g, function(match, dec) {
78		return String.fromCharCode(dec);
79		});
80	}
81};// /window.htmlentities = {
82  
83/**
84 * js_back()
85 * a simple back button
86 *
87 */
88jQuery(document).ready(function($) {
89		$(document).on('click','.js-back',function($e){
90		$e.preventDefault();
91		js_back();
92	});
93});
94function js_back() {
95	history.back();
96}
97
98/**
99 * local_storage_debug()
100 * print to console all localStorage key/values
101 *
102 */
103function local_storage_debug() {
104	for (var $k in localStorage) {
105		if (typeof localStorage[$k] === 'function') {continue;}
106		console.log($k, ' = ', localStorage[$k]);
107	}// /for (var $k in localStorage) {
108}// /function local_storage_debug() {
109
110/**
111 * scrollto()
112 * scroll to anchor
113 * on page load, select change and link click
114 */
115jQuery(document).ready(function($) {
116	$('a[href^="#"]').on('click',function ($e) {
117		//use like: <a href="#fred">Fred</a>  <a name="fred" id="fred"></a>
118		$e.preventDefault();
119		if (typeof $(this).attr('fancybox-inline') != 'undefined') {return false;}
120		scrollto($(this).hash);
121	});
122	$('select').change(function($e){
123		if($(this).val().charAt(0) == '#') {
124			$e.preventDefault();
125			scrollto($(this).val());
126		}
127	});
128	$(window).ready(function(){
129		if (location.hash) {scrollto(location.hash);}
130	});
131});// /jQuery(document).ready(function($) {
132function scrollto(hash) {
133	jQuery(document).ready(function($) {
134		// console.log('hash:',hash);
135		if (typeof(hash) == 'undefined' || hash == '') {return false;}
136		var $target = $(hash);
137		if (typeof $target.offset() == 'undefined') {return false;}
138		$('html, body').stop().animate({
139			 'scrollTop': parseInt($target.offset().top)-0//130
140		}, 900, 'swing');
141	});// /jQuery(document).ready(function($) {
142}// /function scrollto (hash) {
143
144/**
145 * slider()
146 * slide rotator
147 * modded from hp-darrel.js upcoming events rotator
148 *
149 * @param string $slider REQUIRED
150 * @param int data-timer -- in milliseconds
151 * @param int data-timer_resume -- milliseconds
152 *
153 * @since 2021-02 - TW
154 *
155 * use like, (in WP use group and/or columns for div's):
156 * <div class="slider">
157 * 	<div class="slide">$content</div>
158 * 	<div class="slide">$content</div>
159 * </div>
160 *
161 * css like:
162.slider {
163border: solid 10px red;
164}
165.slide {
166	opacity: 0;
167	transition: 0.5s opacity;
168border: solid 10px green;
169}
170.slide:not(:first-of-type) {
171	position: absolute;
172	top: 0;
173	left: 0;
174}
175.slide .wp-block-column {
176border: solid 10px yellow;
177}
178.slide.slide-current {
179	opacity: 1;
180}
181.slider-nav-container {
182	display: flex;
183	justify-content: flex-start;
184border: solid 10px blue;
185}
186.slide-nav {
187	width: 20px;
188	height: 20px;
189	margin-right: 10px;
190	background-color: rgba(0,0,0,1);
191	border-radius: 20px;
192	cursor: pointer;
193	transition: 0.5s all;
194}
195.slide-nav.slide-nav-current {
196	background-color: rgba(255,255,255,1);
197}
198 */
199jQuery(document).ready(function($) {
200	$('.slider').each(function($k,$v){
201		slider($(this));
202	});
203});// /jQuery(document).ready(function($) {
204function slider($obj) {
205	jQuery(document).ready(function($) {
206		//console.log('$obj:',$obj);
207		//console.log('$obj.find(\'.slide\'):',$obj.find('.slide'));
208
209		var $timer = 4000;
210		if (typeof $obj.attr('data-timer') != 'undefined') {$timer = parseInt($obj.attr('data-timer'));}
211		//console.log('$timer:',$timer);
212
213		var $timer_resume = 10000;
214		if (typeof $obj.attr('data-timer_resume') != 'undefined') {$timer_resume = parseInt($obj.attr('data-timer_resume'));}
215		//console.log('$timer_resume:',$timer_resume);
216
217		var $slides_count = $obj.find('.slide').length;
218		var $slide_current = $slides_count;
219		if ($slides_count > 0) {
220			if ($slides_count > 1) {
221				// add the nav
222				$obj.append('<div class="slider-nav-container"></div>');
223				for(var $n = 1; $n <= $slides_count; $n++) {
224					$obj.find('.slider-nav-container').append('<div class="slide-nav" data-num="'+$n+'"></div>');
225				}
226
227				// start the timer
228				var $slidetimer = setInterval(function(){slide_display()},$timer);
229			}// /if ($slides_count > 1) {
230
231			// now show the first slide
232			slide_display();
233		}// /if ($slides_count > 0) {
234
235		$obj.find('.slide-nav').on('click',function(){
236			// stop the timer
237			clearInterval($slidetimer);
238			$slidetimer = null;
239
240			// restart the timer after x seconds
241			setTimeout(function(){
242				$slidetimer = setInterval(function(){slide_display()},$timer);
243			},$timer_resume);
244
245			// set the clicked slide to current
246			$slide_current = ($(this).attr('data-num')-1);
247			slide_display();
248
249		});// /$('.slide-nav').on('click',function(){
250
251		function slide_display() {
252			//console.log('$obj:',$obj);
253			$obj.find('.slide').removeClass('slide-current');
254			$slide_current = ($slide_current%$slides_count)+1;//console.log('$slide_current:',$slide_current);
255			$obj.find('.slide:nth-of-type('+$slide_current+')').addClass('slide-current');
256
257			$obj.find('.slide-nav').removeClass('slide-nav-current');
258			$obj.find('.slide-nav:nth-of-type('+$slide_current+')').addClass('slide-nav-current');
259		}// /function slide_display() {
260	});// /jQuery(document).ready(function($) {
261}// /function slider() {
262
263/**
264 * spinner_load()
265 * DOM insert modal background with a css animated div, hidden by default
266 * see also ../css/style-custom.css spinner
267 */
268spinner_load();
269function spinner_load() {
270	jQuery(document).ready(function($) {
271		var popup = '<div class="hp-spinnerpopup" style="display:none;position:fixed;top:0px;left:0px;z-index:20000;width:100%;height:100%;background-color: rgba(0,0,0,0.5);"><div id="loader"></div></i></div>';
272
273		$('body').append(popup);
274
275		var $viewport_height = parseInt($(window).height());//console.log($viewport_height);
276		$('.hp-spinnerpopup').css('padding-top',(($viewport_height/2)-60)+'px');
277
278		$('body').on('click','.show_spinner',function($e){spinner_show();});
279
280		window.default_alert = window.alert;// hold original alert obj
281		window.alert = function() {
282			$('.hp-spinnerpopup').hide();
283			default_alert(arguments[0]);
284			return;
285		}
286	});// /jQuery(document).ready(function($) {
287}// /function spinner_load() {
288
289/**
290 * spinner_show()
291 * show/hide from spinner_load() above
292 *
293 * can also instead simply use the show() hide() in a page
294 * to progammatically determine when to show/hide,
295 * such as on an ajax send/return
296 *
297 * @param int $length -- length in milliseconds before hiding the spinner popup
298 */
299function spinner_show($length) {
300	jQuery(document).ready(function($) {
301		//console.log('$length:',$length);
302		if (
303		typeof $length == 'undefined'
304		|| $length == ''
305		|| $length == 0
306		|| !$length
307		) {
308			$length = 10000;
309		}
310		$('.hp-spinnerpopup').show();
311		window.setTimeout(function(){
312			$('.hp-spinnerpopup').hide();
313		},$length);
314	});// /jQuery(document).ready(function($) {
315}// /function spinner_show() {
316
317/**
318 * tabs()
319 * HTML like:
320<div class="tabs">
321
322<div class="tabs-nav">
323<div class="active" data-tab="tab-name1">Name 1</div>
324<div data-tab="tab-name2">Name 2</div>
325</div><!-- class="tabs-nav"-->
326
327<div class="tab active" id="tab-name1">
328<content here>
329</div><!-- class="tab"-->
330
331<div class="tab" id="tab-name2">
332<content here>
333</div><!-- class="tab"-->
334
335</div><!-- class="tabs"-->
336
337 * CSS like:
338.tabs {
339}
340.tabs-nav {
341	position: relative;
342	z-index: 10000;
343	border-bottom: solid 1px #000;
344}
345.tabs-nav div {
346	display: inline-block;
347	padding: 3px 3px 3px 3px;
348	color: #ccc;
349	border-style: solid;
350	border-width: 1px 0px 0px 1px;
351	border-color: #000000;
352	cursor: pointer;
353}
354.tabs-nav div:last-child {
355	border-right-width: 1px;
356}
357.tabs-nav div.active{
358	color: #000;
359}
360.tab {
361	display: none;
362}
363.tab.active {
364	display: block;
365}
366 */
367function tabs() {
368	jQuery(document).ready(function($) {
369		$('.tabs-nav div').click(function($e){
370			$e.preventDefault();
371
372			var $tabs = $(this).closest('.tabs');
373			var $tabs_nav = $(this).closest('.tabs-nav');
374			var $target = $(this).attr('data-tab');
375
376			$tabs_nav.find('div').removeClass('active');
377			$(this).addClass('active');
378
379			$tabs.find('.tab').hide();
380			$('#'+$target).show();
381		});// /$('.tabs-nav div').click(function($e){
382	});// /jQuery(document).ready(function($) {
383}// /function tabs() {
384tabs();
385// /MISC ===================================================================
386
387// FORMS ===================================================================
388/*
389NOTE: 2020-06-12
390some of the below have been rebuilt and may not function correctly, test before deployment!!!!!
391*/
392
393// move labels =============================================
394/**
395 * move_form_labels()
396 * move form labels inside of form elements: text, textarea
397 * see also see also style-custom.css label {} for the inital hide of labels
398 * 
399 * must be in separate function if form is inserted in the dom via ajax or other mechanism, 
400 * ex: see /admintools-3/api.js at3_form_print()
401 */
402move_form_labels();
403function move_form_labels() {
404	jQuery(document).ready(function($) {
405		// if element is pre-populated, add .label-pos-focused to the container
406		
407		// move selected form element labels ==========
408		// see ../php/shortcodes-form.php [password],[text],[textarea]
409		var $container = $('.input-password-container,.input-text-container,.input-textarea-container');
410		$container.addClass('label-pos');
411
412		var $elements = 'input[type=password],input[type=text],textarea';
413		// console.log('$elements:',$elements);
414
415		// $container.find('input[type=text]').blur();// removes autofocus if set
416		if ($container.find('input[type=text]').prop('autofocus')) {
417			$container.find('input[type=text]').blur();
418		}
419
420		$container.each(function($k,$v){
421			// console.log('$v:',$v);
422			// console.log('$(this)',$(this));
423			var $_this = $(this);
424			var $val = $_this.find($elements).val();
425			// console.log('$val:',$val.length);
426			if (typeof $val !== 'undefined' && $val.length > 0) {$_this.addClass('label-pos-focused');}
427			// console.log('$_this.attr(\'class\')',$_this.attr('class'));
428			
429			// show the labels, see also style-custom.css label {}
430			$_this.find('label').show();
431			
432			$_this.find($elements).on('focus',function(){
433				$_this.addClass('label-pos-focused');
434			});
435			$_this.find('label').on('click',function(){
436				$_this.addClass('label-pos-focused');
437				$_this.find($elements).focus();
438			});
439			$_this.find($elements).on('blur',function(){
440				if ($(this).val() == '') {
441					$_this.removeClass('label-pos-focused');
442				}
443			});
444		});// /$container.each(function($k,$v){
445		// /move selected form element labels ==========
446
447		// refocus on the last autofocus ==========
448		/*
449		NOTE: DO NOT HAVE CONSOLE OPEN OR THIS WILL NOT FOCUS!!!!!
450		Also, a timeout will NOT steal focus from the console, so don't try it
451		*/
452		$.each($('input[type=text]'),function($k,$v){
453			if ($(this).prop('autofocus')) {
454				$(this).focus();
455			}
456		});// /$.each($('input[type=text]'),function($k,$v){
457		// /refocus on the last autofocus ==========
458
459		// suspenders/belt -- make sure labels are shown in case dom inserted
460		setTimeout(function(){
461			$('label').show();
462		},1600);
463
464	});// /jQuery(document).ready(function($) {
465}// /function move_form_labels() {
466// /move labels =============================================
467
468// validate on submit ============================================
469/**
470 * form_submit()
471 * validate forms on submit IF the form has data-validate="true"
472 *
473 * if data-validate == to an existing function, that function will be called, ex:
474 * [form2 name="password_confirm_password" validate="pcp"] will call this function: pcp()
475 * modded from: https://www.labnol.org/code/20181-call-javascript-function-by-name
476 *
477 * for recaptcha v2 (invisible):
478 * if a form has attr('data-recaptcha') == true
479 * and attr('data-rsk') != 'undefined', i.e. has the public key
480 * supposedly on initial fail, should pop a visual puzzle?? doesn't seem to be a way to test...
481 * on recaptcha fail, redirects to wp page /bot/
482 *
483 * for recaptcha v3:
484 * if a form has attr('data-recaptcha') == true
485 * and attr('data-rsk') != 'undefined', i.e. has the public key
486 * on recaptcha fail, redirects to wp page /bot/
487 *
488 * see ../php/shortcodes-form-2.php [form2]
489 */
490jQuery(document).ready(function($) {
491	$('form').on('submit',function($e){
492
493		// call a specific submit function:
494		if (
495		typeof $(this).attr('data-validate') !== 'undefined'
496		&& typeof window[$(this).attr('data-validate')] === 'function'// $(this).attr('data-validate') == 'pcp'
497		) {
498			window[$(this).attr('data-validate')]($e,$(this));//pcp($e,$(this));
499		}
500
501		// use the generic submit function
502		else {
503			form_submit($e,$(this));
504		}
505	});// /$('form').on('submit',function($e){
506	function form_submit($e,$obj) {
507		if (
508		typeof $obj.attr('data-validate') === 'undefined'
509		|| $obj.attr('data-validate') !== 'true'
510		) {return;}
511
512		/*
513		stop the submit
514		to resubmit after tests,
515		unbind the submit button from the submit action like:
516		$obj.unbind('submit').submit();
517		*/
518		$e.preventDefault();
519
520		var $validated = true;
521
522		// see ../../assets/js/validate.js for validate functions
523		$obj.find(':input').each(function($k,$v){
524			//console.log('$(this):',$(this));
525			var $validate_type = '';
526			if (typeof $(this).attr('data-validate') != 'undefined') {$validate_type = $(this).attr('data-validate');}
527			//console.log('$validate_type:',$validate_type);
528			var $msg = '';
529			if (typeof $(this).attr('data-validate-msg') != 'undefined') {$msg = $(this).attr('data-validate-msg');}
530			//console.log($msg);
531
532			if ($validate_type == 'blank' && !check_blank($(this),$msg)) {$validated = false;return false;}
533			if ($validate_type == 'blank-no-email' && !check_blank_no_email($(this),$msg)) {$validated = false;return false;}
534			if ($validate_type == 'checkbox' && !check_checkbox($(this),$msg)) {$validated = false;return false;}
535			if ($validate_type == 'email' && !check_email($(this),$msg)) {$validated = false;return false;}
536			if ($validate_type == 'radio' && !check_radio_grp($(this),$msg)) {$validated = false;return false;}
537			if ($validate_type == 'select' && !check_select($(this),$msg)) {$validated = false;return false;}
538
539			// see ../php/shortcodes-form-2.php > [password_confirm_password2]
540			if ($validate_type == 'pcp-add' && $(this).hasClass('password')) {
541				// NOTE: $(this).hasClass('password') skips .password_confirm in the loop
542				var $pw = $(this);
543				var $pwc = $obj.find('.password_confirm');//alert($pwc);
544				if(!check_blank($pw,'Please fill out the "'+$pw.attr('title')+'" field')) {$validated = false;return false;}
545				if(!check_blank($pwc,'Please fill out the "'+$pwc.attr('title')+'" field')) {$validated = false;return false;}
546				if(!check_match_a_b($pw,$pwc,$msg)) {$validated = false;return false;}
547				if(!check_min_max($pw,$pw.attr('data-minlength'),$pw.attr('data-maxlength'))) {$validated = false;return false;}
548			}// /if ($validate_type == 'pcp-add' && $(this).hasClass('password')) {
549
550		});// /$(this).find(':input').each(function($k,$v){
551		//if (!check_blank($('#form_id #field_id'))) {return false;}// an example of checking a specific field instead of using the above loop
552
553		// recaptcha test MUST be LAST!!!!!
554		// NOTE: $enable_recaptcha var at the top simply stops the redirect to the bot page, it does NOT stop the recaptcha test
555		if (
556		typeof $obj.attr('data-recaptcha') != 'undefined'
557		&& $obj.attr('data-recaptcha') == true
558		&& typeof $obj.attr('data-rsk') != 'undefined'
559		&& $validated
560		) {
561			// console.log('$obj.attr(\'id\')',$obj.attr('id'));
562			// console.log('$obj.attr(\'data-recaptcha\'):',$obj.attr('data-recaptcha'));
563			// console.log('$obj.attr(\'data-rsk\'):',$obj.attr('data-rsk'));
564			var $site_key = $obj.attr('data-rsk');
565			var $rsk = $site_key;
566
567			// $recaptcha_v set at the top of this file
568			// for $jsphp_vars see ../../functions.php
569			if ($recaptcha_v == 2) {
570				/*
571				see shortcodes-form-2.php form2_func()
572				sets the inital recaptcha invisible widget up in an obj for use in grecaptcha.execute() below
573				mulitple recaptcha widgets per page allowed this way
574				*/
575				// var $rvu = $jsphp_vars['parent_theme_file_uri']+'/assets/php/recaptcha/recaptcha_v2_validate.php';//'/wp-content/themes/'.HP_THEME_FOLDER.'/assets/php/recaptcha/recaptcha_v3_validate.php';
576				var $rvu = $jsphp_vars['stylesheet_directory_uri']+'/assets/php/recaptcha/recaptcha_v2_validate.php';//'/wp-content/themes/'.HP_THEME_FOLDER.'/assets/php/recaptcha/recaptcha_v3_validate.php';
577				// /*
578				grecaptcha.ready(function() {
579					// alert($recaptcha_widget[$obj.attr('id')]);
580					grecaptcha.execute($recaptcha_widget[$obj.attr('id')]).then(function($token) {
581						var $url = $rvu;
582						// why use $.ajax instead of $.post??? Seems setting async to false gives a more accurate score???
583						$.ajax({
584							async: true,//false,
585							type: 'POST',
586							url: $url,
587							data: {'token':$token},
588							success: function($data){
589								$data = JSON.parse($data);
590								// console.log($data);
591
592								// always show this in console, helps with troubleshooting
593								console.log('v2 $data[\'score\']:',$data['score']);
594
595								// fail --  don't test score, just $data['success'] true|false
596								// $enable_recaptcha set at the top of this file
597								if (
598								$enable_recaptcha
599								&& (
600									typeof $data['success'] == 'undefined'
601									|| !$data['success']
602									// || typeof $data['score'] == 'undefined'
603									// || $data['score'] < $recaptcha_bot_level
604									)
605								) {
606									// pops visual recaptcha??? no way to test it seems...
607										window.location.replace('/bot/');
608										return false;
609								}
610								// pass -- submit form
611								else {$obj.unbind('submit').submit();}
612							},
613							dataType: 'json'
614						});
615
616					});
617				});
618				// */
619			}// /if ($recaptcha_v == 2) {
620			if ($recaptcha_v == 3) {
621				// var $rvu = $jsphp_vars['parent_theme_file_uri']+'/assets/php/recaptcha/recaptcha_v3_validate.php';//'/wp-content/themes/'.HP_THEME_FOLDER.'/assets/php/recaptcha/recaptcha_v3_validate.php';
622				var $rvu = $jsphp_vars['stylesheet_directory_uri']+'/assets/php/recaptcha/recaptcha_v3_validate.php';//'/wp-content/themes/'.HP_THEME_FOLDER.'/assets/php/recaptcha/recaptcha_v3_validate.php';
623				grecaptcha.ready(function() {
624					grecaptcha.execute($rsk, {action:'shortcode_form'}).then(function(token) {
625						var $url = $rvu;
626						// why use $.ajax instead of $.post??? Seems setting async to false gives a more accurate score???
627						$.ajax({
628							async: true,//false,
629							type: 'POST',
630							url: $url,
631							data: {'token':token},
632							success: function($data){
633								$data = JSON.parse($data);//console.log($data);
634
635								// always show this in console, helps with troubleshooting
636								console.log('v3 $data[\'score\']:',$data['score']);
637
638								// $enable_recaptcha set at the top of this file
639								if ($enable_recaptcha) {
640									if (typeof $data['success'] == 'undefined') {
641										window.location.replace('/bot/?msg=success-undefined');
642										return false;
643									}
644									if (!$data['success']) {
645										window.location.replace('/bot/?msg=success-false');
646										return false;
647									}
648									if (typeof $data['score'] == 'undefined') {
649										window.location.replace('/bot/?msg=score-undefined');
650										return false;
651									}
652									if($data['score'] < $recaptcha_bot_level) {
653										window.location.replace('/bot/?msg=score-small&size='+$data['score']);
654										return false;
655									}
656
657									// pass -- submit the form
658									$obj.unbind('submit').submit();
659								}// /if ($enable_recaptcha) {
660								if (!$enable_recaptcha) {// submit the form regardless, see top of this file
661									$obj.unbind('submit').submit();
662								}// /if (!$enable_recaptcha) {
663							},
664							dataType: 'json'
665						});
666					});// /grecaptcha.execute(
667				});// /grecaptcha.ready(function() {
668			}// /if ($recaptcha_v == 3) {
669		}// /if (typeof $obj.attr('data-recaptcha') != 'undefined'
670
671		else if ($validated) {$obj.unbind('submit').submit();}
672	}// /function form_submit() {
673
674	/**
675	* pcp()
676	* password confirm password form submit
677	* see ../php/shortcodes-form-2.php > [password_confirm_password2]
678	*
679	* html MUST be like:
680	* <input type="password" class="password"
681	* <input type="password" class="password"_confirm"
682	*/
683	function pcp($e,$obj) {
684		//alert($e);$e.preventDefault();return false;
685		var $pw = $obj.find('input.password');
686		var $pwc = $obj.find('input.password_confirm');
687
688		var $msg = '';
689		if (typeof $pw.attr('data-validate-msg') != 'undefined') {$msg = $pw.attr('data-validate-msg');}
690		//console.log($msg);
691		if(!check_blank($pw,'Please fill out the "'+$pw.attr('title')+'" field')) {$e.preventDefault();return false;}
692		if(!check_blank($pwc,'Please fill out the "'+$pwc.attr('title')+'" field')) {$e.preventDefault();return false;}
693		if(!check_match_a_b($pw,$pwc,$msg)) {$e.preventDefault();return false;}
694		if(!check_min_max($pw,$pw.attr('data-minlength'),$pw.attr('data-maxlength'))) {$e.preventDefault();return false;}
695	}// /function form_submit_pcp() {
696});// /jQuery(document).ready(function($) {
697// /validate on submit ============================================
698
699// ajax validate ============================================
700/**
701 * validate_ajax()
702 * see ../php/shortcodes-form-2.php [text2]
703 *
704 * NOTE: blur initially gets hit for all text fields to handle the moving of the label
705 * into the field, see move_form_labels() above
706 */
707jQuery(document).ready(function($) {
708	$('input').on('blur',function(){
709		if (typeof $(this).attr('data-validate-ajax') !== 'undefined')  {
710			validate_ajax($(this));
711		}
712	});
713});// /jQuery(document).ready(function($) {
714function validate_ajax($obj) {
715	jQuery(document).ready(function($) {
716		//var $obj = $(obj);console.log('$obj:',$obj);
717
718		// if empty, stop -- will be hit on page load all the time by move_form_labels()
719		if (typeof $obj.val() == 'undefined' || $obj.val() == '') {return false;}
720
721		// if no string to test with, stop
722		if (typeof $obj.attr('data-validate-ajax') == 'undefined' || $obj.attr('data-validate-ajax') == '') {return false;}
723
724		var $args = {};
725		parse_str($obj.attr('data-validate-ajax'),$args);
726		if (typeof $args['process'] == 'undefined' || $args['process'] == '') {$args['process'] = 'unique_db';}
727		$args['v'] = $obj.val();
728		$args['ajax_return'] = true;
729
730		var $url = './';// see db.php
731		if (typeof $args['url'] != 'undefined' && $args['url'] != '') {$url = $args['url'];}
732
733		//console.log('$url:',$url);
734		//console.log('$args:',$args);
735		$.post($url,$args).done(function($data) {
736			//console.log('validate_ajax $data:',$data);
737			//console.log('$obj.attr(\'data-validate-ajax-exist\'):',$obj.attr('data-validate-ajax-exist'));
738			/*
739			if a value is returned, it means that the value exists already in the db
740			$exist = check db to see if returned value is to be tested as existing or not existing
741			*/
742			var $exist = JSON.parse($obj.attr('data-validate-ajax-exist').toLowerCase());// cast "true"|"false" to bool true|false
743			if (!$exist && $data.hasOwnProperty('check_v')) {
744				alert('The value you entered "'+$obj.val()+'" is not available. Please try again.');
745				$obj.val('');
746				$obj.focus();
747			}
748			if ($exist && !$data.hasOwnProperty('check_v')) {
749				alert('The value you entered "'+$obj.val()+'" is not on file. Please try again.');
750				$obj.val('');
751				$obj.focus();
752			}
753		},'json');
754	});// /jQuery(document).ready(function($) {
755}// /function validate_ajax(obj) {
756// /ajax validate ============================================
757
758// file upload ==============================================
759/**
760 * file uploader
761 * upload both to specific server location or email attachement
762 * drag and drop interface
763 *
764 * see ../php/shortcodes-form-2.php [file2]
765 */
766jQuery(document).ready(function($) {
767	if (typeof $('.file-uploader-container') != 'undefined') {
768		$('.file-uploader-container').each(function($k,$v){
769			$obj = $(this);
770			var $id = $obj.attr('data-id');//console.log('$id:',$id);
771			var $data_id = $obj.attr('data-id');//console.log('$data_id:',$data_id);
772			var $imgsrc = $obj.find('img').attr('src');//console.log('$imgsrc:',$imgsrc);
773			var $init_string = $('#'+$data_id+'-file-upload-display-name').html();//console.log('$init_string:',$init_string);
774
775			// show initial image
776			if (!empty($imgsrc)) {
777				$id.show();
778			}// /if (!empty($imgsrc)) {
779
780			// drop on file input
781			$('#'+$data_id).on('dragover',false).on('drop',function($e){
782				var $files = $e.originalEvent.dataTransfer.files;//console.log($files);
783				file_upload_set($files,$data_id);
784			});
785
786			$('#'+$data_id+'-div .file-upload-reset').on('click',function($e){
787				file_upload_reset($e,$data_id,$init_string,$imgsrc);
788			});
789
790			$obj.find('.bn_delete').on('click',function($e){
791				file_upload_delete($e,$data_id,$itempath,$copypath)
792			});
793		});// /$('.file-uploader-container').each(function($k,$v){
794	}// /if (typeof $('.file-uploader-container') != 'undefined') {
795});// /jQuery(document).ready(function($) {
796
797/**
798 * file_upload_set()
799 *
800 */
801function file_upload_set($files,$data_id) {
802	//console.log('$files:',$files);
803	//console.log('$data_id:',$data_id);
804	jQuery(document).ready(function($) {
805		var $name = $files[0]['name'];//console.log($name);
806		$('#'+$data_id+'-file-upload-display-name').show().html($name);
807		//for(var $n = 0; $n < $files.length; $n++) {console.log($n+':'+$files[$n].name);}
808
809		// image upload =====
810		if (
811		typeof $files[0]['type'] != 'undefined'
812		&& $files[0]['type'].search(/image/i) > -1
813		) {
814			var reader = new FileReader();
815			reader.onload = function ($e) {
816				$('#'+$data_id+'-file-upload-img-container').show();
817				$('#'+$data_id+'-file-upload-img-container img').attr('src',$e.target.result);
818			}
819			//reader.readAsDataURL(e.target.files[0]);
820			reader.readAsDataURL($files[0]);
821		}
822		// /image upload =====
823
824		$('#'+$data_id+'-div .file-upload-reset').show();
825	});// /jQuery(document).ready(function($) {
826}// /function file_upload_set() {
827
828/**
829 * file_upload_reset()
830 *
831 */
832function file_upload_reset($e,$data_id,$init_string,$imgsrc) {
833	jQuery(document).ready(function($) {
834		$e.preventDefault();
835		$('#'+$data_id+'-file-upload-display-name').html($init_string);
836		$('#'+$data_id).val('');// this is the ONLY value that can be set with js for an input[type="file"]
837		$('#'+$data_id+'-file-upload-img-container img').attr('src',$imgsrc);
838		$('#'+$data_id+'-div .file-upload-reset').hide();
839	});// /jQuery(document).ready(function($) {
840}// /function file_upload_reset() {
841
842/**
843 * file_upload_delete()
844 *
845 */
846function file_upload_delete($e,$data_id,$itempath,$copypath) {
847	jQuery(document).ready(function($) {
848		//var $_this = $(this);
849		var $_this = $e.target;
850		$e.preventDefault();
851		if (confirm('Are you SURE you want to delete this???')) {
852			$imgsrc = '';
853			$url = './';// see shared.php
854			$postdata = {
855				'process':'delete_collateral',
856				'item':$itempath,
857				'copypath':$copypath,
858				'ajax':true,
859			};
860			//console.log('$postdata:',$postdata);
861
862			$.post($url,$postdata).done(function($data) {
863				console.log($data);
864				if (
865				$data.hasOwnProperty('deleted')
866				&& $data['deleted'] == true
867				) {
868					$('#'+$data_id+'-div .file-upload-reset').click();
869					$_this.hide();
870				}
871				else {
872					alert('There was a problem with your request.');
873				}
874			},'json').fail(function(xhr,status,error){
875				console.log('xhr:',xhr);
876				console.log('status:',status);
877				console.log('error:',error);
878			});
879		}// /if (confirm
880	});// /jQuery(document).ready(function($) {
881}// /function file_upload_delete() {
882// /file upload ==============================================
883
884// generate password ========================================
885/**
886 * generate_password()
887 *
888 */
889jQuery(document).ready(function($) {
890	$('.gen-pswd').on('click',function($e){
891		$e.preventDefault();
892		generate_password($e,$(this));
893	});
894});// /jQuery(document).ready(function($) {
895function generate_password($e,$obj) {
896	jQuery(document).ready(function($) {
897		var $id = $obj.attr('data-id').replace('.','\\\.');// in case of id like: tablename.colname
898		var $url = './';
899		var $args = {
900			'process':'ajax_pswd_gen',// in shared.php
901			'length':9,
902			'strength':10,
903		}
904		$.post($url,$args).done(function($data) {
905			//console.log('$data:',$data);
906			//console.log('$id:',$id);
907			if ($data.hasOwnProperty('pswd')) {
908				var $css_hide = {
909					'color':'rgba(0,0,0,0)',
910					'transition':'color 200ms',
911				};
912				var $css_show = {
913					'color':'rgba(0,0,0,1)',
914				};
915
916				var $newpswdmsg = '<div><i>Randomly generated password:</i></div><p><strong style="display:none;">'+$data['pswd']+'</strong></p>';
917				$('#'+$id+'-gen-result').html($newpswdmsg);
918				$('#'+$id+'').val($data['pswd']).css($css_hide);
919				$('#'+$id+'_confirm').val($data['pswd']).css($css_hide);
920				$('#'+$id+'').focus();
921				$('#'+$id+'_confirm').focus();
922				$('#'+$id+'-gen-result strong').fadeIn('fast',function(){
923					$('#'+$id+'').css($css_show);
924					$('#'+$id+'_confirm').css($css_show);
925				});
926			}
927		},'json');// /$.post(
928	});// /jQuery(document).ready(function($) {
929}// /function generate_password() {
930
931// optimize images ========================================
932/**
933 * optimage()
934 *
935 */
936document.addEventListener('DOMContentLoaded', (event) => {
937	//console.log('DOM fully loaded and parsed');
938	window.onresize = optimage;
939	optimage();
940});
941
942// optimize images ========================================
943/**
944 * optimage()
945 *
946 */
947document.addEventListener('DOMContentLoaded', (event) => {
948	//console.log('DOM fully loaded and parsed');
949	window.onresize = optimage;
950	optimage();
951});
952
953function optimage() {
954	var optimages = document.querySelectorAll('.optimage img')
955	optimages.forEach(function(optimg) {
956		if (optimg.hasAttribute('srcset')) {
957			var srcset;
958			if (optimg.hasAttribute('srcset2')) {
959				srcset = optimg.getAttribute('srcset2');
960			} else {
961				srcset = optimg.getAttribute('srcset');
962				optimg.setAttribute('srcset2', srcset);
963				optimg.srcset = "";
964			}
965			var sources = srcset.split(', ').map(e => e.split(' '));
966			sources.forEach(function (source, index) {
967				sources[index][1] = Number(sources[index][1].substring(0, sources[index][1].length - 1))
968			})
969			sources.sort(function (a, b) {
970				return b[1] - a[1]
971			});
972			var containerw = optimg.closest('.optimage').offsetWidth;
973			var containerh = optimg.closest('.optimage').offsetHeight;
974			var optimgwidth = optimg.getAttribute('width');
975			var optimgheight = optimg.getAttribute('height');
976			var optimgratio = optimgheight / optimgwidth;
977			var zoomlevel = 0
978
979			while (sources[zoomlevel][1] > containerw && optimgratio * sources[zoomlevel][1] > containerh) {
980				//console.log(zoomlevel, containerw, sources[zoomlevel][1]);
981				if (zoomlevel === sources.length - 1) break;
982				if (containerw < sources[zoomlevel + 1][1] && containerh < sources[zoomlevel + 1][1] * optimgratio) {
983					zoomlevel = zoomlevel + 1;
984				} else {
985					break
986				}
987			}
988			//console.log(containerw + ": " + sources[zoomlevel]);
989			zoomlevel = Math.max(0, Math.min(zoomlevel, sources.length - 1))
990			if (optimg.src !== sources[zoomlevel][0]) optimg.src = sources[zoomlevel][0];
991		}
992	})
993}
994
995
996
997// /generate password ========================================
998
999/**
1000 * password_chars_showhide()
1001 * show/hide the characters in a password input
1002 */
1003jQuery(document).ready(function($) {
1004	$(document).on('click','.show-pswd',function($e){
1005		$e.preventDefault();
1006		password_chars_showhide($(this));
1007	});
1008});// /jQuery(document).ready(function($) {
1009function password_chars_showhide($obj) {
1010	$obj.toggleClass('active');
1011	var $pswd_field = $obj.closest('.pswd-container').find('.password');
1012	if ($pswd_field.attr('type') === 'password') {
1013		$pswd_field.attr('type','text');
1014	}
1015	else {
1016		$pswd_field.attr('type','password');
1017	}
1018	$pswd_field.focus();
1019}
1020
1021// prevent form submission double-clicking ===============================
1022/**
1023 * prevent_double_click()
1024 * stop accidental or purposeful multiple clicks on submit buttons and other form submission types
1025 *
1026 * NOTE: DO NOT DISABLE THE SUBMIT BUTTON,
1027 * will break submissions that require the name of the submit button!!!!!
1028 * Instead, set a data-disabled attr.
1029 */
1030jQuery(document).ready(function($) {
1031	$("form").each(function($k,$v) {
1032		$_this = $(this);
1033		prevent_double_click($k,$v,$_this);
1034	});// /$("form").each(function($k,$v) {
1035});// /jQuery(document).ready(function($) {
1036function prevent_double_click($k,$v,$_this) {
1037	jQuery(document).ready(function($) {
1038
1039		// enter key
1040		$_this.keypress(function($e){
1041			if($e.which == 13) {
1042				// sets the data-disabled attr on the form itself.
1043				if ($_this.attr('data-disabled')) {
1044					$e.preventDefault();
1045					return false;
1046				}
1047				$_this.attr('data-disabled','disabled');
1048				setTimeout(function(){$_this.removeAttr('data-disabled');},1000);
1049				console.log('form submitted');
1050			}// /if($e.which == 13) {
1051		});// /$_this.keypress(function($e){
1052
1053		// submit buttons
1054		$_this.submit(function($e){
1055			// assume regular input submit button
1056			var $submit = $_this.find('input[type="submit"]');
1057
1058			// if running from an html 5 button instead:
1059			if ($submit.length === 0) {$submit = $_this.find('button[type="submit"]');}
1060
1061			if ($submit.attr('data-disabled')) {
1062				$e.preventDefault();
1063				return false;
1064			}
1065			$submit.attr('data-disabled','disabled');
1066			setTimeout(function(){$submit.removeAttr('data-disabled');},1000);
1067
1068			console.log('form submitted');
1069		});// /$_this.submit(function($e){
1070	});// /jQuery(document).ready(function($) {
1071}// /function prevent_double_click() {
1072// /prevent form submission double-clicking ===============================
1073
1074// /FORMS ===================================================================
1075
1076
1077// WORDPRESS additions/overwrites ==========================================
1078// NOTE: these additions are a moving target, so try not to rely on them
1079
1080/**
1081 * hide_featured_img()
1082 * if an image/cover is in the page with a class of "featured" remove any featured image that may be set
1083 * either manually or via shortcode [featured_image]
1084 * mainly useful for [featured_image use_default_img="true"], see shortcodes php for settings
1085 */
1086hide_featured_img();
1087function hide_featured_img() {
1088	jQuery(document).ready(function($) {
1089		if (
1090		$('.wp-block-cover.featured').length
1091		|| $('.wp-block-image.featured').length
1092		) {
1093			$('.wp-block-post-featured-image').hide();
1094		}
1095	});// /jQuery(document).ready(function($) {
1096}// /function hide_featured_img() {
1097
1098/**
1099 * remove empty p tags
1100 */
1101jQuery(document).ready(function($) {
1102	$('p:empty').remove();
1103});// /jQuery(document).ready(function($) {
1104
1105/**
1106 * file_buttons()
1107 * add classes for file buttons
1108 */
1109file_buttons();
1110function file_buttons() {
1111	jQuery(document).ready(function($) {
1112		$('a.wp-block-file__button').each(function($k,$v){
1113			//console.log('$(this).attr(\'href\'):',$(this).attr('href'));
1114			if (stripos($(this).attr('href'),'.xls') !== false) {
1115				$(this).addClass('xls');
1116				$(this).text('Excel');
1117			}
1118			if (stripos($(this).attr('href'),'.pdf') !== false) {
1119				$(this).addClass('pdf');
1120				$(this).text('PDF');
1121			}
1122			if (stripos($(this).attr('href'),'.doc') !== false) {
1123				$(this).addClass('doc');
1124				$(this).text('Doc');
1125			}
1126		});// /$('.wp-block-file__button').each(function($k,$v){
1127		// NOTE: initially hidden in ../css/style.css
1128		// $('a.wp-block-file__button').attr('style','display:inline-block !important');
1129	});// /jQuery(document).ready(function($) {
1130}// /function file_buttons() {
1131
1132/**
1133* wrappers_inner()
1134* add inner div wrappers to select elements
1135*/
1136jQuery(document).ready(function($) {
1137	wrappers_inner();
1138});// /jQuery(document).ready(function($) {
1139function wrappers_inner() {
1140	jQuery(document).ready(function($) {
1141		// $('.wp-block-column').wrapInner('<div class="wp-block-column-inner"></div>');
1142	});// /jQuery(document).ready(function($) {
1143}// /function wrappers_inner() {
1144
1145/**
1146* wrappers_outer()
1147* add outer div wrappers to select elements
1148*
1149*/
1150jQuery(document).ready(function($) {
1151	wrappers_outer();
1152});// /jQuery(document).ready(function($) {
1153function wrappers_outer() {
1154	jQuery(document).ready(function($) {
1155	});// /jQuery(document).ready(function($) {
1156}// /function wrappers_outer() {
1157// /WORDPRESS additions/overwrites ==========================================

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.