PageSourceSearch

https://www.ipko.com/wp-content/plugins/unlimited-elements-for-ele…/remote/ue-remote-controls.js

js ipko.com collected 2026-09-24 09:38:10 UTC 47,445 bytes, 2,808 lines download raw bytes

1/**
2* remote gallery api class
3*/
4function UERemoteGeneralAPI(){
5
6	var t = this, g_objParent;
7	var g_isTypeEvents = false;
8	var g_options = null;
9
10	var g_vars = {
11		parent_id:"",
12		class_items:"",
13		class_active:"",
14		selector_item_trigger:"",
15		add_set_active_code:false,
16		active_code_first_unselected:false,
17		listen_class_change:true,
18		enableDebug:false,
19		is_editor:false,
20		trigger_event: "click"
21	};
22
23	var g_temp = {
24			handle:null,
25			trashold:50
26	};
27
28	/**
29	* console log some string
30	*/
31	function trace(str){
32		console.log(str);
33	}
34
35	/**
36	 * get object property
37	 */
38	function getVal(obj, name, defaultValue){
39
40		return window.ueRemoteConnection.getVal(obj, name, defaultValue);
41	}
42
43
44	/**
45	 * run function with trashold
46	 */
47	function runWithTrashold(func, trashold){
48
49		if(g_temp.handle)
50			clearTimeout(g_temp.handle);
51
52		g_temp.handle = setTimeout(func, g_temp.trashold);
53
54	};
55
56
57	/**
58	 * validate inited
59	 */
60	function validateInited(){
61
62		var isInited = g_objParent.data("remote_inited");
63
64		if(isInited == false)
65			throw new Error("The remote parent not inited");
66
67	}
68
69	/**
70	 * get items objet
71	 */
72	function getObjItems(){
73
74		var objItems = g_objParent.find("."+g_vars.class_items);
75
76		return(objItems);
77	}
78
79
80	/**
81	 * get total items
82	 */
83	function getNumTotal(){
84		
85		var objItems = g_objParent.find("."+g_vars.class_items);
86		
87		var numTotal = objItems.length;
88				
89		return(numTotal);
90	}
91
92
93	/**
94	 * get current item
95	 */
96	function getObjCurrentItem(){
97
98		var selector = "."+g_vars.class_items+"."+g_vars.class_active;
99
100		var objCurrent = g_objParent.find(selector);
101
102		return(objCurrent);
103	}
104
105
106	/**
107	 * get current item
108	 */
109	function getNumCurrent(){
110
111		var objCurrent = getObjCurrentItem();
112		
113		if(objCurrent.length == 0)
114			return(-1);
115		
116		var index = objCurrent.index();
117
118		return(index);
119	}
120
121	/**
122	 * get item by index
123	 */
124	function getItem(index){
125
126		if(index < 0)
127			index = 0;
128
129		var objItems = getObjItems();
130
131		if(objItems.length == 0)
132			return(null);
133
134		if(index >= objItems.length )
135			index = objItems.length-1;
136
137		var objItem = jQuery(objItems[index]);
138
139		return(objItem);
140	}
141
142
143
144	/**
145	 * get item number
146	 */
147	function getItemNum(num){
148
149		var total = getNumTotal();
150
151		if(jQuery.isNumeric(num) == false)
152			throw new Error("num item should be numeric");
153
154		if(num >= total )
155			num = total-1;
156
157		if(num < 0)
158			num = 0;
159		
160		if(!num)
161			num = 0;
162
163		if(typeof num == "undefined")
164			num = 0;
165
166		return(num);
167	}
168
169	/**
170	 * unselect all selected items if available
171	 */
172	function unselectItems(){
173		
174		var objItem = getObjCurrentItem();
175				
176		if(objItem.length == null){
177			
178			if(g_vars.enableDebug)
179				trace("Unselect Item - Selected Item not found "+g_vars.parent_id);
180			
181			return(false);
182		}
183				
184		objItem.removeClass(g_vars.class_active);
185		
186		if(g_vars.enableDebug)
187			trace("Items Unselected: " + g_vars.parent_id);
188		
189	}
190	
191	
192	/**
193	 * change item
194	 */
195	function changeItem(mixed){
196		
197		var numItem = getItemNum(mixed);
198
199		var objItem = getItem(numItem);
200		
201		if(objItem == null){
202			
203			if(g_vars.enableDebug)
204				trace("General API: changeItem - item not found");
205			
206			return(false);
207		}
208		
209		var numCurrent = getNumCurrent();
210		
211		if(numCurrent === numItem){
212			
213			if(g_vars.enableDebug)
214				trace("General API: changeItem - num current == numitem - skip (" + numItem+" )");
215			
216			return(false);
217		}
218		
219		
220		if(!g_vars.selector_item_trigger){
221
222			objItem.trigger(g_vars.trigger_event);
223			return(false);
224		}
225
226		var objInner = objItem.find(g_vars.selector_item_trigger);
227
228		if(objInner.length == 0){
229			trace(objItem);
230			throw new Error("Can't find inner by selector:"+g_vars.selector_item_trigger);
231		}
232
233		objInner.trigger(g_vars.trigger_event);
234
235	}
236
237
238
239	/*
240		events
241	*/
242	this.onEvent = function(name, func){
243
244		  validateInited();
245
246	      switch(name){
247			case "change":
248
249				g_objParent.on("uc_change", func);
250
251			break;
252			case "pause":		// do nothing
253			break;
254			default:
255				throw new Error("General API: Wrong event: "+name);
256			break;
257
258		}
259	}
260
261
262	/**
263	* do some action
264	*/
265	this.doAction = function(action, arg1, arg2){
266
267		validateInited();
268
269		if(g_isTypeEvents == true){
270
271			var funcRunAction = getVal(g_options, "func_doAction");
272
273			if(!funcRunAction)
274				throw new Error("Missing option: 'func_doAction' ");
275
276			var response = g_options.func_doAction(action, arg1, arg2);
277
278			return(response);
279		}
280
281		if(g_vars.enableDebug){
282			trace("Action (General): " + action+" arg1: "+arg1+" arg2: "+arg2);
283		}
284
285		switch(action){
286
287			case 'get_num_current':
288
289				var current = getNumCurrent();
290
291				if(g_vars.enableDebug)
292					trace("response: "+current);
293
294				return(current);
295			break;
296			case "get_total_items":
297				
298				var total = getNumTotal();
299				
300				if(g_vars.enableDebug)
301					trace("response: "+total);
302
303				return(total);
304
305			break;
306			case 'change_item':
307				
308				changeItem(arg1);
309
310			break;
311			case "unselect_items":
312				
313				unselectItems();
314				
315			break;
316			case "pause":
317			case "play":
318			break;
319			default:
320				throw new Error("General API: Wrong action: "+action);
321			break;
322		}
323
324	}
325
326	/**
327	 * listen to class change
328	 */
329	function initEvents_listenClassChange(){
330
331		var objItems = getObjItems();
332
333		if(g_vars.enableDebug == true){
334			trace("generalAPI: listen class change: ");
335			trace(objItems);
336		}
337
338		jQuery.each(objItems, function(index, item){
339
340			var objItem = jQuery(item);
341
342			var isSetObserver = objItem.data("uc_set_observer");
343			if(isSetObserver === true){
344				return(true);
345			}
346
347			var observer = new MutationObserver(function(records){
348				
349				runWithTrashold(function(){
350
351					if(g_vars.enableDebug == true)
352						trace("generalAPI: trigger item change");
353
354					g_objParent.trigger("uc_change");
355
356				});
357
358			});
359
360			var config = { attributes: true};
361
362			observer.observe(item, config);
363
364			objItem.data("uc_set_observer", true);
365
366		});
367
368
369	}
370
371
372	/**
373	 * add set active events
374	 */
375	function initEvents_setActive(){
376		
377		if(g_vars.enableDebug == true)
378			trace("start initEvents_setActive")
379
380		var objItems = getObjItems();
381
382		if(objItems.length == 0){
383
384			if(g_vars.enableDebug == true)
385				trace("no items, exit")
386
387			return(false);
388		}
389
390		//activate first item
391
392		var objFirstItem = getItem(0);
393		
394		if(objFirstItem == null){
395
396			if(g_vars.enableDebug == true)
397				trace("empty first item - exit")
398
399			return(false);
400		}
401		
402		
403		if(g_vars.active_code_first_unselected !== true)
404			objFirstItem.addClass(g_vars.class_active);
405		else if(g_vars.enableDebug == true)
406			trace("skip activating first item: g_vars.active_code_first_unselected=true");
407		
408		objItems.on(g_vars.trigger_event, function(event){
409
410			var objItem = jQuery(this);
411
412			//clicked element
413			var objElement = jQuery(event.target);
414			var isLink = objElement.is("a");
415
416			//quit on link inside
417			if(isLink == true && objElement.hasClass(g_vars.class_items) == false){
418
419				return(true);
420			}
421
422			objItems.not(objItem).removeClass(g_vars.class_active);
423
424			objItem.addClass(g_vars.class_active);
425
426			g_objParent.trigger("uc_change");
427
428			event.preventDefault();
429
430		});
431
432
433	}
434
435
436	/**
437	 * init obzerver events
438	 */
439	function initEvents(){
440
441		if(g_vars.enableDebug == true){
442			trace("generalAPI: init events");
443			trace(g_objParent);
444		}
445
446		if(g_vars.listen_class_change == true)
447			initEvents_listenClassChange();
448
449		if(g_vars.add_set_active_code == true){
450
451			initEvents_setActive();
452
453		}
454
455	}
456
457
458	/**
459	 * get element
460	 */
461	this.getElement = function(){
462
463		return(g_objParent);
464	}
465
466	/**
467	 * get api type
468	 */
469	this.getAPIType = function(){
470
471		return("general");
472	}
473
474
475	/**
476	 * init by classes
477	 */
478	function initByClasses(){
479				
480		try{
481			
482			var widgetName = g_objParent.data("widgetname");
483			
484			g_vars.class_items = getVal(g_options, "class_items");
485			
486			if(!g_vars.class_items){
487				
488				var widgetID = g_objParent.attr("id");
489				trace("missing class_items in "+widgetID);
490				trace(g_vars);
491				
492				throw new Error(widgetName +" - missing 'class_items' option");
493			}
494			
495			g_vars.class_active = getVal(g_options, "class_active");
496
497			if(!g_vars.class_active)
498				throw new Error(widgetName +" - missing 'class_active' in options");
499			
500			g_vars.parent_id = g_objParent.attr("id");
501			
502			g_vars.selector_item_trigger = getVal(g_options, "selector_item_trigger");
503
504			g_vars.add_set_active_code = getVal(g_options, "add_set_active_code");
505			
506			g_vars.active_code_first_unselected = getVal(g_options, "active_code_first_unselected");
507			
508			if(g_vars.add_set_active_code === true)
509				g_vars.listen_class_change = false;
510
511		}
512		catch(e){
513
514			trace("ERROR: "+e);
515
516			trace("passed options: ");
517			trace(g_options);
518			throw e;
519		}
520	}
521
522
523
524	/**
525	 * init the api
526	 */
527	this.init = function(objParent, options, isEditor){
528		
529		//not allow to init general api without options
530		if(!options)
531			return(false);
532				
533		g_vars.is_editor = isEditor;
534
535		g_objParent = objParent;
536
537		var connectType = getVal(options, "connect_type");
538		if(connectType == "events")
539			g_isTypeEvents = true;		//events allow to connect own functions
540
541		g_options = options;
542
543		var enableDebug = getVal(options, "trace_debug");
544
545		if(enableDebug == true)
546			g_vars.enableDebug = true;
547		
548		if(g_vars.enableDebug == true){
549			trace("init general api");
550			trace(objParent);
551			trace(options);
552		}
553		
554		if(isEditor == true)
555			g_vars.trigger_event = "ucclick";
556		
557		if(g_isTypeEvents == false)
558			initByClasses();
559
560		g_objParent.data("remote_inited", true);
561
562		if(g_isTypeEvents == false){
563
564			if(g_vars.listen_class_change == true)
565				setTimeout(initEvents, 1000);
566			else
567				initEvents();
568
569			g_objParent.on("uc_ajax_refreshed", function(){
570
571				setTimeout(initEvents,500)
572
573			});
574
575		}
576
577
578		return(true);
579	}
580
581}
582
583
584
585/**
586* remote gallery api class
587*/
588function UERemoteGalleryAPI(){
589
590	var g_api, g_isInited;
591	var g_objParent;
592	var t = this;
593
594	/**
595	* console log some string
596	*/
597	function trace(str){
598		console.log(str);
599	}
600
601	/**
602	* validate that the object is inited
603	*/
604	function validateInited(){
605
606		if(g_isInited == false)
607			throw new Error("The owl carousel API is not inited");
608	}
609
610	/**
611		do some action
612	*/
613	this.doAction = function(action, arg1, arg2){
614
615		validateInited();
616
617		switch(action){
618			case 'get_num_current':
619
620				var current = g_api.getNumCurrent();
621
622				return(current);
623			break;
624			case "get_total_items":
625
626				var total = g_api.getNumItems();
627
628				return(total);
629			break;
630			case 'change_item':
631				
632				if(arg1 < 0)
633					arg1 = 0;
634					
635				g_api.selectItem(arg1);
636				
637			break;
638			case "unselect_items":
639				
640				g_api.selectItem(0);
641				
642			break;
643			case "is_playing":
644
645				var isPlaying = g_api.isPlaying();
646
647				return(isPlaying);
648
649			break;
650			case "pause":
651
652				g_api.stop();
653
654			break;
655			case "play":
656
657				g_api.play();
658			break;
659			default:
660				throw new Error("GALLERY API: Wrong action: "+action);
661			break;
662		}
663
664	}
665
666	/*
667	  events
668	*/
669	this.onEvent = function(name, func){
670
671		  validateInited();
672
673	      switch(name){
674			case "change":
675				g_api.on("item_change", func);
676			break;
677			case "play":
678				g_api.on("play",func);
679			break;
680			case "pause":
681				g_api.on("stop",func);
682			break;
683			default:
684				throw new Error("Gallery API: Wrong event: "+name);
685			break;
686
687		}
688	}
689
690
691	/**
692	 * get element
693	 */
694	this.getElement = function(){
695
696		return(g_objParent);
697	}
698
699
700	/**
701	 * get api type
702	 */
703	this.getAPIType = function(){
704
705		return("gallery");
706	}
707
708
709	/**
710	* init the api
711	*/
712	this.init = function(objParent, options){
713
714		g_api = objParent.data("unitegallery-api");
715		if(!g_api)
716			return(false);
717
718		g_objParent = objParent;
719
720		g_isInited = true;
721
722		return(true);
723	}
724
725
726
727}
728
729
730/**
731* remote carousel api class
732*/
733function UERemoteCarouselAPI(){
734
735	var g_owlCarousel, g_owl, g_isInited;
736	var t = this;
737	var enableDebug = false;
738
739
740	/**
741	* console log some string
742	*/
743	function trace(str){
744		console.log(str);
745	}
746
747	/**
748	* validate that the object is inited
749	*/
750	function validateInited(){
751
752		if(g_isInited == false)
753			throw new Error("The owl carousel API is not inited");
754	}
755
756	/**
757	 * get total items
758	 */
759	function getTotalItems(){
760
761		var total = g_owlCarousel.find(".owl-item:not(.cloned)").length;
762
763		return(total);
764	}
765
766	/**
767	 * reset the autoplay if exists
768	 */
769	function resetAutoplay(){
770
771		if(g_owl.settings.autoplay == false)
772			return(false);
773
774		g_owlCarousel.trigger('stop.owl.autoplay');
775		g_owlCarousel.trigger('play.owl.autoplay');
776
777	}
778
779	/**
780		do some action
781	*/
782	this.doAction = function(action, arg1, arg2){
783
784		validateInited();
785
786		if(enableDebug == true){
787			trace("carousel action: "+action+" "+arg1+" "+arg2);
788		}
789
790		switch(action){
791			case "next":
792
793				g_owlCarousel.trigger('next.owl.carousel');
794			break;
795			case "prev":
796				g_owlCarousel.trigger('prev.owl.carousel');
797			break;
798			case "play":
799
800				g_owlCarousel.trigger('start_autoplay.owl.autoplay');
801
802			break;
803			case "pause":
804
805				g_owlCarousel.trigger('stop.owl.autoplay');
806
807			break;
808			case "is_playing":
809
810				if (g_owl.settings.autoplay == true)
811                    return(true)
812                else
813                    return(false);
814
815			break;
816			case "get_total_items":
817
818				var total = getTotalItems()
819
820				return(total);
821
822			break;
823			case "get_progress_time":
824
825      			var progressTime = g_owl.settings.autoplayTimeout / 1000;
826				return(progressTime);
827
828			break;
829			case "get_modified_progress_time":
830
831      			var progressTime = (g_owl.settings.autoplayTimeout - g_owl.settings.smartSpeed) / 1000;
832				return(progressTime);
833
834			break;
835			case 'get_num_current':
836
837      			var currentItem = g_owl.relative(g_owl.current());
838
839      			if(enableDebug === true){
840      				trace("num current: " + currentItem);
841      			}
842
843      			return(currentItem);
844			break;
845			case "get_total_text":
846
847				var owlTotalItems = g_owlCarousel.find(".owl-item:not(.cloned)").length;
848				if(owlTotalItems.toString().length < 2){
849                    owlTotalItems = "0" + owlTotalItems;
850                   }
851				return(owlTotalItems);
852
853			break;
854            case "get_current_text":
855
856                var owlCurrentItem = g_owl.relative(g_owl.current()) + 1;
857                if(owlCurrentItem.toString().length < 2){
858                    owlCurrentItem = "0" + owlCurrentItem;
859                   }
860				return(owlCurrentItem);
861
862            break;
863			case 'change_item':
864				
865				var total = getTotalItems()
866				var currentItem = g_owl.relative(g_owl.current());
867
868				var slideNum = arg1;
869
870				if(slideNum == currentItem)
871					return(false);
872				
873				if(slideNum >= total)
874					slideNum = (total-1);
875				else
876					if(slideNum < 0)
877						slideNum = 0;
878				
879                g_owlCarousel.trigger('to.owl.carousel', [slideNum, null, true]);
880                
881                resetAutoplay();
882
883			break;
884			case "unselect_items":
885			break;
886			default:
887				throw new Error("Carousel API: Wrong action: "+action);
888			break;
889		}
890
891	}
892
893
894	/*
895		events
896	*/
897	this.onEvent = function(name, func){
898
899		  validateInited();
900
901          switch(name){
902			case "play":
903
904				g_owlCarousel.on("play_autoplay.owl.carousel", func);
905
906			break;
907			case "pause":
908
909				g_owlCarousel.on("stop_autoplay.owl.carousel", func);
910
911			break;
912			case "change":
913
914				g_owlCarousel.on("changed.owl.carousel", func);
915
916			break;
917			case "transition_start":
918
919				g_owlCarousel.on("translate.owl.carousel", func);
920
921			break;
922			case "transition_end":
923
924				g_owlCarousel.on("translated.owl.carousel", func);
925
926			break;
927			case "refreshed":
928
929				g_owlCarousel.on("refreshed.owl.carousel", func);
930
931			break;
932			default:
933				console.error("Carousel API: Wrong event: "+name);
934				throw new Error("Carousel API: Wrong event: "+name);
935			break;
936
937		}
938	}
939
940	/**
941	 * get api type
942	 */
943	this.getAPIType = function(){
944
945		return("carousel");
946	}
947
948	/**
949	 * get the element
950	 */
951	this.getElement = function(){
952
953		return(g_owlCarousel);
954	}
955
956
957	/**
958	* init the api
959	*/
960	this.init = function(objParent){
961
962		if(objParent.hasClass("owl-carousel") == false)
963			throw new Error("owl-carousel class not found");
964
965		g_owlCarousel = objParent;
966
967		g_owl = g_owlCarousel.data("owl.carousel");
968
969		if(!g_owl)
970			return(false);
971
972		g_isInited = true;
973
974		return(true);
975
976	}
977
978}
979
980/**
981 * sync object
982 */
983function UESyncObject(){
984
985	var g_objApis = {};
986	var g_groupName, g_objIDs;
987	var t = this;
988
989	var g_vars = {
990		is_editor:false,
991		is_editor_func_started:false,
992		show_debug:false
993	};
994
995	/**
996	* console log some string
997	*/
998	function trace(str){
999		console.log(str);
1000	}
1001
1002
1003
1004	/**
1005	 * validate api, that they match the existing by number of items
1006	 */
1007	function validate(objAPI){
1008
1009		if(g_objApis.length == 0)
1010			return(false);
1011				
1012		var numItems = objAPI.doAction("get_total_items");
1013
1014		//check with first existing api number of items
1015		for(var elID in g_objApis){
1016			
1017			var firstExistingAPI = g_objApis[elID];
1018
1019			var numItemsExisting = firstExistingAPI.doAction("get_total_items");
1020			
1021			if(numItemsExisting !== numItems){
1022				
1023				var objElement = objAPI.getElement();
1024				var elementID = objElement.attr("id");
1025				
1026				trace("Sync failed "+elementID+" has "+numItems+" items and "+elID+" has "+numItemsExisting+ " items");
1027				
1028				throw new Error("Sync failed, number of items should be the same. Now it's "+numItems+" and "+numItemsExisting);
1029			}
1030			
1031			return(false);
1032		}
1033
1034
1035	}
1036
1037
1038	/**
1039	 * set options
1040	 */
1041	this.setOptions = function(groupName, isEditor){
1042
1043		if(isEditor === true)
1044			g_vars.is_editor = true;
1045
1046		if(!g_groupName)
1047			g_groupName = groupName;
1048
1049	}
1050
1051
1052	/**
1053	 * get api parent id
1054	 */
1055	function getElementID(objAPI){
1056
1057		var objElement = objAPI.getElement();
1058
1059		var elementID = objElement.attr("id");
1060
1061		return(elementID);
1062	}
1063
1064
1065	/**
1066	 * get all ips except the given
1067	 */
1068	function mapAPIs(func, objElement){
1069		
1070		if(typeof ucRemoteDebugEnabled != "undefined")
1071			g_vars.show_debug = true;
1072
1073		var elementID = null;
1074
1075		if(objElement){
1076
1077			var elementID = objElement.attr("id");
1078
1079			if(g_objApis.length == 1)
1080				return(null);
1081		}
1082
1083		for(var elID in g_objApis){
1084
1085			var api = g_objApis[elID];
1086
1087			//except if exists
1088			if(elementID && elID == elementID)
1089					continue;
1090
1091			func(api);
1092
1093		}
1094
1095	}
1096
1097
1098	/**
1099	 * activate change command on all other apis
1100	 */
1101	function onItemChange(objAPI){
1102		
1103		var numCurrent = objAPI.doAction("get_num_current");
1104		
1105		var objElement = objAPI.getElement();
1106
1107		if(g_vars.show_debug == true){
1108
1109			trace("sync onchange: " + numCurrent);
1110			trace(objElement);
1111			trace(g_objApis);
1112		}
1113		
1114		mapAPIs(function(api){
1115						
1116			if(numCurrent < 0)
1117				api.doAction("unselect_items");
1118			else
1119				api.doAction("change_item", numCurrent);
1120			
1121		}, objElement);
1122
1123	}
1124
1125	/**
1126	 * on pause - pause others as well
1127	 */
1128	function onPause(objAPI){
1129
1130		var objElement = objAPI.getElement();
1131
1132		mapAPIs(function(api){
1133
1134			api.doAction("pause");
1135
1136		}, objElement);
1137
1138
1139	}
1140
1141
1142	/**
1143	 * trigger some action
1144	 */
1145	function trigger(action, params){
1146
1147		var realAction = "uc_remote_sync_"+g_groupName+"_action_"+action;
1148
1149		jQuery("body").trigger(realAction, params);
1150	}
1151
1152
1153	/**
1154	 * on event
1155	 */
1156	this.on = function(action, func){
1157
1158		var realAction = "uc_remote_sync_"+g_groupName+"_action_"+action;
1159
1160		jQuery("body").on(realAction, func);
1161
1162	}
1163
1164
1165	/**
1166	 * get debug text
1167	 */
1168	this.getDebugText = function(objElement){
1169
1170		var text = "sync group: <b>" + g_groupName+"</b>, ";
1171
1172		var textWidgets = "";
1173
1174		mapAPIs(function(api){
1175
1176			var objElement = api.getElement();
1177			var widgetName = objElement.data("widgetname");
1178			var widgetID = objElement.attr("id");
1179
1180			if(textWidgets)
1181				textWidgets += ", ";
1182
1183			textWidgets += "<a href='#"+widgetID+"' style='color:green;text-decoration:underline'><b>
1183" + widgetName + "</b></a>";
1184
1185		}, objElement);
1186
1187		if(textWidgets)
1188			text += "sync with: " + textWidgets;
1189
1190		return(text);
1191	}
1192
1193
1194	/**
1195	 * remove deleted from page APIs
1196	 */
1197	function removeDeletedAPIs(){
1198
1199		var objAPIsNew = {};
1200
1201		mapAPIs(function(api){
1202
1203			var elementID = getElementID(api);
1204			var objElement = jQuery("#"+elementID);
1205
1206			if(objElement.length == 0)
1207				return(false);
1208
1209			var parent = objElement.parent();
1210
1211			objAPIsNew[elementID] = api;
1212
1213		});
1214
1215		g_objApis = objAPIsNew;
1216
1217	}
1218
1219
1220	/**
1221	 * on editor check
1222	 */
1223	function onEditorCheck(){
1224
1225		removeDeletedAPIs();
1226
1227		trigger("update_debug", g_groupName);
1228
1229	}
1230
1231	/**
1232	 * get group name
1233	 */
1234	this.getGroupName = function(){
1235
1236		return(g_groupName);
1237	}
1238
1239	/**
1240	 * add widget to sync object
1241	 */
1242	this.addAPI = function(objAPI){
1243		
1244		
1245		var id = getElementID(objAPI);
1246		
1247		if(g_objApis.hasOwnProperty(id))
1248			return(false);
1249
1250		g_objApis[id] = objAPI;
1251
1252		if(g_vars.is_editor == true)
1253			removeDeletedAPIs();
1254
1255		validate(objAPI);
1256
1257
1258		//debug
1259		var objElement = objAPI.getElement();
1260
1261		//add debug
1262		trigger("update_debug", g_groupName);
1263
1264		//set events
1265		objAPI.onEvent("change", function(){
1266
1267			onItemChange(objAPI);
1268
1269		});
1270
1271		//sync objects pause
1272
1273		objAPI.onEvent("pause", function(){
1274
1275			onPause(objAPI);
1276		});
1277
1278
1279		if(g_vars.is_editor == true && g_vars.is_editor_func_started == false){
1280
1281			setInterval(onEditorCheck, 700);
1282			g_vars.is_editor_func_started = false;
1283		}
1284
1285
1286	}
1287
1288	/**
1289	 * get all elements
1290	 */
1291	this.getElements = function(exceptID){
1292
1293		if(!g_objApis)
1294			return(null);
1295
1296		var arrElements = [];
1297
1298		//check with first existing api number of items
1299		for(var elID in g_objApis){
1300
1301			if(exceptID && exceptID == elID)
1302				continue;
1303
1304			var objApi = g_objApis[elID];
1305
1306			var objElement = objApi.getElement();
1307
1308			arrElements.push(objElement);
1309		}
1310
1311		if(arrElements.length == 0)
1312			return(null);
1313
1314		return(arrElements);
1315	}
1316
1317}
1318
1319/**
1320* ---------------------------------------------------
1321* remote widget api class
1322*/
1323function UERemoteWidgets(){
1324
1325	var g_objParent, g_objWidget, g_parentID;
1326	var g_api, g_objSync, g_remoteConnection = window.ueRemoteConnection;
1327	var t = this;
1328
1329	var g_vars = {
1330		is_inited:false,
1331		funcOnInit:null,
1332		is_editor:null,
1333		widget_id:null,
1334		init_options:null,
1335		is_parent_mode: false,
1336		syncid:null,
1337		options_api:null,
1338		show_connection_debug:false,
1339		debug_show_ids:false,
1340		debug_show_widget: "",
1341		trace_debug:false	//debug
1342	};
1343
1344	var g_types = {
1345		CAROUSEL:"carousel",
1346		GALLERY:"gallery",
1347		GENERAL:"general"
1348	};
1349
1350
1351	/**
1352	* console log some string
1353	*/
1354	function trace(str){
1355		console.log(str);
1356	}
1357
1358	/**
1359	 * get object property
1360	 */
1361	function getVal(obj, name, defaultValue){
1362
1363		return window.ueRemoteConnection.getVal(obj, name, defaultValue);
1364	}
1365
1366
1367
1368	function _______INIT_________(){}
1369
1370	/**
1371	* init widget
1372	*/
1373	function initWidget(widgetID){
1374
1375		g_objWidget = jQuery("#"+widgetID);
1376		if(g_objWidget.length == 0)
1377			throw new Error("Widget not found by id: "+widgetID);
1378
1379		g_vars.widget_id = widgetID;
1380
1381		var forceID = getVal(g_vars.init_options, "force_parentid");
1382
1383		if(forceID)
1384			g_parentID = forceID;
1385		else
1386			g_parentID = g_objWidget.data("parentid");
1387
1388		if(!g_parentID)
1389			throw new Error("Parent controlled ID not set");
1390
1391	}
1392
1393	/**
1394	* get controlled parent type
1395	*/
1396	function getParentType(){
1397
1398		if(!g_objParent || g_objParent.length == 0)
1399			throw new Error("getParentType: no parent found");
1400
1401		if(g_objParent.hasClass("owl-carousel"))
1402			return(g_types.CAROUSEL);
1403
1404		var dataType = g_objParent.data("remote-type");
1405
1406		switch(dataType){
1407			case "gallery":
1408				return g_types.GALLERY;
1409			break;
1410		}
1411
1412
1413		return(g_types.GENERAL);
1414	}
1415
1416
1417	/**
1418	 * get offsets distance
1419	 */
1420	function getOffsetsDistance(offset1, offset2){
1421
1422	  var dx = offset2.left-offset1.left;
1423	  var dy = offset2.top-offset1.top;
1424
1425	  return Math.sqrt(dx*dx+dy*dy);
1426	}
1427
1428
1429	/**
1430	 * get closest object by offset
1431	 */
1432	function getClosestByOffset(objParents, objElement){
1433
1434		var objClosest = null;
1435		var minDiff = 1000000;
1436
1437		var elementOffset = objElement.offset();
1438
1439		if(g_vars.trace_debug){
1440			trace("Widget Offset: ");
1441			trace(elementOffset);
1442		}
1443
1444		jQuery.each(objParents, function(index, parent){
1445
1446			var objParent = jQuery(parent);
1447			var parentOffset = objParent.offset();
1448
1449			if(parentOffset.top == 0){
1450
1451				var firstParent = getWidgetContainer(objParent);
1452				var parentOffset = firstParent.offset();
1453
1454			}
1455
1456			var distance = getOffsetsDistance(parentOffset, elementOffset);
1457
1458			if(g_vars.trace_debug){
1459				trace("Parent offset: ");
1460				trace(objParent);
1461				trace(parentOffset);
1462				trace("distance: " + distance);
1463			}
1464
1465			if(distance < minDiff){
1466				minDiff = distance;
1467				objClosest = objParent;
1468			}
1469
1470		});
1471
1472		return(objClosest);
1473	}
1474
1475	/**
1476	 * filter parents by section
1477	 */
1478	function filterParentsBySection(objParents, objElement){
1479
1480		var objSection = objElement.closest(".elementor-top-section");
1481
1482		if(objSection.length == 0)
1483			return(objParents);
1484
1485		var section = objSection[0];
1486
1487		var objFiltered = objParents.filter(function(index, parent){
1488
1489			var isContains = jQuery.contains(section, parent);
1490
1491			return isContains;
1492		});
1493
1494		if(objFiltered.length)
1495			return(objFiltered);
1496
1497		return(objParents);
1498	}
1499
1500
1501	/**
1502	 * detect closest parent
1503	 */
1504	function detectClosestParent(objParents){
1505		
1506		var objContainer = jQuery("body");
1507		
1508		//twick for tempalte switcher
1509		var objTemplateHolder = g_objWidget.closest(".uc-template-holder");
1510		
1511		if(objTemplateHolder.length)
1512			objContainer = objTemplateHolder;
1513		
1514		if(!objParents)
1515			var objParents = objContainer.find(".uc-remote-parent").not(g_objWidget);
1516		
1517		if(g_vars.trace_debug){
1518			trace("detect closest start. group:");
1519			trace(objParents);
1520		}
1521		
1522		var numParents = objParents.length;
1523
1524		if(numParents == 0)
1525			return(null);
1526
1527		if(numParents == 1)
1528			return(objParents);
1529
1530		//filter by auto
1531
1532		if(g_vars.trace_debug)
1533			trace("filter auto");
1534
1535		var objParentsFiltered = objParents.filter("[data-remoteid='"+g_parentID+"']");
1536
1537		if(objParentsFiltered.length == 1)
1538			return(objParentsFiltered);
1539
1540		//find by offset
1541
1542		if(g_vars.trace_debug){
1543			trace("filter by section");
1544		}
1545
1546		var objParents = filterParentsBySection(objParents, g_objWidget);
1547
1548		if(g_vars.trace_debug){
1549			trace(objParents);
1550		}
1551
1552		if(objParents.length == 1)
1553			return(objParents);
1554
1555		if(g_vars.trace_debug)
1556			trace("get closest by parent");
1557
1558		var objClosest = getClosestByOffset(objParents, g_objWidget);
1559
1560		if(objClosest)
1561			return(objClosest);
1562
1563		if(g_vars.trace_debug)
1564			trace("get first");
1565
1566		var firstParent = jQuery(objParentsFiltered[0]);
1567
1568
1569		return(firstParent);
1570	}
1571
1572	/**
1573	 * set parent object
1574	 */
1575	function setParentObject(){
1576
1577		var objForceParent = getVal(g_vars.init_options, "force_parent_obj");
1578
1579		var widgetID = g_objWidget.attr("id");
1580		
1581		if(g_vars.trace_debug)
1582			trace("start set parent for: "+widgetID+", parent name: "+g_parentID);
1583
1584		if(objForceParent){
1585
1586			g_objParent = objForceParent;
1587
1588			if(g_vars.trace_debug){
1589				trace("set force parent");
1590				trace(g_objParent);
1591			}
1592
1593			return(true);
1594		}
1595		
1596		
1597		if(!g_parentID)
1598		   throw new Error("Parent controller ID not found");
1599
1600		if(!g_objParent || g_objParent.length == 0){
1601
1602			if(g_parentID == "auto"){
1603
1604				if(g_vars.trace_debug){
1605					trace("auto detect selected");
1606				}
1607
1608				g_objParent = detectClosestParent();
1609
1610				if(g_vars.trace_debug){
1611					trace("detect closest");
1612					trace(g_objParent);
1613				}
1614
1615				if(!g_objParent)
1616					throw new Error("Can't detect remote parent");
1617
1618			}
1619			else{
1620
1621				var objParents = jQuery(".uc-remote-parent[data-remoteid='"+g_parentID+"']").not(g_objWidget);
1622
1623				if(g_vars.trace_debug)
1624					trace("Detect from group: "+g_parentID);
1625
1626				g_objParent = detectClosestParent(objParents);
1627
1628				if(g_vars.trace_debug){
1629					trace("detected from group");
1630					trace(g_objParent);
1631				}
1632				
1633				if(!g_objParent || g_objParent.length == 0){
1634					
1635				   //set another try
1636				   var isAnotherTry = g_objWidget.data("uc_parent_detect_another_try");
1637				   if(!isAnotherTry){
1638					   g_objWidget.data("uc_parent_detect_another_try", true);
1639					   
1640					   if(g_vars.trace_debug)
1641						   trace("Set another try for parent detect");
1642					   
1643					   return(false);
1644				   }
1645				
1646				   throw new Error("Parent widget with remote name: '"+g_parentID+"' not found");
1647				}
1648				
1649			}
1650
1651		}
1652
1653		if(g_objParent && g_objParent.length > 1){
1654			g_objParent = jQuery(g_objParent[0]);
1655		}
1656
1657		if(g_vars.trace_debug == true){
1658
1659			var parentID = g_objParent.attr("id");
1660			var widgetID = g_objWidget.attr("id");
1661			
1662			trace("widget: "+widgetID+" connected to: "+parentID);
1663
1664		}
1665
1666		if(!g_objParent || g_objParent.length == 0)
1667			  throw new Error("Remote parent not found");
1668		
1669		return(true);
1670	}
1671
1672
1673	/**
1674	 * init api variable
1675	 */
1676	function initAPI(){
1677		
1678		if(g_vars.trace_debug == true){
1679			trace("start init api function");
1680		}
1681
1682		//set type and related objects
1683		if(!g_api){
1684
1685			var parentType = getParentType();
1686
1687
1688			if(!parentType){
1689				trace(g_objParent);
1690				throw new Error("No parent type found");
1691			}
1692
1693			if(g_vars.trace_debug == true){
1694
1695				trace("init api: " + parentType);
1696				trace(g_objParent);
1697			}
1698
1699			//init the api
1700			switch(parentType){
1701				case g_types.CAROUSEL:
1702					g_api = new UERemoteCarouselAPI();
1703				break;
1704				case g_types.GENERAL:
1705
1706					g_api = new UERemoteGeneralAPI();
1707
1708				break;
1709				case g_types.TABS:
1710
1711					//g_api = new UERemoteTabsAPI();
1712					g_api = new UERemoteGeneralAPI();
1713
1714				break;
1715				case g_types.GALLERY:
1716
1717					g_api = new UERemoteGalleryAPI();
1718
1719				break;
1720				default:
1721					throw new Error("Wrong parent type: "+parentType);
1722				break;
1723			}
1724
1725		}
1726
1727		var optionsFromData = g_objParent.data("uc-remote-options");
1728
1729		var isEditor = isInsideEditor();
1730
1731		if(optionsFromData)
1732			g_vars.options_api = optionsFromData;
1733		
1734		var optionsAPI = {};
1735		
1736		var optionsAPI = jQuery.extend({},g_vars.options_api);
1737		
1738		if(jQuery.isEmptyObject(g_vars.options_api) == false)
1739			jQuery.extend({},optionsAPI, g_vars.options_api);
1740			
1741		if(g_vars.trace_debug == true){
1742			
1743			if(optionsAPI)
1744				trace(optionsAPI);
1745				
1746			optionsAPI["trace_debug"] = true;			
1747		}
1748		
1749		var isInited = g_api.init(g_objParent, g_vars.options_api, isEditor);
1750		
1751		if(g_vars.trace_debug == true){
1752			trace("inited: " + isInited);
1753		}
1754
1755		return(isInited);
1756	}
1757
1758
1759	/**
1760	*	init parent
1761	*/
1762	function initParent(){
1763		
1764		var isParentSet = setParentObject();
1765		
1766		if(isParentSet == false)
1767			return(false);
1768		
1769		var isInited = initAPI();
1770
1771		return(isInited);
1772	}
1773
1774
1775	/**
1776		init global helper function
1777	*/
1778	function initGlobal(widgetID, func){
1779
1780		if(!g_objWidget)
1781			initWidget(widgetID);
1782		
1783		//init the debug related
1784		
1785		var isDebug = g_objWidget.data("debug");
1786		if(isDebug === true || typeof ucRemoteDebugEnabled != "undefined"){
1787			
1788			g_vars.trace_debug = true;
1789			g_vars.show_connection_debug = true;
1790			
1791		}
1792		
1793		if(g_vars.trace_debug){
1794			if(!widgetID)
1795				widgetID = g_objWidget.attr("id");
1796			
1797			trace("Initing Remote Widget: "+widgetID);
1798		}
1799		
1800		g_vars.is_inited = initParent();
1801
1802		if(g_vars.is_inited == false){
1803
1804			if(!g_objParent){
1805				
1806				setTimeout(func, 1000);	//try onWidgetInit in a second again
1807				
1808			}else{
1809				
1810				if(g_vars.trace_debug == true){
1811
1812					trace(g_objParent);
1813					trace("set object ready event");	//onWidgetInit
1814				}
1815				
1816				g_objParent.on("uc-object-ready", func);
1817				
1818			}
1819			
1820
1821		}
1822	}
1823
1824
1825	/**
1826	* set action, bind to some object
1827	* objElement can be jQuery object or selector
1828	*/
1829	this.setAction = function(action, objElement, allowMultiple){
1830		
1831		if(g_vars.trace_debug == true){
1832			trace("set action: "+action);
1833		}
1834
1835		if(g_vars.is_inited == false)
1836			throw new Error("Widget not inited");
1837
1838		if(typeof objElement == "string"){
1839		  var selector = objElement;
1840		   objElement = g_objWidget.find(objElement);
1841		   if(objElement.length == 0)
1842				throw new Error("Remote '"+action+"' action error: element: "+selector+" not found");
1843		}
1844
1845		if(!objElement || objElement.length == 0)
1846			throw new Error("Element not inited");
1847
1848		if(!g_api)
1849			throw new Error("API not inited!");
1850
1851		//avoid double action
1852		var linkedAction = objElement.data("uc-action");
1853
1854		if(allowMultiple !== true)
1855			if(linkedAction){
1856				
1857				trace("not allow multiple action: "+action);
1858				
1859				return(false);
1860			}
1861
1862		objElement.data("uc-action", action);
1863
1864		objElement.on("click",function(){
1865
1866			var objElement = jQuery(this);
1867
1868			if(objElement.hasClass("uc-disabled"))
1869				return(true);
1870
1871			t.doAction(action);
1872
1873		});
1874
1875	}
1876
1877
1878	/**
1879	 * run this function after the widget is ready to use
1880	 */
1881	function onWidgetReady(){
1882
1883		checkWidgetDebug();
1884
1885		var isEditorMode = isInsideEditor();
1886		
1887		//in editor mode check debug every second
1888
1889		if(isEditorMode == true){
1890
1891			hideErrorOnWidget();
1892
1893			setInterval(checkWidgetInsideEditor, 700);
1894		}
1895
1896
1897	}
1898
1899
1900	function _______TEXT_ON_WIDGET_________(){}
1901
1902
1903	/**
1904	 * hide error on widget
1905	 */
1906	function hideErrorOnWidget(){
1907
1908		if(!g_objWidget || g_objWidget.length == 0)
1909			return(false);
1910
1911		var objParent = getWidgetContainer(g_objWidget);
1912
1913		//don't hide if no message
1914
1915		var objError = objParent.find('.uc-remote-error');
1916
1917		if(objError.length == 0)
1918			return(false);
1919
1920		if(objError.is(":visible") == false)
1921			return(false);
1922
1923		objError.hide();
1924
1925		g_objWidget.css({
1926			"border" : "none"
1927		});
1928
1929		//try to set the debug if avaliable
1930		checkWidgetDebug();
1931
1932	}
1933
1934	/**
1935	 * get widget container
1936	 */
1937	function getWidgetContainer(objWidget){
1938
1939		var objParent = objWidget.parents(".elementor-widget-container");
1940		if(objParent.length == 0)
1941			objParent = objWidget.parent();
1942
1943		return(objParent);
1944	}
1945
1946
1947	/**
1948	 * add error message div on the widget div
1949	 *
1950	 */
1951	function addTextDiv(objWidget, type){
1952
1953		var objParent = getWidgetContainer(objWidget);
1954
1955		var isDebug = (type == "debug");
1956
1957		var className = "uc-remote-error";
1958		if(isDebug == true)
1959			className = "uc-remote-debug";
1960
1961		var divText = "<div class='"+className+"'></div>";
1962		objParent.append(divText);
1963
1964		var objError = objParent.find('.'+className+'');
1965
1966		var css = {
1967				"position":"absolute",
1968				"color":"red",
1969				"top":"-30px",
1970				"left":"0px",
1971				"z-index":"999999",
1972				"background-color":"#ffffff"
1973		};
1974
1975		if(isDebug == true){
1976			css["color"] = "green";
1977			css["z-index"] = "999998";
1978		}
1979
1980		//fix position for bg
1981		var objParentsBG = objParent.parents(".unlimited-elements-background-overlay");
1982		if(objParentsBG.length){
1983			css["top"] = "0px";
1984		}
1985
1986		objError.css(css);
1987
1988		var objError = objParent.find('.'+className+'');
1989
1990		return(objError);
1991	}
1992
1993	/**
1994	 * display some error on widget interface
1995	 */
1996	function displayTextOnWidget(objWidget, message, type){
1997
1998		var isDebug = (type == "debug");
1999
2000		var className = "uc-remote-error";
2001		if(isDebug == true)
2002			className = "uc-remote-debug";
2003
2004		var objParent = getWidgetContainer(objWidget);
2005
2006		objText = objParent.find("."+className);
2007
2008		//add error div if missing. pause error in editor
2009		//second time the div will be not empty and it will show the message
2010		if(objText.length == 0){
2011
2012			objText = addTextDiv(objWidget, type);
2013
2014			if(isDebug == false){
2015
2016				var isInEditor = isInsideEditor();
2017
2018				if(isInEditor == true){
2019
2020					setTimeout(function(){
2021						displayTextOnWidget(objWidget, message, type);
2022					},2000);
2023
2024					return(false);
2025				}
2026
2027			}
2028
2029		}
2030
2031		//add the error border
2032		if(isDebug == false){
2033
2034			objWidget.css({
2035				"border" : "2px solid red",
2036				"position" : "relative"
2037			});
2038
2039		}
2040
2041		objText.show();
2042		objText.html(message);
2043
2044	}
2045
2046
2047	/**
2048	 * display error message
2049	 */
2050	function displayErrorMessage(message){
2051
2052		if(typeof g_ucRemoteHideErrors !== "undefined" && g_ucRemoteHideErrors === true){
2053		
2054			trace("UE Remote Error: "+message);
2055			
2056			return(false);
2057		}
2058		
2059	
2060		if(g_vars.is_parent_mode == false){
2061
2062			if(g_objWidget && g_objWidget.length)
2063				displayTextOnWidget(g_objWidget, message,"error");
2064
2065		}else{
2066
2067			displayTextOnWidget(g_objParent, message, "error");
2068
2069		}
2070		
2071		//console.log("UE Remote Error: "+message);
2072		//console.log(message);
2073
2074	}
2075
2076	function _______DEBUG_________(){}
2077
2078
2079	/**
2080	 * return if the debug is active
2081	 */
2082	function isDebugActive(objWidget){
2083
2084		if(!objWidget)
2085			objWidget = g_objWidget;
2086
2087		var isActive = objWidget.data("debug_active");
2088
2089		if(isActive === true)
2090			return(true);
2091
2092		return(false);
2093	}
2094
2095
2096	/**
2097	 * remove debug visual from the widget
2098	 */
2099	function removeDebugVisual(objWidget){
2100
2101		if(!objWidget)
2102			objWidget = g_objWidget;
2103
2104		g_objWidget.data("debug_active", false);
2105
2106		g_objWidget.css({
2107			"border-style":"none"
2108		});
2109
2110	}
2111
2112
2113	/**
2114	 * set debug visual
2115	 */
2116	function setDebugVisual(color, objWidget){
2117
2118		if(!objWidget)
2119			objWidget = g_objWidget;
2120
2121		objWidget.data("debug_active", true);
2122
2123		objWidget.css({
2124			"border-style":"solid",
2125			"border-width":"3px",
2126			"border-color":color
2127		});
2128
2129	}
2130
2131	/**
2132	 * check if parent debug is active
2133	 */
2134	function isParentDebugActive(objParent){
2135
2136		var dataDebug = objParent.data("debug");
2137		var isDebug = (dataDebug === true);
2138
2139		return(isDebug);
2140	}
2141
2142
2143	/**
2144	 * check widget debug work
2145	 */
2146	function checkWidgetDebugWork(objWidget, objParent){
2147
2148		if(!objWidget)
2149			objWidget = g_objWidget;
2150
2151		if(!objParent)
2152			objParent = g_objParent;
2153
2154		var isDebug = isParentDebugActive(objParent);
2155
2156		var isActive = isDebugActive(objWidget);
2157
2158		/*
2159		trace("check! "+isActive+" "+isDebug);
2160		trace(objParent);
2161		trace(objWidget);
2162		*/
2163
2164		//remove debug if active but no need
2165
2166		if(isDebug == false){
2167
2168			if(isActive == true)
2169				removeDebugVisual(objWidget);
2170
2171			return(false);
2172		}
2173
2174		//add debug is not in debug mode
2175
2176		if(isActive == false){
2177
2178			//get parent color
2179			var color = addParentDebug(objParent);
2180			setDebugVisual(color, objWidget);
2181
2182		}
2183
2184
2185	}
2186
2187	/**
2188	 * check and put debug connection
2189	 */
2190	function checkDebugConnectionText(){
2191
2192		if(!g_objWidget)
2193			return(false);
2194
2195		if(g_vars.show_connection_debug == false)
2196			return(false);
2197
2198		if(!g_objParent || g_objParent.length == 0)
2199			throw new Error("Not conneted to no parent");
2200
2201		var widgetName = g_objParent.data("widgetname");
2202		var widgetID = g_objParent.attr("id");
2203
2204		var text = "connected to <a href='#"+widgetID+"' style='color:green;text-decoration:underline'><b>" + widgetName + "</b></a>";
2205		
2206		displayTextOnWidget(g_objWidget, text, "debug");
2207
2208	}
2209
2210
2211	/**
2212	 * check widget debug
2213	 */
2214	function checkWidgetDebug(){
2215
2216		var noDebugCheck = getVal(g_vars.init_options, "no_debug_check");
2217
2218		if(noDebugCheck === true)
2219			return(false);
2220
2221		//get debug color
2222		if(!g_objParent || g_vars.is_inited == false){
2223			removeDebugVisual();
2224			return(false);
2225		}
2226
2227		checkWidgetDebugWork();
2228
2229		checkDebugConnectionText();
2230
2231	}
2232
2233	/**
2234	 * on api event
2235	 */
2236	this.onEvent = function(name, func){
2237		g_api.onEvent(name,func);
2238	}
2239
2240
2241	/**
2242	 * change item by action (0 - total-1)
2243	 */
2244	function changeItemByAction(dir){
2245		
2246		var current = t.doAction("get_num_current");
2247		var total = t.doAction("get_total_items");
2248		
2249		switch(dir){
2250			case "next":
2251
2252				var num = current+1;
2253				if(num >= total )
2254					num = 0;
2255
2256			break;
2257			case "prev":
2258
2259				var num = current-1;
2260				if(num < 0)
2261					num = total-1;
2262				
2263			break;
2264			default:
2265				throw new Error("wrong direction type: "+dir);
2266			break;
2267		}
2268		
2269		
2270		t.doAction("change_item", num);
2271
2272	}
2273
2274
2275	/**
2276	 * do api action
2277	 */
2278	this.doAction = function(action, arg1, arg2){
2279
2280		if(g_vars.trace_debug){
2281			trace("Do Action: ");
2282			trace(action+ " "+arg1+" "+arg2);
2283		}
2284		
2285		if(!g_api){
2286			if(g_vars.trace_debug)
2287				trace("empty g_api, exit");
2288			
2289			return(false);
2290		}
2291		
2292		switch(action){
2293			case "prev":
2294			case "next":
2295
2296				var apiType = g_api.getAPIType();
2297
2298				if(apiType == "carousel"){
2299
2300					g_api.doAction(action);
2301					
2302					return(false);
2303				}
2304				
2305				changeItemByAction(action);
2306				return(false);
2307			break;
2308		}
2309
2310		var response = g_api.doAction(action, arg1, arg2);
2311		
2312		if(g_vars.trace_debug){
2313			trace("Response: ");
2314			trace(response);
2315		}
2316
2317
2318		return(response);
2319	}
2320
2321	/**
2322	 * add the parent some debug color
2323	 */
2324	function addParentDebug(objParent){
2325
2326		if(!objParent)
2327			objParent = g_objParent;
2328
2329		var color = g_objParent.data("uc-debug-color");
2330		if(color)
2331			return(color);
2332
2333		var objBody = jQuery("body");
2334		var dataColors = "uc-remote-debug-colors";
2335
2336		var objColors = objBody.data(dataColors);
2337
2338		if(!objColors){
2339			objColors = ["#ffeb00","blue","#808000","#d1e231","#01796f","#8e4585","#ff33cc","#436b95","#eaa221","#b86d29"];
2340		}
2341
2342		var color = objColors.pop();
2343
2344		g_objParent.data("uc-debug-color", color);
2345		objBody.data(dataColors, objColors);
2346
2347		g_objParent.css("border","3px solid "+color);
2348
2349		return(color);
2350	}
2351
2352
2353	/**
2354	 * update sync debug
2355	 */
2356	function updateSyncDebug(event, syncID){
2357
2358		//if show id's disable other debug
2359		if(g_vars.debug_show_ids == true)
2360			return(false);
2361
2362		try{
2363
2364			if(syncID != g_vars.syncid){
2365
2366				var name = g_objParent.data("widgetname");
2367				throw new Error("Wrong sync group mishmash "+g_vars.syncid+" and " + syncID);
2368			}
2369
2370			var debugText = g_objSync.getDebugText(g_objParent);
2371
2372			if(!debugText)
2373				return(false);
2374
2375			displayTextOnWidget(g_objParent, debugText, "debug");
2376
2377		}catch(error){
2378
2379			displayErrorMessage(error);
2380
2381		}
2382
2383	}
2384
2385
2386	function _______EDITOR_RELATED_________(){}
2387
2388	
2389	/**
2390	 * check if inside editor
2391	 */
2392	function isInsideEditor(){
2393		
2394		if(g_vars.is_editor !== null)
2395			return g_vars.is_editor;
2396		
2397		//check for gutenberg
2398		
2399		if(typeof g_ucAdmin !== "undefined"){
2400			g_vars.is_editor = true;
2401			return(true);
2402		}
2403		
2404		// check for elementor
2405		if (window.self !== window.top && typeof window.parent.elementor !== "undefined") {
2406			
2407			g_vars.is_editor = true;
2408
2409			return true;
2410		}
2411				
2412		g_vars.is_editor = false;
2413
2414		return false;
2415	}
2416
2417	/**
2418	 * reset the settings
2419	 */
2420	function resetSettingsInsideEditor(){
2421
2422		g_objParent = null;
2423		g_api = null;
2424		g_vars.is_inited = false;
2425
2426	}
2427
2428
2429	/**
2430	 * check widget inside editor
2431	 */
2432	function checkWidgetInsideEditor(){
2433				
2434		//check for disconnect
2435		try{
2436
2437			hideErrorOnWidget();
2438
2439			if(g_vars.is_inited == true){
2440
2441				if(g_objParent.is(":hidden")){
2442
2443					//disconnect
2444					resetSettingsInsideEditor();
2445				}
2446
2447			}else{
2448
2449				//check for connect
2450				g_vars.is_inited = initParent();
2451
2452				if(g_vars.is_inited == true){
2453
2454					g_vars.funcOnInit();
2455				}
2456				else
2457				if(g_vars.is_inited == false){
2458
2459					g_objParent.on("uc-object-ready", function(){
2460
2461						g_vars.is_inited = true;
2462						g_vars.funcOnInit();
2463
2464					});
2465				}
2466
2467			}
2468
2469			checkWidgetDebug();
2470
2471		}catch(message){
2472
2473			displayErrorMessage(message);
2474
2475			return(false);
2476		}
2477
2478
2479	}
2480
2481
2482
2483	/**
2484	* on widget init
2485	*/
2486	this.onWidgetInit = function(widgetID, func, options){
2487		
2488		try{
2489			
2490			if(g_vars.is_inited == true)
2491				return(false);
2492			
2493			if(g_vars.trace_debug == true){
2494				trace("on widget init");
2495			}
2496
2497			if(!g_vars.funcOnInit){
2498
2499				if(typeof func != "function")
2500					throw new Error("onWidgetInit error: the second parameter should be a function");
2501
2502				g_vars.funcOnInit = func;
2503			}
2504
2505			if(options && g_vars.init_options == null)
2506				g_vars.init_options = options;
2507			
2508			if(g_vars.debug_show_widget && g_vars.debug_show_widget == widgetID)
2509				g_vars.trace_debug = true;
2510			
2511			initGlobal(widgetID, t.onWidgetInit);
2512
2513			if(g_vars.is_inited == false){
2514				
2515				if(g_vars.trace_debug == true){
2516					trace(widgetID+" not inited yet, waiting for parent init");
2517				}
2518
2519				return(false);
2520			}
2521
2522			//show id's on the widgets
2523			if(g_vars.debug_show_ids == true){
2524
2525				trace("start debug show id's");
2526
2527				displayTextOnWidget(g_objWidget, g_objWidget.attr("id"), "debug");
2528			}
2529
2530			if(g_vars.trace_debug == true)
2531				trace("start debug - show connect");
2532
2533			if(g_objParent.length > 1){
2534
2535				trace(g_objWidget);
2536				trace(g_objParent);
2537
2538				throw new Error("Remote widget can't connect to more then 1 parents");
2539			}
2540
2541			//widget is inited
2542
2543			onWidgetReady();
2544					
2545			if(g_vars.funcOnInit){
2546				
2547				g_vars.is_inited = true;
2548				g_vars.funcOnInit(g_objWidget);				
2549			}
2550				
2551		}catch(message){
2552
2553
2554			displayErrorMessage(message);
2555
2556			var isEditorMode = isInsideEditor();
2557
2558			//in editor mode check debug every second
2559
2560			if(isEditorMode == true)
2561				setInterval(checkWidgetInsideEditor, 700);
2562
2563			return(false);
2564		}
2565
2566	}
2567
2568
2569	/**
2570	 * start sync
2571	 */
2572	function startParentSync(){
2573				
2574		var syncID = g_objParent.data("syncid");
2575
2576		//if under template switcher - modify sync id
2577			
2578		if(g_vars.trace_debug == true){
2579			trace("Start parent sync");
2580			trace(g_objParent);
2581		}
2582
2583		if(!syncID){
2584
2585			if(g_vars.trace_debug == true){
2586				trace("no sync id");
2587			}
2588
2589			return(false);
2590		}
2591
2592		var objSync = g_remoteConnection.getSyncObject(syncID);
2593		
2594		var isEditorMode = isInsideEditor();
2595				
2596		objSync.setOptions(syncID, isEditorMode);
2597
2598		var isInited = initAPI();
2599
2600		if(isInited == false){
2601
2602			var widgetID = g_objParent.attr("id");
2603
2604			var parentType = getParentType();
2605
2606			var message = "Sync Error - can't init api for "+widgetID;
2607
2608			if(parentType == g_types.CAROUSEL){
2609
2610				message += ", please check that the owl carousel js file loading from unlimited elements plugin.";
2611
2612			}else{
2613				message += ", please check if the widget is inited and working.";
2614			}
2615
2616			throw new Error(message);
2617		}
2618
2619		g_vars.syncid = syncID;
2620
2621		//add debug event listener
2622		if(g_vars.trace_debug === true)
2623			objSync.on("update_debug", updateSyncDebug);
2624
2625		g_objSync = objSync;
2626
2627		objSync.addAPI(g_api);
2628
2629		//if(isEditorMode == true)
2630			//setInterval(checkSyncInsideEditor, 700);
2631
2632	}
2633
2634
2635	/**
2636	 * parent init, init the debug
2637	 */
2638	this.onParentInit = function(objParent, optionsAPI){
2639
2640		try{
2641
2642			g_objParent = objParent;
2643
2644			if(!g_objParent)
2645				return(false);
2646
2647			if(g_objParent.length == 0)
2648				return(false);
2649
2650			g_vars.is_parent_mode = true;
2651
2652			var optionsFromData = g_objParent.data("uc-remote-options");
2653
2654			if(optionsFromData)
2655				optionsAPI = optionsFromData;
2656
2657			if(optionsAPI)
2658				g_vars.options_api = optionsAPI;
2659
2660			var isDebug = g_objParent.data("debug");
2661
2662			if(typeof ucRemoteDebugEnabled != "undefined")
2663				isDebug = true;
2664
2665			g_vars.trace_debug = isDebug;
2666
2667			if(isDebug === true)
2668				addParentDebug(objParent);
2669
2670			var isSync = objParent.data("sync");
2671
2672			if(isSync == true)
2673				startParentSync();
2674
2675			if(g_vars.debug_show_ids == true){
2676				displayTextOnWidget(g_objParent, g_objParent.attr("id"), "debug");
2677			}
2678
2679		}catch(message){
2680
2681			displayErrorMessage(message);
2682
2683			return(false);
2684
2685		}
2686
2687	}
2688
2689	/**
2690	 * show the info
2691	 */
2692	this.showInfo = function(){
2693
2694		trace("parent");
2695		trace(g_objParent);
2696
2697		trace("current widget");
2698		trace(g_objWidget);
2699
2700
2701	}
2702
2703
2704	/**
2705	 * get the connected parent
2706	 */
2707	this.getParent = function(){
2708
2709		return(g_objParent);
2710	}
2711
2712}
2713
2714/**
2715 * remote connection class - for interacting with outside
2716 */
2717function UERemoteConnection(){
2718
2719	var t = this;
2720
2721	/**
2722	 * get object property
2723	 */
2724	this.getVal = function(obj, name, defaultValue){
2725
2726		if(!defaultValue)
2727			var defaultValue = "";
2728
2729		var val = "";
2730
2731		if(!obj || typeof obj != "object")
2732			val = defaultValue;
2733		else if(obj.hasOwnProperty(name) == false){
2734			val = defaultValue;
2735		}else{
2736			val = obj[name];
2737		}
2738
2739		return(val);
2740	}
2741
2742
2743	/**
2744	 * get the sync object, if not exists, create one
2745	 */
2746	this.getSyncObject = function(syncID){
2747
2748		var syncRealID = "uc_sync_"+syncID;
2749
2750		var objSync = t.getVal(window, syncRealID);
2751
2752		if(objSync)
2753			return(objSync);
2754		
2755		var objSync = new UESyncObject();
2756
2757		window[syncRealID] = objSync;
2758
2759		return(objSync);
2760	}
2761
2762
2763	/**
2764	 * get object synced other objets id's
2765	 */
2766	this.getSyncedElements = function(objElement){
2767
2768		if(!objElement)
2769			return(null);
2770
2771		if(objElement.length == 0)
2772			return(null);
2773
2774		if(objElement.hasClass("uc-remote-parent") == false)
2775			return(null);
2776
2777		var isSync = objElement.data("sync");
2778
2779		if(isSync !== true)
2780			return(null);
2781
2782		var syncID = objElement.data("syncid");
2783
2784		if(!syncID)
2785			return(null);
2786
2787		var objSync = t.getSyncObject(syncID);
2788
2789		var currentID = objElement.attr("id");
2790
2791		var arrElements = objSync.getElements(currentID);
2792
2793		return(arrElements);
2794	}
2795
2796}
2797
2798
2799//body init
2800
2801jQuery(document).on("uc-remote-parent-init",function(event, objParent, optionsAPI){
2802	
2803	var objRemote = new UERemoteWidgets();
2804	objRemote.onParentInit(objParent, optionsAPI);
2805	
2806});
2807
2808window.ueRemoteConnection = new UERemoteConnection();

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.