PageSourceSearch

https://www.masseriasalamina.com/wp-content/plugins/unlimited-elem…/remote/ue-remote-controls.js?ver=2.0.10

js masseriasalamina.com collected 2026-09-26 16:08:14 UTC 47,876 bytes, 2,837 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 g_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(g_enableDebug == true){
787			
788			var strAction = action;
789			
790			if(arg1)
791				strAction += " "+arg1;
792			
793			if(arg2)
794				strAction += " "+arg2;
795			
796			trace("carousel action: "+strAction);
797		}
798		
799		switch(action){
800			case "next":
801				g_owlCarousel.trigger('next.owl.carousel');
802			break;
803			case "prev":
804				g_owlCarousel.trigger('prev.owl.carousel');
805			break;
806			case "play":
807
808				g_owlCarousel.trigger('start_autoplay.owl.autoplay');
809
810			break;
811			case "pause":
812
813				g_owlCarousel.trigger('stop.owl.autoplay');
814
815			break;
816			case "is_playing":
817
818				if (g_owl.settings.autoplay == true)
819                    return(true)
820                else
821                    return(false);
822
823			break;
824			case "get_total_items":
825
826				var total = getTotalItems()
827
828				return(total);
829
830			break;
831			case "get_progress_time":
832
833      			var progressTime = g_owl.settings.autoplayTimeout / 1000;
834				return(progressTime);
835
836			break;
837			case "get_modified_progress_time":
838
839      			var progressTime = (g_owl.settings.autoplayTimeout - g_owl.settings.smartSpeed) / 1000;
840				return(progressTime);
841
842			break;
843			case 'get_num_current':
844
845      			var currentItem = g_owl.relative(g_owl.current());
846
847      			if(g_enableDebug === true){
848      				trace("num current: " + currentItem);
849      			}
850
851      			return(currentItem);
852			break;
853			case "get_total_text":
854
855				var owlTotalItems = g_owlCarousel.find(".owl-item:not(.cloned)").length;
856				if(owlTotalItems.toString().length < 2){
857                    owlTotalItems = "0" + owlTotalItems;
858                   }
859				return(owlTotalItems);
860
861			break;
862            case "get_current_text":
863
864                var owlCurrentItem = g_owl.relative(g_owl.current()) + 1;
865                if(owlCurrentItem.toString().length < 2){
866                    owlCurrentItem = "0" + owlCurrentItem;
867                   }
868				return(owlCurrentItem);
869
870            break;
871			case 'change_item':
872				
873				var total = getTotalItems()
874				var currentItem = g_owl.relative(g_owl.current());
875
876				var slideNum = arg1;
877
878				if(slideNum == currentItem)
879					return(false);
880				
881				if(slideNum >= total)
882					slideNum = (total-1);
883				else
884					if(slideNum < 0)
885						slideNum = 0;
886				
887                g_owlCarousel.trigger('to.owl.carousel', [slideNum, null, true]);
888                
889                resetAutoplay();
890
891			break;
892			case "unselect_items":
893			break;
894			default:
895				throw new Error("Carousel API: Wrong action: "+action);
896			break;
897		}
898
899	}
900
901
902	/*
903		events
904	*/
905	this.onEvent = function(name, func){
906
907		  validateInited();
908
909          switch(name){
910			case "play":
911
912				g_owlCarousel.on("play_autoplay.owl.carousel", func);
913
914			break;
915			case "pause":
916
917				g_owlCarousel.on("stop_autoplay.owl.carousel", func);
918
919			break;
920			case "change":
921
922				g_owlCarousel.on("changed.owl.carousel", func);
923
924			break;
925			case "transition_start":
926
927				g_owlCarousel.on("translate.owl.carousel", func);
928
929			break;
930			case "transition_end":
931
932				g_owlCarousel.on("translated.owl.carousel", func);
933
934			break;
935			case "refreshed":
936
937				g_owlCarousel.on("refreshed.owl.carousel", func);
938
939			break;
940			default:
941				console.error("Carousel API: Wrong event: "+name);
942				throw new Error("Carousel API: Wrong event: "+name);
943			break;
944
945		}
946	}
947
948	/**
949	 * get api type
950	 */
951	this.getAPIType = function(){
952
953		return("carousel");
954	}
955
956	/**
957	 * get the element
958	 */
959	this.getElement = function(){
960
961		return(g_owlCarousel);
962	}
963
964
965	/**
966	* init the api
967	*/
968	this.init = function(objParent){
969
970		if(typeof ucRemoteDebugEnabled != "undefined")
971			g_enableDebug = true;
972		
973		if(objParent.hasClass("owl-carousel") == false)
974			throw new Error("owl-carousel class not found");
975
976		g_owlCarousel = objParent;
977		
978		g_owl = g_owlCarousel.data("owl.carousel");
979		
980		g_owlCarousel.on("uc_ajax_refreshed", onAjaxRefreshed);
981		
982		if(!g_owl)
983			return(false);
984
985		g_isInited = true;
986		
987		
988		return(true);
989	}
990	
991	/**
992	 * on ajax refreshed
993	 */
994	function onAjaxRefreshed(){
995		
996		g_owl = g_owlCarousel.data("owl.carousel");
997		
998	}
999
1000	
1001}
1002
1003/**
1004 * sync object
1005 */
1006function UESyncObject(){
1007
1008	var g_objApis = {};
1009	var g_groupName, g_objIDs;
1010	var t = this;
1011
1012	var g_vars = {
1013		is_editor:false,
1014		is_editor_func_started:false,
1015		show_debug:false
1016	};
1017
1018	/**
1019	* console log some string
1020	*/
1021	function trace(str){
1022		console.log(str);
1023	}
1024
1025
1026
1027	/**
1028	 * validate api, that they match the existing by number of items
1029	 */
1030	function validate(objAPI){
1031
1032		if(g_objApis.length == 0)
1033			return(false);
1034				
1035		var numItems = objAPI.doAction("get_total_items");
1036
1037		//check with first existing api number of items
1038		for(var elID in g_objApis){
1039			
1040			var firstExistingAPI = g_objApis[elID];
1041
1042			var numItemsExisting = firstExistingAPI.doAction("get_total_items");
1043			
1044			if(numItemsExisting !== numItems){
1045				
1046				var objElement = objAPI.getElement();
1047				var elementID = objElement.attr("id");
1048				
1049				trace("Sync failed "+elementID+" has "+numItems+" items and "+elID+" has "+numItemsExisting+ " items");
1050				
1051				throw new Error("Sync failed, number of items should be the same. Now it's "+numItems+" and "+numItemsExisting);
1052			}
1053			
1054			return(false);
1055		}
1056
1057
1058	}
1059
1060
1061	/**
1062	 * set options
1063	 */
1064	this.setOptions = function(groupName, isEditor){
1065
1066		if(isEditor === true)
1067			g_vars.is_editor = true;
1068
1069		if(!g_groupName)
1070			g_groupName = groupName;
1071
1072	}
1073
1074
1075	/**
1076	 * get api parent id
1077	 */
1078	function getElementID(objAPI){
1079
1080		var objElement = objAPI.getElement();
1081
1082		var elementID = objElement.attr("id");
1083
1084		return(elementID);
1085	}
1086
1087
1088	/**
1089	 * get all ips except the given
1090	 */
1091	function mapAPIs(func, objElement){
1092		
1093		if(typeof ucRemoteDebugEnabled != "undefined")
1094			g_vars.show_debug = true;
1095
1096		var elementID = null;
1097
1098		if(objElement){
1099
1100			var elementID = objElement.attr("id");
1101
1102			if(g_objApis.length == 1)
1103				return(null);
1104		}
1105
1106		for(var elID in g_objApis){
1107
1108			var api = g_objApis[elID];
1109
1110			//except if exists
1111			if(elementID && elID == elementID)
1112					continue;
1113
1114			func(api);
1115
1116		}
1117
1118	}
1119
1120
1121	/**
1122	 * activate change command on all other apis
1123	 */
1124	function onItemChange(objAPI){
1125		
1126		var numCurrent = objAPI.doAction("get_num_current");
1127		
1128		var objElement = objAPI.getElement();
1129
1130		if(g_vars.show_debug == true){
1131			
1132			trace("sync onchange: " + numCurrent);
1133			trace(objElement);
1134			trace(g_objApis);
1135		}
1136		
1137		mapAPIs(function(api){
1138						
1139			if(numCurrent < 0)
1140				api.doAction("unselect_items");
1141			else
1142				api.doAction("change_item", numCurrent);
1143			
1144		}, objElement);
1145
1146	}
1147
1148	/**
1149	 * on pause - pause others as well
1150	 */
1151	function onPause(objAPI){
1152
1153		var objElement = objAPI.getElement();
1154
1155		mapAPIs(function(api){
1156
1157			api.doAction("pause");
1158
1159		}, objElement);
1160
1161
1162	}
1163
1164
1165	/**
1166	 * trigger some action
1167	 */
1168	function trigger(action, params){
1169
1170		var realAction = "uc_remote_sync_"+g_groupName+"_action_"+action;
1171
1172		jQuery("body").trigger(realAction, params);
1173	}
1174
1175
1176	/**
1177	 * on event
1178	 */
1179	this.on = function(action, func){
1180
1181		var realAction = "uc_remote_sync_"+g_groupName+"_action_"+action;
1182
1183		jQuery("body").on(realAction, func);
1184
1185	}
1186
1187
1188	/**
1189	 * get debug text
1190	 */
1191	this.getDebugText = function(objElement){
1192
1193		var text = "sync group: <b>" + g_groupName+"</b>, ";
1194
1195		var textWidgets = "";
1196
1197		mapAPIs(function(api){
1198
1199			var objElement = api.getElement();
1200			var widgetName = objElement.data("widgetname");
1201			var widgetID = objElement.attr("id");
1202
1203			if(textWidgets)
1204				textWidgets += ", ";
1205
1206			textWidgets += "<a href='#"+widgetID+"' style='color:green;text-decoration:underline'><b>
1206" + widgetName + "</b></a>";
1207
1208		}, objElement);
1209
1210		if(textWidgets)
1211			text += "sync with: " + textWidgets;
1212
1213		return(text);
1214	}
1215
1216
1217	/**
1218	 * remove deleted from page APIs
1219	 */
1220	function removeDeletedAPIs(){
1221
1222		var objAPIsNew = {};
1223
1224		mapAPIs(function(api){
1225
1226			var elementID = getElementID(api);
1227			var objElement = jQuery("#"+elementID);
1228
1229			if(objElement.length == 0)
1230				return(false);
1231
1232			var parent = objElement.parent();
1233
1234			objAPIsNew[elementID] = api;
1235
1236		});
1237
1238		g_objApis = objAPIsNew;
1239
1240	}
1241
1242
1243	/**
1244	 * on editor check
1245	 */
1246	function onEditorCheck(){
1247
1248		removeDeletedAPIs();
1249
1250		trigger("update_debug", g_groupName);
1251
1252	}
1253
1254	/**
1255	 * get group name
1256	 */
1257	this.getGroupName = function(){
1258
1259		return(g_groupName);
1260	}
1261
1262	/**
1263	 * add widget to sync object
1264	 */
1265	this.addAPI = function(objAPI){
1266		
1267		
1268		var id = getElementID(objAPI);
1269		
1270		if(g_objApis.hasOwnProperty(id))
1271			return(false);
1272
1273		g_objApis[id] = objAPI;
1274
1275		if(g_vars.is_editor == true)
1276			removeDeletedAPIs();
1277
1278		validate(objAPI);
1279
1280
1281		//debug
1282		var objElement = objAPI.getElement();
1283
1284		//add debug
1285		trigger("update_debug", g_groupName);
1286
1287		//set events
1288		objAPI.onEvent("change", function(){
1289
1290			onItemChange(objAPI);
1291
1292		});
1293
1294		//sync objects pause
1295
1296		objAPI.onEvent("pause", function(){
1297
1298			onPause(objAPI);
1299		});
1300
1301
1302		if(g_vars.is_editor == true && g_vars.is_editor_func_started == false){
1303
1304			setInterval(onEditorCheck, 700);
1305			g_vars.is_editor_func_started = false;
1306		}
1307
1308
1309	}
1310
1311	/**
1312	 * get all elements
1313	 */
1314	this.getElements = function(exceptID){
1315
1316		if(!g_objApis)
1317			return(null);
1318
1319		var arrElements = [];
1320
1321		//check with first existing api number of items
1322		for(var elID in g_objApis){
1323
1324			if(exceptID && exceptID == elID)
1325				continue;
1326
1327			var objApi = g_objApis[elID];
1328
1329			var objElement = objApi.getElement();
1330
1331			arrElements.push(objElement);
1332		}
1333
1334		if(arrElements.length == 0)
1335			return(null);
1336
1337		return(arrElements);
1338	}
1339
1340}
1341
1342/**
1343* ---------------------------------------------------
1344* remote widget api class
1345*/
1346function UERemoteWidgets(){
1347
1348	var g_objParent, g_objWidget, g_parentID;
1349	var g_api, g_objSync, g_remoteConnection = window.ueRemoteConnection;
1350	var t = this;
1351
1352	var g_vars = {
1353		is_inited:false,
1354		funcOnInit:null,
1355		is_editor:null,
1356		widget_id:null,
1357		init_options:null,
1358		is_parent_mode: false,
1359		syncid:null,
1360		options_api:null,
1361		show_connection_debug:false,
1362		debug_show_ids:false,
1363		debug_show_widget: "",
1364		trace_debug:false	//debug
1365	};
1366
1367	var g_types = {
1368		CAROUSEL:"carousel",
1369		GALLERY:"gallery",
1370		GENERAL:"general"
1371	};
1372
1373
1374	/**
1375	* console log some string
1376	*/
1377	function trace(str){
1378		console.log(str);
1379	}
1380
1381	/**
1382	 * get object property
1383	 */
1384	function getVal(obj, name, defaultValue){
1385
1386		return window.ueRemoteConnection.getVal(obj, name, defaultValue);
1387	}
1388
1389
1390
1391	function _______INIT_________(){}
1392
1393	/**
1394	* init widget
1395	*/
1396	function initWidget(widgetID){
1397
1398		g_objWidget = jQuery("#"+widgetID);
1399		if(g_objWidget.length == 0)
1400			throw new Error("Widget not found by id: "+widgetID);
1401
1402		g_vars.widget_id = widgetID;
1403
1404		var forceID = getVal(g_vars.init_options, "force_parentid");
1405
1406		if(forceID)
1407			g_parentID = forceID;
1408		else
1409			g_parentID = g_objWidget.data("parentid");
1410
1411		if(!g_parentID)
1412			throw new Error("Parent controlled ID not set");
1413
1414	}
1415
1416	/**
1417	* get controlled parent type
1418	*/
1419	function getParentType(){
1420
1421		if(!g_objParent || g_objParent.length == 0)
1422			throw new Error("getParentType: no parent found");
1423
1424		if(g_objParent.hasClass("owl-carousel"))
1425			return(g_types.CAROUSEL);
1426
1427		var dataType = g_objParent.data("remote-type");
1428
1429		switch(dataType){
1430			case "gallery":
1431				return g_types.GALLERY;
1432			break;
1433		}
1434
1435
1436		return(g_types.GENERAL);
1437	}
1438
1439
1440	/**
1441	 * get offsets distance
1442	 */
1443	function getOffsetsDistance(offset1, offset2){
1444
1445	  var dx = offset2.left-offset1.left;
1446	  var dy = offset2.top-offset1.top;
1447
1448	  return Math.sqrt(dx*dx+dy*dy);
1449	}
1450
1451
1452	/**
1453	 * get closest object by offset
1454	 */
1455	function getClosestByOffset(objParents, objElement){
1456
1457		var objClosest = null;
1458		var minDiff = 1000000;
1459
1460		var elementOffset = objElement.offset();
1461		
1462		if(g_vars.trace_debug){
1463			trace("Widget Offset: ");
1464			trace(elementOffset);
1465		}
1466
1467		jQuery.each(objParents, function(index, parent){
1468
1469			var objParent = jQuery(parent);
1470			var parentOffset = objParent.offset();
1471
1472			if(parentOffset.top == 0){
1473
1474				var firstParent = getWidgetContainer(objParent);
1475				var parentOffset = firstParent.offset();
1476
1477			}
1478
1479			var distance = getOffsetsDistance(parentOffset, elementOffset);
1480
1481			if(g_vars.trace_debug){
1482				trace("Parent offset: ");
1483				trace(objParent);
1484				trace(parentOffset);
1485				trace("distance: " + distance);
1486			}
1487
1488			if(distance < minDiff){
1489				minDiff = distance;
1490				objClosest = objParent;
1491			}
1492
1493		});
1494
1495		return(objClosest);
1496	}
1497
1498	/**
1499	 * filter parents by section
1500	 */
1501	function filterParentsBySection(objParents, objElement){
1502
1503		var objSection = objElement.closest(".elementor-top-section");
1504
1505		if(objSection.length == 0)
1506			return(objParents);
1507
1508		var section = objSection[0];
1509
1510		var objFiltered = objParents.filter(function(index, parent){
1511
1512			var isContains = jQuery.contains(section, parent);
1513
1514			return isContains;
1515		});
1516
1517		if(objFiltered.length)
1518			return(objFiltered);
1519
1520		return(objParents);
1521	}
1522
1523
1524	/**
1525	 * detect closest parent
1526	 */
1527	function detectClosestParent(objParents){
1528		
1529		var objContainer = jQuery("body");
1530		
1531		//twick for tempalte switcher
1532		var objTemplateHolder = g_objWidget.closest(".uc-template-holder");
1533		
1534		if(objTemplateHolder.length)
1535			objContainer = objTemplateHolder;
1536		
1537		if(!objParents)
1538			var objParents = objContainer.find(".uc-remote-parent").not(g_objWidget);
1539		
1540		if(g_vars.trace_debug){
1541			trace("detect closest start. group:");
1542			trace(objParents);
1543		}
1544		
1545		var numParents = objParents.length;
1546
1547		if(numParents == 0)
1548			return(null);
1549
1550		if(numParents == 1)
1551			return(objParents);
1552
1553		//filter by auto
1554
1555		if(g_vars.trace_debug)
1556			trace("filter auto");
1557
1558		var objParentsFiltered = objParents.filter("[data-remoteid='"+g_parentID+"']");
1559
1560		if(objParentsFiltered.length == 1)
1561			return(objParentsFiltered);
1562
1563		//find by offset
1564
1565		if(g_vars.trace_debug){
1566			trace("filter by section");
1567		}
1568
1569		var objParents = filterParentsBySection(objParents, g_objWidget);
1570
1571		if(g_vars.trace_debug){
1572			trace(objParents);
1573		}
1574
1575		if(objParents.length == 1)
1576			return(objParents);
1577
1578		if(g_vars.trace_debug)
1579			trace("get closest by parent");
1580
1581		var objClosest = getClosestByOffset(objParents, g_objWidget);
1582
1583		if(objClosest)
1584			return(objClosest);
1585
1586		if(g_vars.trace_debug)
1587			trace("get first");
1588
1589		var firstParent = jQuery(objParentsFiltered[0]);
1590
1591
1592		return(firstParent);
1593	}
1594
1595	/**
1596	 * set parent object
1597	 */
1598	function setParentObject(){
1599
1600		var objForceParent = getVal(g_vars.init_options, "force_parent_obj");
1601
1602		var widgetID = g_objWidget.attr("id");
1603		
1604		if(g_vars.trace_debug)
1605			trace("start set parent for: "+widgetID+", parent name: "+g_parentID);
1606
1607		if(objForceParent){
1608
1609			g_objParent = objForceParent;
1610
1611			if(g_vars.trace_debug){
1612				trace("set force parent");
1613				trace(g_objParent);
1614			}
1615
1616			return(true);
1617		}
1618		
1619		
1620		if(!g_parentID)
1621		   throw new Error("Parent controller ID not found");
1622
1623		if(!g_objParent || g_objParent.length == 0){
1624
1625			if(g_parentID == "auto"){
1626
1627				if(g_vars.trace_debug){
1628					trace("auto detect selected");
1629				}
1630
1631				g_objParent = detectClosestParent();
1632
1633				if(g_vars.trace_debug){
1634					trace("detect closest");
1635					trace(g_objParent);
1636				}
1637
1638				if(!g_objParent)
1639					throw new Error("Can't detect remote parent");
1640
1641			}
1642			else{
1643
1644				var objParents = jQuery(".uc-remote-parent[data-remoteid='"+g_parentID+"']").not(g_objWidget);
1645
1646				if(g_vars.trace_debug)
1647					trace("Detect from group: "+g_parentID);
1648
1649				g_objParent = detectClosestParent(objParents);
1650
1651				if(g_vars.trace_debug){
1652					trace("detected from group");
1653					trace(g_objParent);
1654				}
1655				
1656				if(!g_objParent || g_objParent.length == 0){
1657					
1658				   //set another try
1659				   var isAnotherTry = g_objWidget.data("uc_parent_detect_another_try");
1660				   if(!isAnotherTry){
1661					   g_objWidget.data("uc_parent_detect_another_try", true);
1662					   
1663					   if(g_vars.trace_debug)
1664						   trace("Set another try for parent detect");
1665					   
1666					   return(false);
1667				   }
1668				
1669				   throw new Error("Parent widget with remote name: '"+g_parentID+"' not found");
1670				}
1671				
1672			}
1673
1674		}
1675
1676		if(g_objParent && g_objParent.length > 1){
1677			g_objParent = jQuery(g_objParent[0]);
1678		}
1679
1680		if(g_vars.trace_debug == true){
1681
1682			var parentID = g_objParent.attr("id");
1683			var widgetID = g_objWidget.attr("id");
1684			
1685			trace("widget: "+widgetID+" connected to: "+parentID);
1686
1687		}
1688
1689		if(!g_objParent || g_objParent.length == 0)
1690			  throw new Error("Remote parent not found");
1691		
1692		return(true);
1693	}
1694
1695
1696	/**
1697	 * init api variable
1698	 */
1699	function initAPI(){
1700		
1701		if(g_vars.trace_debug == true){
1702			trace("start init api function");
1703		}
1704
1705		//set type and related objects
1706		if(!g_api){
1707
1708			var parentType = getParentType();
1709
1710
1711			if(!parentType){
1712				trace(g_objParent);
1713				throw new Error("No parent type found");
1714			}
1715
1716			if(g_vars.trace_debug == true){
1717
1718				trace("init api: " + parentType);
1719				trace(g_objParent);
1720			}
1721
1722			//init the api
1723			switch(parentType){
1724				case g_types.CAROUSEL:
1725					g_api = new UERemoteCarouselAPI();
1726				break;
1727				case g_types.GENERAL:
1728
1729					g_api = new UERemoteGeneralAPI();
1730
1731				break;
1732				case g_types.TABS:
1733
1734					//g_api = new UERemoteTabsAPI();
1735					g_api = new UERemoteGeneralAPI();
1736
1737				break;
1738				case g_types.GALLERY:
1739
1740					g_api = new UERemoteGalleryAPI();
1741
1742				break;
1743				default:
1744					throw new Error("Wrong parent type: "+parentType);
1745				break;
1746			}
1747
1748		}
1749
1750		var optionsFromData = g_objParent.data("uc-remote-options");
1751
1752		var isEditor = isInsideEditor();
1753
1754		if(optionsFromData)
1755			g_vars.options_api = optionsFromData;
1756		
1757		var optionsAPI = {};
1758		
1759		var optionsAPI = jQuery.extend({},g_vars.options_api);
1760		
1761		if(jQuery.isEmptyObject(g_vars.options_api) == false)
1762			jQuery.extend({},optionsAPI, g_vars.options_api);
1763			
1764		if(g_vars.trace_debug == true){
1765			
1766			if(optionsAPI)
1767				trace(optionsAPI);
1768				
1769			optionsAPI["trace_debug"] = true;			
1770		}
1771		
1772		var isInited = g_api.init(g_objParent, g_vars.options_api, isEditor);
1773		
1774		if(g_vars.trace_debug == true){
1775			trace("inited: " + isInited);
1776		}
1777
1778		return(isInited);
1779	}
1780
1781
1782	/**
1783	*	init parent
1784	*/
1785	function initParent(){
1786		
1787		var isParentSet = setParentObject();
1788		
1789		if(isParentSet == false)
1790			return(false);
1791		
1792		var isInited = initAPI();
1793
1794		return(isInited);
1795	}
1796
1797
1798	/**
1799		init global helper function
1800	*/
1801	function initGlobal(widgetID, func){
1802
1803		if(!g_objWidget)
1804			initWidget(widgetID);
1805		
1806		//init the debug related
1807		
1808		var isDebug = g_objWidget.data("debug");
1809		if(isDebug === true || typeof ucRemoteDebugEnabled != "undefined"){
1810			
1811			g_vars.trace_debug = true;
1812			g_vars.show_connection_debug = true;
1813			
1814		}
1815		
1816		if(g_vars.trace_debug){
1817			if(!widgetID)
1818				widgetID = g_objWidget.attr("id");
1819			
1820			trace("Initing Remote Widget: "+widgetID);
1821		}
1822		
1823		g_vars.is_inited = initParent();
1824
1825		if(g_vars.is_inited == false){
1826
1827			if(!g_objParent){
1828				
1829				setTimeout(func, 1000);	//try onWidgetInit in a second again
1830				
1831			}else{
1832				
1833				if(g_vars.trace_debug == true){
1834
1835					trace(g_objParent);
1836					trace("set object ready event");	//onWidgetInit
1837				}
1838				
1839				g_objParent.on("uc-object-ready", func);
1840				
1841			}
1842			
1843
1844		}
1845	}
1846
1847
1848	/**
1849	* set action, bind to some object
1850	* objElement can be jQuery object or selector
1851	*/
1852	this.setAction = function(action, objElement, allowMultiple){
1853		
1854		if(g_vars.trace_debug == true){
1855			trace("set action: "+action);
1856		}
1857
1858		if(g_vars.is_inited == false)
1859			throw new Error("Widget not inited");
1860
1861		if(typeof objElement == "string"){
1862		  var selector = objElement;
1863		   objElement = g_objWidget.find(objElement);
1864		   if(objElement.length == 0)
1865				throw new Error("Remote '"+action+"' action error: element: "+selector+" not found");
1866		}
1867
1868		if(!objElement || objElement.length == 0)
1869			throw new Error("Element not inited");
1870
1871		if(!g_api)
1872			throw new Error("API not inited!");
1873
1874		//avoid double action
1875		var linkedAction = objElement.data("uc-action");
1876
1877		if(allowMultiple !== true)
1878			if(linkedAction){
1879				
1880				trace("not allow multiple action: "+action);
1881				
1882				return(false);
1883			}
1884
1885		objElement.data("uc-action", action);
1886
1887		objElement.on("click",function(){
1888
1889			var objElement = jQuery(this);
1890
1891			if(objElement.hasClass("uc-disabled"))
1892				return(true);
1893
1894			t.doAction(action);
1895
1896		});
1897
1898	}
1899
1900
1901	/**
1902	 * run this function after the widget is ready to use
1903	 */
1904	function onWidgetReady(){
1905
1906		checkWidgetDebug();
1907
1908		var isEditorMode = isInsideEditor();
1909		
1910		//in editor mode check debug every second
1911
1912		if(isEditorMode == true){
1913
1914			hideErrorOnWidget();
1915
1916			setInterval(checkWidgetInsideEditor, 700);
1917		}
1918
1919
1920	}
1921
1922
1923	function _______TEXT_ON_WIDGET_________(){}
1924
1925
1926	/**
1927	 * hide error on widget
1928	 */
1929	function hideErrorOnWidget(){
1930
1931		if(!g_objWidget || g_objWidget.length == 0)
1932			return(false);
1933
1934		var objParent = getWidgetContainer(g_objWidget);
1935
1936		//don't hide if no message
1937
1938		var objError = objParent.find('.uc-remote-error');
1939
1940		if(objError.length == 0)
1941			return(false);
1942
1943		if(objError.is(":visible") == false)
1944			return(false);
1945
1946		objError.hide();
1947
1948		g_objWidget.css({
1949			"border" : "none"
1950		});
1951
1952		//try to set the debug if avaliable
1953		checkWidgetDebug();
1954
1955	}
1956
1957	/**
1958	 * get widget container
1959	 */
1960	function getWidgetContainer(objWidget){
1961		
1962		objParent = objWidget.parent();
1963
1964		return(objParent);
1965	}
1966
1967
1968	/**
1969	 * add error message div on the widget div
1970	 *
1971	 */
1972	function addTextDiv(objWidget, type){
1973		
1974		var objParent = getWidgetContainer(objWidget);
1975
1976		var isDebug = (type == "debug");
1977
1978		var className = "uc-remote-error";
1979		if(isDebug == true)
1980			className = "uc-remote-debug";
1981
1982		var divText = "<div class='"+className+"'></div>";
1983		objParent.append(divText);
1984
1985		var objError = objParent.find('.'+className+'');
1986
1987		var css = {
1988				"position":"absolute",
1989				"color":"red",
1990				"top":"-30px",
1991				"left":"0px",
1992				"z-index":"999999",
1993				"background-color":"#ffffff"
1994		};
1995
1996		if(isDebug == true){
1997			css["color"] = "green";
1998			css["z-index"] = "999998";
1999		}
2000
2001		//fix position for bg
2002		var objParentsBG = objParent.parents(".unlimited-elements-background-overlay");
2003		if(objParentsBG.length){
2004			css["top"] = "0px";
2005		}
2006
2007		objError.css(css);
2008
2009		var objError = objParent.find('.'+className+'');
2010
2011		return(objError);
2012	}
2013
2014	/**
2015	 * display some error on widget interface
2016	 */
2017	function displayTextOnWidget(objWidget, message, type){
2018		
2019		var isDebug = (type == "debug");
2020
2021		var className = "uc-remote-error";
2022		if(isDebug == true)
2023			className = "uc-remote-debug";
2024
2025		var objParent = getWidgetContainer(objWidget);
2026
2027		objText = objParent.find("."+className);
2028
2029		//add error div if missing. pause error in editor
2030		//second time the div will be not empty and it will show the message
2031		if(objText.length == 0){
2032
2033			objText = addTextDiv(objWidget, type);
2034
2035			if(isDebug == false){
2036
2037				var isInEditor = isInsideEditor();
2038
2039				if(isInEditor == true){
2040
2041					setTimeout(function(){
2042						displayTextOnWidget(objWidget, message, type);
2043					},2000);
2044
2045					return(false);
2046				}
2047
2048			}
2049
2050		}
2051
2052		//add the error border
2053		if(isDebug == false){
2054
2055			objWidget.css({
2056				"border" : "2px solid red",
2057				"position" : "relative"
2058			});
2059
2060		}
2061
2062		objText.show();
2063		objText.html(message);
2064
2065	}
2066
2067
2068	/**
2069	 * display error message
2070	 */
2071	function displayErrorMessage(message){
2072
2073		if(typeof g_ucRemoteHideErrors !== "undefined" && g_ucRemoteHideErrors === true){
2074		
2075			trace("UE Remote Error: "+message);
2076			
2077			return(false);
2078		}
2079		
2080	
2081		if(g_vars.is_parent_mode == false){
2082
2083			if(g_objWidget && g_objWidget.length)
2084				displayTextOnWidget(g_objWidget, message,"error");
2085
2086		}else{
2087
2088			displayTextOnWidget(g_objParent, message, "error");
2089
2090		}
2091		
2092		//console.log("UE Remote Error: "+message);
2093		//console.log(message);
2094
2095	}
2096
2097	function _______DEBUG_________(){}
2098
2099
2100	/**
2101	 * return if the debug is active
2102	 */
2103	function isDebugActive(objWidget){
2104
2105		if(!objWidget)
2106			objWidget = g_objWidget;
2107
2108		var isActive = objWidget.data("debug_active");
2109
2110		if(isActive === true)
2111			return(true);
2112
2113		return(false);
2114	}
2115
2116
2117	/**
2118	 * remove debug visual from the widget
2119	 */
2120	function removeDebugVisual(objWidget){
2121
2122		if(!objWidget)
2123			objWidget = g_objWidget;
2124
2125		g_objWidget.data("debug_active", false);
2126
2127		g_objWidget.css({
2128			"border-style":"none"
2129		});
2130
2131	}
2132
2133
2134	/**
2135	 * set debug visual
2136	 */
2137	function setDebugVisual(color, objWidget){
2138
2139		if(!objWidget)
2140			objWidget = g_objWidget;
2141
2142		objWidget.data("debug_active", true);
2143
2144		objWidget.css({
2145			"border-style":"solid",
2146			"border-width":"3px",
2147			"border-color":color
2148		});
2149
2150	}
2151
2152	/**
2153	 * check if parent debug is active
2154	 */
2155	function isParentDebugActive(objParent){
2156
2157		var dataDebug = objParent.data("debug");
2158		var isDebug = (dataDebug === true);
2159
2160		return(isDebug);
2161	}
2162
2163
2164	/**
2165	 * check widget debug work
2166	 */
2167	function checkWidgetDebugWork(objWidget, objParent){
2168
2169		if(!objWidget)
2170			objWidget = g_objWidget;
2171
2172		if(!objParent)
2173			objParent = g_objParent;
2174
2175		var isDebug = isParentDebugActive(objParent);
2176
2177		var isActive = isDebugActive(objWidget);
2178
2179		/*
2180		trace("check! "+isActive+" "+isDebug);
2181		trace(objParent);
2182		trace(objWidget);
2183		*/
2184
2185		//remove debug if active but no need
2186
2187		if(isDebug == false){
2188
2189			if(isActive == true)
2190				removeDebugVisual(objWidget);
2191
2192			return(false);
2193		}
2194
2195		//add debug is not in debug mode
2196
2197		if(isActive == false){
2198
2199			//get parent color
2200			var color = addParentDebug(objParent);
2201			setDebugVisual(color, objWidget);
2202
2203		}
2204
2205
2206	}
2207
2208	/**
2209	 * check and put debug connection
2210	 */
2211	function checkDebugConnectionText(){
2212
2213		if(!g_objWidget)
2214			return(false);
2215
2216		if(g_vars.show_connection_debug == false)
2217			return(false);
2218
2219		if(!g_objParent || g_objParent.length == 0)
2220			throw new Error("Not conneted to no parent");
2221
2222		var widgetName = g_objParent.data("widgetname");
2223		var widgetID = g_objParent.attr("id");
2224
2225		var text = "connected to <a href='#"+widgetID+"' style='color:green;text-decoration:underline'><b>" + widgetName + "</b></a>";
2226		
2227		displayTextOnWidget(g_objWidget, text, "debug");
2228
2229	}
2230
2231
2232	/**
2233	 * check widget debug
2234	 */
2235	function checkWidgetDebug(){
2236
2237		var noDebugCheck = getVal(g_vars.init_options, "no_debug_check");
2238
2239		if(noDebugCheck === true)
2240			return(false);
2241
2242		//get debug color
2243		if(!g_objParent || g_vars.is_inited == false){
2244			removeDebugVisual();
2245			return(false);
2246		}
2247
2248		checkWidgetDebugWork();
2249
2250		checkDebugConnectionText();
2251
2252	}
2253
2254	/**
2255	 * on api event
2256	 */
2257	this.onEvent = function(name, func){
2258		g_api.onEvent(name,func);
2259	}
2260
2261
2262	/**
2263	 * change item by action (0 - total-1)
2264	 */
2265	function changeItemByAction(dir){
2266		
2267		var current = t.doAction("get_num_current");
2268		var total = t.doAction("get_total_items");
2269		
2270		switch(dir){
2271			case "next":
2272
2273				var num = current+1;
2274				if(num >= total )
2275					num = 0;
2276
2277			break;
2278			case "prev":
2279
2280				var num = current-1;
2281				if(num < 0)
2282					num = total-1;
2283				
2284			break;
2285			default:
2286				throw new Error("wrong direction type: "+dir);
2287			break;
2288		}
2289		
2290		
2291		t.doAction("change_item", num);
2292
2293	}
2294
2295
2296	/**
2297	 * do api action
2298	 */
2299	this.doAction = function(action, arg1, arg2){
2300
2301		if(g_vars.trace_debug){
2302						
2303			var strAction = action;
2304			if(arg1)
2305				strAction += " "+arg1;
2306			if(arg2)
2307				strAction += " "+arg2;
2308
2309			trace("Do Action: ");
2310			
2311			trace(strAction);
2312		}
2313		
2314		if(!g_api){
2315			if(g_vars.trace_debug)
2316				trace("empty g_api, exit");
2317			
2318			return(false);
2319		}
2320		
2321		switch(action){
2322			case "prev":
2323			case "next":
2324
2325				var apiType = g_api.getAPIType();
2326
2327				if(apiType == "carousel"){
2328										
2329					g_api.doAction(action);
2330					
2331					return(false);
2332				}
2333				
2334				changeItemByAction(action);
2335				return(false);
2336			break;
2337		}
2338
2339		var response = g_api.doAction(action, arg1, arg2);
2340		
2341		if(g_vars.trace_debug){
2342			trace("Response: ");
2343			trace(response);
2344		}
2345
2346
2347		return(response);
2348	}
2349
2350	/**
2351	 * add the parent some debug color
2352	 */
2353	function addParentDebug(objParent){
2354
2355		if(!objParent)
2356			objParent = g_objParent;
2357
2358		var color = g_objParent.data("uc-debug-color");
2359		if(color)
2360			return(color);
2361
2362		var objBody = jQuery("body");
2363		var dataColors = "uc-remote-debug-colors";
2364
2365		var objColors = objBody.data(dataColors);
2366
2367		if(!objColors){
2368			objColors = ["#ffeb00","blue","#808000","#d1e231","#01796f","#8e4585","#ff33cc","#436b95","#eaa221","#b86d29"];
2369		}
2370
2371		var color = objColors.pop();
2372
2373		g_objParent.data("uc-debug-color", color);
2374		objBody.data(dataColors, objColors);
2375
2376		g_objParent.css("border","3px solid "+color);
2377
2378		return(color);
2379	}
2380
2381
2382	/**
2383	 * update sync debug
2384	 */
2385	function updateSyncDebug(event, syncID){
2386
2387		//if show id's disable other debug
2388		if(g_vars.debug_show_ids == true)
2389			return(false);
2390
2391		try{
2392
2393			if(syncID != g_vars.syncid){
2394
2395				var name = g_objParent.data("widgetname");
2396				throw new Error("Wrong sync group mishmash "+g_vars.syncid+" and " + syncID);
2397			}
2398
2399			var debugText = g_objSync.getDebugText(g_objParent);
2400
2401			if(!debugText)
2402				return(false);
2403
2404			displayTextOnWidget(g_objParent, debugText, "debug");
2405
2406		}catch(error){
2407
2408			displayErrorMessage(error);
2409
2410		}
2411
2412	}
2413
2414
2415	function _______EDITOR_RELATED_________(){}
2416
2417	
2418	/**
2419	 * check if inside editor
2420	 */
2421	function isInsideEditor(){
2422		
2423		if(g_vars.is_editor !== null)
2424			return g_vars.is_editor;
2425		
2426		//check for gutenberg
2427		
2428		if(typeof g_ucAdmin !== "undefined"){
2429			g_vars.is_editor = true;
2430			return(true);
2431		}
2432		
2433		// check for elementor
2434		if (window.self !== window.top && typeof window.parent.elementor !== "undefined") {
2435			
2436			g_vars.is_editor = true;
2437
2438			return true;
2439		}
2440				
2441		g_vars.is_editor = false;
2442
2443		return false;
2444	}
2445
2446	/**
2447	 * reset the settings
2448	 */
2449	function resetSettingsInsideEditor(){
2450
2451		g_objParent = null;
2452		g_api = null;
2453		g_vars.is_inited = false;
2454
2455	}
2456
2457
2458	/**
2459	 * check widget inside editor
2460	 */
2461	function checkWidgetInsideEditor(){
2462				
2463		//check for disconnect
2464		try{
2465
2466			hideErrorOnWidget();
2467
2468			if(g_vars.is_inited == true){
2469
2470				if(g_objParent.is(":hidden")){
2471
2472					//disconnect
2473					resetSettingsInsideEditor();
2474				}
2475
2476			}else{
2477
2478				//check for connect
2479				g_vars.is_inited = initParent();
2480
2481				if(g_vars.is_inited == true){
2482
2483					g_vars.funcOnInit();
2484				}
2485				else
2486				if(g_vars.is_inited == false){
2487
2488					g_objParent.on("uc-object-ready", function(){
2489
2490						g_vars.is_inited = true;
2491						g_vars.funcOnInit();
2492
2493					});
2494				}
2495
2496			}
2497
2498			checkWidgetDebug();
2499
2500		}catch(message){
2501
2502			displayErrorMessage(message);
2503
2504			return(false);
2505		}
2506
2507
2508	}
2509
2510
2511
2512	/**
2513	* on widget init
2514	*/
2515	this.onWidgetInit = function(widgetID, func, options){
2516		
2517		try{
2518			
2519			if(g_vars.is_inited == true)
2520				return(false);
2521			
2522			if(g_vars.trace_debug == true){
2523				trace("on widget init: " + widgetID);
2524			}
2525			
2526			if(!g_vars.funcOnInit){
2527
2528				if(typeof func != "function")
2529					throw new Error("onWidgetInit error: the second parameter should be a function");
2530
2531				g_vars.funcOnInit = func;
2532			}
2533
2534			if(options && g_vars.init_options == null)
2535				g_vars.init_options = options;
2536			
2537			if(g_vars.debug_show_widget && g_vars.debug_show_widget == widgetID)
2538				g_vars.trace_debug = true;
2539			
2540			initGlobal(widgetID, t.onWidgetInit);
2541						
2542			if(g_vars.is_inited == false){
2543				
2544				if(g_vars.trace_debug == true){
2545					trace(widgetID+" not inited yet, waiting for parent init");
2546				}
2547
2548				return(false);
2549			}
2550
2551			//show id's on the widgets
2552			if(g_vars.debug_show_ids == true){
2553
2554				trace("start debug show id's");
2555
2556				displayTextOnWidget(g_objWidget, g_objWidget.attr("id"), "debug");
2557			}
2558
2559			if(g_vars.trace_debug == true)
2560				trace("start debug - show connect");
2561
2562			if(g_objParent.length > 1){
2563
2564				trace(g_objWidget);
2565				trace(g_objParent);
2566
2567				throw new Error("Remote widget can't connect to more then 1 parents");
2568			}
2569
2570			//widget is inited
2571
2572			onWidgetReady();
2573					
2574			if(g_vars.funcOnInit){
2575				
2576				g_vars.is_inited = true;
2577				g_vars.funcOnInit(g_objWidget);				
2578			}
2579				
2580		}catch(message){
2581
2582
2583			displayErrorMessage(message);
2584
2585			var isEditorMode = isInsideEditor();
2586
2587			//in editor mode check debug every second
2588
2589			if(isEditorMode == true)
2590				setInterval(checkWidgetInsideEditor, 700);
2591
2592			return(false);
2593		}
2594
2595	}
2596
2597
2598	/**
2599	 * start sync
2600	 */
2601	function startParentSync(){
2602				
2603		var syncID = g_objParent.data("syncid");
2604
2605		//if under template switcher - modify sync id
2606			
2607		if(g_vars.trace_debug == true){
2608			trace("Start parent sync");
2609			trace(g_objParent);
2610		}
2611
2612		if(!syncID){
2613
2614			if(g_vars.trace_debug == true){
2615				trace("no sync id");
2616			}
2617
2618			return(false);
2619		}
2620
2621		var objSync = g_remoteConnection.getSyncObject(syncID);
2622		
2623		var isEditorMode = isInsideEditor();
2624				
2625		objSync.setOptions(syncID, isEditorMode);
2626
2627		var isInited = initAPI();
2628
2629		if(isInited == false){
2630
2631			var widgetID = g_objParent.attr("id");
2632
2633			var parentType = getParentType();
2634
2635			var message = "Sync Error - can't init api for "+widgetID;
2636
2637			if(parentType == g_types.CAROUSEL){
2638
2639				message += ", please check that the owl carousel js file loading from unlimited elements plugin.";
2640
2641			}else{
2642				message += ", please check if the widget is inited and working.";
2643			}
2644
2645			throw new Error(message);
2646		}
2647
2648		g_vars.syncid = syncID;
2649
2650		//add debug event listener
2651		if(g_vars.trace_debug === true)
2652			objSync.on("update_debug", updateSyncDebug);
2653
2654		g_objSync = objSync;
2655
2656		objSync.addAPI(g_api);
2657
2658		//if(isEditorMode == true)
2659			//setInterval(checkSyncInsideEditor, 700);
2660
2661	}
2662
2663
2664	/**
2665	 * parent init, init the debug
2666	 */
2667	this.onParentInit = function(objParent, optionsAPI){
2668
2669		try{
2670
2671			g_objParent = objParent;
2672
2673			if(!g_objParent)
2674				return(false);
2675
2676			if(g_objParent.length == 0)
2677				return(false);
2678
2679			g_vars.is_parent_mode = true;
2680
2681			var optionsFromData = g_objParent.data("uc-remote-options");
2682
2683			if(optionsFromData)
2684				optionsAPI = optionsFromData;
2685
2686			if(optionsAPI)
2687				g_vars.options_api = optionsAPI;
2688
2689			var isDebug = g_objParent.data("debug");
2690
2691			if(typeof ucRemoteDebugEnabled != "undefined")
2692				isDebug = true;
2693
2694			g_vars.trace_debug = isDebug;
2695
2696			if(isDebug === true)
2697				addParentDebug(objParent);
2698
2699			var isSync = objParent.data("sync");
2700
2701			if(isSync == true)
2702				startParentSync();
2703
2704			if(g_vars.debug_show_ids == true){
2705				displayTextOnWidget(g_objParent, g_objParent.attr("id"), "debug");
2706			}
2707
2708		}catch(message){
2709
2710			displayErrorMessage(message);
2711
2712			return(false);
2713
2714		}
2715
2716	}
2717
2718	/**
2719	 * show the info
2720	 */
2721	this.showInfo = function(){
2722
2723		trace("parent");
2724		trace(g_objParent);
2725
2726		trace("current widget");
2727		trace(g_objWidget);
2728
2729
2730	}
2731
2732
2733	/**
2734	 * get the connected parent
2735	 */
2736	this.getParent = function(){
2737
2738		return(g_objParent);
2739	}
2740
2741}
2742
2743/**
2744 * remote connection class - for interacting with outside
2745 */
2746function UERemoteConnection(){
2747
2748	var t = this;
2749
2750	/**
2751	 * get object property
2752	 */
2753	this.getVal = function(obj, name, defaultValue){
2754
2755		if(!defaultValue)
2756			var defaultValue = "";
2757
2758		var val = "";
2759
2760		if(!obj || typeof obj != "object")
2761			val = defaultValue;
2762		else if(obj.hasOwnProperty(name) == false){
2763			val = defaultValue;
2764		}else{
2765			val = obj[name];
2766		}
2767
2768		return(val);
2769	}
2770
2771
2772	/**
2773	 * get the sync object, if not exists, create one
2774	 */
2775	this.getSyncObject = function(syncID){
2776
2777		var syncRealID = "uc_sync_"+syncID;
2778
2779		var objSync = t.getVal(window, syncRealID);
2780
2781		if(objSync)
2782			return(objSync);
2783		
2784		var objSync = new UESyncObject();
2785
2786		window[syncRealID] = objSync;
2787
2788		return(objSync);
2789	}
2790
2791
2792	/**
2793	 * get object synced other objets id's
2794	 */
2795	this.getSyncedElements = function(objElement){
2796
2797		if(!objElement)
2798			return(null);
2799
2800		if(objElement.length == 0)
2801			return(null);
2802
2803		if(objElement.hasClass("uc-remote-parent") == false)
2804			return(null);
2805
2806		var isSync = objElement.data("sync");
2807
2808		if(isSync !== true)
2809			return(null);
2810
2811		var syncID = objElement.data("syncid");
2812
2813		if(!syncID)
2814			return(null);
2815
2816		var objSync = t.getSyncObject(syncID);
2817
2818		var currentID = objElement.attr("id");
2819
2820		var arrElements = objSync.getElements(currentID);
2821
2822		return(arrElements);
2823	}
2824
2825}
2826
2827
2828//body init
2829
2830jQuery(document).on("uc-remote-parent-init",function(event, objParent, optionsAPI){
2831	
2832	var objRemote = new UERemoteWidgets();
2833	objRemote.onParentInit(objParent, optionsAPI);
2834	
2835});
2836
2837window.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.