/** * remote gallery api class */ function UERemoteGeneralAPI(){ var t = this, g_objParent; var g_isTypeEvents = false; var g_options = null; var g_vars = { class_items:"", class_active:"", selector_item_trigger:"", add_set_active_code:false, listen_class_change:true, enableDebug:false, is_editor:false, trigger_event: "click" }; var g_temp = { handle:null, trashold:50 }; /** * console log some string */ function trace(str){ console.log(str); } /** * get object property */ function getVal(obj, name, defaultValue){ return window.ueRemoteConnection.getVal(obj, name, defaultValue); } /** * run function with trashold */ function runWithTrashold(func, trashold){ if(g_temp.handle) clearTimeout(g_temp.handle); g_temp.handle = setTimeout(func, g_temp.trashold); }; /** * validate inited */ function validateInited(){ var isInited = g_objParent.data("remote_inited"); if(isInited == false) throw new Error("The remote parent not inited"); } /** * get items objet */ function getObjItems(){ var objItems = g_objParent.find("."+g_vars.class_items); return(objItems); } /** * get total items */ function getNumTotal(){ var objItems = g_objParent.find("."+g_vars.class_items); var numTotal = objItems.length; return(numTotal); } /** * get current item */ function getObjCurrentItem(){ var selector = "."+g_vars.class_items+"."+g_vars.class_active; var objCurrent = g_objParent.find(selector); return(objCurrent); } /** * get current item */ function getNumCurrent(){ var objCurrent = getObjCurrentItem(); if(objCurrent.length == 0) return(0); var index = objCurrent.index(); return(index); } /** * get item by index */ function getItem(index){ if(index < 0) index = 0; var objItems = getObjItems(); if(objItems.length == 0) return(null); if(index >= objItems.length ) index = objItems.length-1; var objItem = jQuery(objItems[index]); return(objItem); } /** * get item number */ function getItemNum(num){ var total = getNumTotal(); if(jQuery.isNumeric(num) == false) throw new Error("num item should be numeric"); if(num >= total ) num = total-1; if(num < 0) num = 0; if(!num) num = 0; if(typeof num == "undefined") num = 0; return(num); } /** * change item */ function changeItem(mixed){ var numItem = getItemNum(mixed); var objItem = getItem(numItem); if(objItem == null) return(false); var numCurrent = getNumCurrent(); if(numCurrent == numItem) return(false); if(!g_vars.selector_item_trigger){ objItem.trigger(g_vars.trigger_event); return(false); } var objInner = objItem.find(g_vars.selector_item_trigger); if(objInner.length == 0){ trace(objItem); throw new Error("Can't find inner by selector:"+g_vars.selector_item_trigger); } objInner.trigger(g_vars.trigger_event); } /* events */ this.onEvent = function(name, func){ validateInited(); switch(name){ case "change": g_objParent.on("uc_change", func); break; case "pause": // do nothing break; default: throw new Error("General API: Wrong event: "+name); break; } } /** * do some action */ this.doAction = function(action, arg1, arg2){ validateInited(); if(g_isTypeEvents == true){ var funcRunAction = getVal(g_options, "func_doAction"); if(!funcRunAction) throw new Error("Missing option: 'func_doAction' "); var response = g_options.func_doAction(action, arg1, arg2); return(response); } if(g_vars.enableDebug){ trace("DEBUG - Action: " + action+" arg1: "+arg1+" arg2: "+arg2); } switch(action){ case 'get_num_current': var current = getNumCurrent(); if(g_vars.enableDebug) trace("response: "+current); return(current); break; case "get_total_items": var total = getNumTotal(); if(g_vars.enableDebug) trace("response: "+total); return(total); break; case 'change_item': if(g_vars.enableDebug) console.trace(); changeItem(arg1); break; case "pause": case "play": break; default: throw new Error("General API: Wrong action: "+action); break; } } /** * listen to class change */ function initEvents_listenClassChange(){ var objItems = getObjItems(); if(g_vars.enableDebug == true){ trace("generalAPI: listen class change: "); trace(objItems); } jQuery.each(objItems, function(index, item){ var objItem = jQuery(item); var isSetObserver = objItem.data("uc_set_observer"); if(isSetObserver === true){ return(true); } var observer = new MutationObserver(function(records){ runWithTrashold(function(){ if(g_vars.enableDebug == true) trace("generalAPI: trigger item change"); g_objParent.trigger("uc_change"); }); }); var config = { attributes: true}; observer.observe(item, config); objItem.data("uc_set_observer", true); }); } /** * add set active events */ function initEvents_setActive(){ if(g_vars.enableDebug == true) trace("start initEvents_setActive") var objItems = getObjItems(); if(objItems.length == 0){ if(g_vars.enableDebug == true) trace("no items, exit") return(false); } //activate first item var objFirstItem = getItem(0); if(objFirstItem == null){ if(g_vars.enableDebug == true) trace("empty first item - exit") return(false); } objFirstItem.addClass(g_vars.class_active); objItems.on(g_vars.trigger_event, function(event){ var objItem = jQuery(this); //clicked element var objElement = jQuery(event.target); var isLink = objElement.is("a"); //quit on link inside if(isLink == true && objElement.hasClass(g_vars.class_items) == false){ return(true); } objItems.not(objItem).removeClass(g_vars.class_active); objItem.addClass(g_vars.class_active); g_objParent.trigger("uc_change"); event.preventDefault(); }); } /** * init obzerver events */ function initEvents(){ if(g_vars.enableDebug == true){ trace("generalAPI: init events"); trace(g_objParent); } if(g_vars.listen_class_change == true) initEvents_listenClassChange(); if(g_vars.add_set_active_code == true){ initEvents_setActive(); } } /** * get element */ this.getElement = function(){ return(g_objParent); } /** * get api type */ this.getAPIType = function(){ return("general"); } /** * init by classes */ function initByClasses(){ try{ var widgetName = g_objParent.data("widgetname"); g_vars.class_items = getVal(g_options, "class_items"); if(!g_vars.class_items) throw new Error(widgetName +" - missing 'class_items' option"); g_vars.class_active = getVal(g_options, "class_active"); if(!g_vars.class_active) throw new Error(widgetName +" - missing 'class_active' in options"); g_vars.selector_item_trigger = getVal(g_options, "selector_item_trigger"); g_vars.add_set_active_code = getVal(g_options, "add_set_active_code"); if(g_vars.add_set_active_code === true) g_vars.listen_class_change = false; } catch(e){ trace("ERROR: "+e); trace("passed options: "); trace(g_options); throw e; } } /** * init the api */ this.init = function(objParent, options, isEditor){ //not allow to init general api without options if(!options) return(false); g_vars.is_editor = isEditor; g_objParent = objParent; var connectType = getVal(options, "connect_type"); if(connectType == "events") g_isTypeEvents = true; //events allow to connect own functions g_options = options; var enableDebug = getVal(options, "trace_debug"); if(enableDebug == true) g_vars.enableDebug = true; if(g_vars.enableDebug == true){ trace("init general api"); trace(objParent); trace(options); } if(isEditor == true) g_vars.trigger_event = "ucclick"; if(g_isTypeEvents == false) initByClasses(); g_objParent.data("remote_inited", true); if(g_isTypeEvents == false){ if(g_vars.listen_class_change == true) setTimeout(initEvents, 1000); else initEvents(); g_objParent.on("uc_ajax_refreshed", function(){ setTimeout(initEvents,500) }); } return(true); } } /** * remote gallery api class */ function UERemoteGalleryAPI(){ var g_api, g_isInited; var g_objParent; var t = this; /** * console log some string */ function trace(str){ console.log(str); } /** * validate that the object is inited */ function validateInited(){ if(g_isInited == false) throw new Error("The owl carousel API is not inited"); } /** do some action */ this.doAction = function(action, arg1, arg2){ validateInited(); switch(action){ case 'get_num_current': var current = g_api.getNumCurrent(); return(current); break; case "get_total_items": var total = g_api.getNumItems(); return(total); break; case 'change_item': g_api.selectItem(arg1); break; case "is_playing": var isPlaying = g_api.isPlaying(); return(isPlaying); break; case "pause": g_api.stop(); break; case "play": g_api.play(); break; default: throw new Error("GALLERY API: Wrong action: "+action); break; } } /* events */ this.onEvent = function(name, func){ validateInited(); switch(name){ case "change": g_api.on("item_change", func); break; case "play": g_api.on("play",func); break; case "pause": g_api.on("stop",func); break; default: throw new Error("Gallery API: Wrong event: "+name); break; } } /** * get element */ this.getElement = function(){ return(g_objParent); } /** * get api type */ this.getAPIType = function(){ return("gallery"); } /** * init the api */ this.init = function(objParent, options){ g_api = objParent.data("unitegallery-api"); if(!g_api) return(false); g_objParent = objParent; g_isInited = true; return(true); } } /** * remote carousel api class */ function UERemoteCarouselAPI(){ var g_owlCarousel, g_owl, g_isInited; var t = this; var enableDebug = false; /** * console log some string */ function trace(str){ console.log(str); } /** * validate that the object is inited */ function validateInited(){ if(g_isInited == false) throw new Error("The owl carousel API is not inited"); } /** * get total items */ function getTotalItems(){ var total = g_owlCarousel.find(".owl-item:not(.cloned)").length; return(total); } /** * reset the autoplay if exists */ function resetAutoplay(){ if(g_owl.settings.autoplay == false) return(false); g_owlCarousel.trigger('stop.owl.autoplay'); g_owlCarousel.trigger('play.owl.autoplay'); } /** do some action */ this.doAction = function(action, arg1, arg2){ validateInited(); if(enableDebug == true){ trace("carousel action: "+action+" "+arg1+" "+arg2); } switch(action){ case "next": g_owlCarousel.trigger('next.owl.carousel'); break; case "prev": g_owlCarousel.trigger('prev.owl.carousel'); break; case "play": g_owlCarousel.trigger('start_autoplay.owl.autoplay'); break; case "pause": g_owlCarousel.trigger('stop.owl.autoplay'); break; case "is_playing": if (g_owl.settings.autoplay == true) return(true) else return(false); break; case "get_total_items": var total = getTotalItems() return(total); break; case "get_progress_time": var progressTime = g_owl.settings.autoplayTimeout / 1000; return(progressTime); break; case "get_modified_progress_time": var progressTime = (g_owl.settings.autoplayTimeout - g_owl.settings.smartSpeed) / 1000; return(progressTime); break; case 'get_num_current': var currentItem = g_owl.relative(g_owl.current()); if(enableDebug == true){ trace("num current: " + currentItem); } return(currentItem); break; case "get_total_text": var owlTotalItems = g_owlCarousel.find(".owl-item:not(.cloned)").length; if(owlTotalItems.toString().length < 2){ owlTotalItems = "0" + owlTotalItems; } return(owlTotalItems); break; case "get_current_text": var owlCurrentItem = g_owl.relative(g_owl.current()) + 1; if(owlCurrentItem.toString().length < 2){ owlCurrentItem = "0" + owlCurrentItem; } return(owlCurrentItem); break; case 'change_item': var total = getTotalItems() var currentItem = g_owl.relative(g_owl.current()); var slideNum = arg1; if(slideNum == currentItem) return(false); if(slideNum >= total) slideNum = (total-1); else if(slideNum < 0) slideNum = 0; g_owlCarousel.trigger('to.owl.carousel', [slideNum, null, true]); resetAutoplay(); break; default: throw new Error("Carousel API: Wrong action: "+action); break; } } /* events */ this.onEvent = function(name, func){ validateInited(); switch(name){ case "play": g_owlCarousel.on("play_autoplay.owl.carousel", func); break; case "pause": g_owlCarousel.on("stop_autoplay.owl.carousel", func); break; case "change": g_owlCarousel.on("changed.owl.carousel", func); break; case "transition_start": g_owlCarousel.on("translate.owl.carousel", func); break; case "transition_end": g_owlCarousel.on("translated.owl.carousel", func); break; case "refreshed": g_owlCarousel.on("refreshed.owl.carousel", func); break; default: console.error("Carousel API: Wrong event: "+name); throw new Error("Carousel API: Wrong event: "+name); break; } } /** * get api type */ this.getAPIType = function(){ return("carousel"); } /** * get the element */ this.getElement = function(){ return(g_owlCarousel); } /** * init the api */ this.init = function(objParent){ if(objParent.hasClass("owl-carousel") == false) throw new Error("owl-carousel class not found"); g_owlCarousel = objParent; g_owl = g_owlCarousel.data("owl.carousel"); if(!g_owl) return(false); g_isInited = true; return(true); } } /** * sync object */ function UESyncObject(){ var g_objApis = {}; var g_groupName, g_objIDs; var t = this; var g_vars = { is_editor:false, is_editor_func_started:false, show_debug:false }; /** * console log some string */ function trace(str){ console.log(str); } /** * validate api, that they match the existing by number of items */ function validate(objAPI){ if(g_objApis.length == 0) return(false); var numItems = objAPI.doAction("get_total_items"); //check with first existing api number of items for(var elID in g_objApis){ var firstExistingAPI = g_objApis[elID]; var numItemsExisting = firstExistingAPI.doAction("get_total_items"); if(numItemsExisting !== numItems) throw new Error("Sync failed, number of items should be the same. Now it's "+numItems+" and "+numItemsExisting); return(false); } } /** * set options */ this.setOptions = function(groupName, isEditor){ if(isEditor === true) g_vars.is_editor = true; if(!g_groupName) g_groupName = groupName; } /** * get api parent id */ function getElementID(objAPI){ var objElement = objAPI.getElement(); var elementID = objElement.attr("id"); return(elementID); } /** * get all ips except the given */ function mapAPIs(func, objElement){ if(typeof ucRemoteDebugEnabled != "undefined") g_vars.show_debug = true; var elementID = null; if(objElement){ var elementID = objElement.attr("id"); if(g_objApis.length == 1) return(null); } for(var elID in g_objApis){ var api = g_objApis[elID]; //except if exists if(elementID && elID == elementID) continue; func(api); } } /** * activate change command on all other apis */ function onItemChange(objAPI){ var numCurrent = objAPI.doAction("get_num_current"); var objElement = objAPI.getElement(); if(g_vars.show_debug == true){ trace("sync onchange: " + numCurrent); trace(objElement); trace(g_objApis); } mapAPIs(function(api){ api.doAction("change_item", numCurrent); }, objElement); } /** * on pause - pause others as well */ function onPause(objAPI){ var objElement = objAPI.getElement(); mapAPIs(function(api){ api.doAction("pause"); }, objElement); } /** * trigger some action */ function trigger(action, params){ var realAction = "uc_remote_sync_"+g_groupName+"_action_"+action; jQuery("body").trigger(realAction, params); } /** * on event */ this.on = function(action, func){ var realAction = "uc_remote_sync_"+g_groupName+"_action_"+action; jQuery("body").on(realAction, func); } /** * get debug text */ this.getDebugText = function(objElement){ var text = "sync group: " + g_groupName+", "; var textWidgets = ""; mapAPIs(function(api){ var objElement = api.getElement(); var widgetName = objElement.data("widgetname"); var widgetID = objElement.attr("id"); if(textWidgets) textWidgets += ", "; textWidgets += "" + widgetName + ""; }, objElement); if(textWidgets) text += "sync with: " + textWidgets; return(text); } /** * remove deleted from page APIs */ function removeDeletedAPIs(){ var objAPIsNew = {}; mapAPIs(function(api){ var elementID = getElementID(api); var objElement = jQuery("#"+elementID); if(objElement.length == 0) return(false); var parent = objElement.parent(); objAPIsNew[elementID] = api; }); g_objApis = objAPIsNew; } /** * on editor check */ function onEditorCheck(){ removeDeletedAPIs(); trigger("update_debug", g_groupName); } /** * get group name */ this.getGroupName = function(){ return(g_groupName); } /** * add widget to sync object */ this.addAPI = function(objAPI){ var id = getElementID(objAPI); if(g_objApis.hasOwnProperty(id)) return(false); g_objApis[id] = objAPI; if(g_vars.is_editor == true) removeDeletedAPIs(); validate(objAPI); //debug var objElement = objAPI.getElement(); //add debug trigger("update_debug", g_groupName); //set events objAPI.onEvent("change", function(){ onItemChange(objAPI); }); //sync objects pause objAPI.onEvent("pause", function(){ onPause(objAPI); }); if(g_vars.is_editor == true && g_vars.is_editor_func_started == false){ setInterval(onEditorCheck, 700); g_vars.is_editor_func_started = false; } } /** * get all elements */ this.getElements = function(exceptID){ if(!g_objApis) return(null); var arrElements = []; //check with first existing api number of items for(var elID in g_objApis){ if(exceptID && exceptID == elID) continue; var objApi = g_objApis[elID]; var objElement = objApi.getElement(); arrElements.push(objElement); } if(arrElements.length == 0) return(null); return(arrElements); } } /** * --------------------------------------------------- * remote widget api class */ function UERemoteWidgets(){ var g_objParent, g_objWidget, g_parentID; var g_api, g_objSync, g_remoteConnection = window.ueRemoteConnection; var t = this; var g_vars = { is_inited:false, funcOnInit:null, is_editor:null, widget_id:null, init_options:null, is_parent_mode: false, syncid:null, options_api:null, show_connection_debug:false, debug_show_ids:false, debug_show_widget: "", trace_debug:false, //debug show_trace_when_debug_on: false }; var g_types = { CAROUSEL:"carousel", GALLERY:"gallery", GENERAL:"general" }; /** * console log some string */ function trace(str){ console.log(str); } /** * get object property */ function getVal(obj, name, defaultValue){ return window.ueRemoteConnection.getVal(obj, name, defaultValue); } function _______INIT_________(){} /** * init widget */ function initWidget(widgetID){ g_objWidget = jQuery("#"+widgetID); if(g_objWidget.length == 0) throw new Error("Widget not found by id: "+widgetID); g_vars.widget_id = widgetID; var forceID = getVal(g_vars.init_options, "force_parentid"); if(forceID) g_parentID = forceID; else g_parentID = g_objWidget.data("parentid"); if(!g_parentID) throw new Error("Parent controlled ID not set"); } /** * get controlled parent type */ function getParentType(){ if(!g_objParent || g_objParent.length == 0) throw new Error("getParentType: no parent found"); if(g_objParent.hasClass("owl-carousel")) return(g_types.CAROUSEL); var dataType = g_objParent.data("remote-type"); switch(dataType){ case "gallery": return g_types.GALLERY; break; } return(g_types.GENERAL); } /** * get offsets distance */ function getOffsetsDistance(offset1, offset2){ var dx = offset2.left-offset1.left; var dy = offset2.top-offset1.top; return Math.sqrt(dx*dx+dy*dy); } /** * get closest object by offset */ function getClosestByOffset(objParents, objElement){ var objClosest = null; var minDiff = 1000000; var elementOffset = objElement.offset(); if(g_vars.trace_debug){ trace("Widget Offset: "); trace(elementOffset); } jQuery.each(objParents, function(index, parent){ var objParent = jQuery(parent); var parentOffset = objParent.offset(); if(parentOffset.top == 0){ var firstParent = getWidgetContainer(objParent); var parentOffset = firstParent.offset(); } var distance = getOffsetsDistance(parentOffset, elementOffset); if(g_vars.trace_debug){ trace("Parent offset: "); trace(objParent); trace(parentOffset); trace("distance: " + distance); } if(distance < minDiff){ minDiff = distance; objClosest = objParent; } }); return(objClosest); } /** * filter parents by section */ function filterParentsBySection(objParents, objElement){ var objSection = objElement.closest(".elementor-top-section"); if(objSection.length == 0) return(objParents); var section = objSection[0]; var objFiltered = objParents.filter(function(index, parent){ var isContains = jQuery.contains(section, parent); return isContains; }); if(objFiltered.length) return(objFiltered); return(objParents); } /** * detect closest parent */ function detectClosestParent(objParents){ if(!objParents) var objParents = jQuery(".uc-remote-parent").not(g_objWidget); if(g_vars.trace_debug){ trace("detect closest start. group:"); trace(objParents); } var numParents = objParents.length; if(numParents == 0) return(null); if(numParents == 1) return(objParents); //filter by auto if(g_vars.trace_debug) trace("filter auto"); var objParentsFiltered = objParents.filter("[data-remoteid='"+g_parentID+"']"); if(objParentsFiltered.length == 1) return(objParentsFiltered); //find by offset if(g_vars.trace_debug){ trace("filter by section"); } var objParents = filterParentsBySection(objParents, g_objWidget); if(g_vars.trace_debug){ trace(objParents); } if(objParents.length == 1) return(objParents); if(g_vars.trace_debug) trace("get closest by parent"); var objClosest = getClosestByOffset(objParents, g_objWidget); if(objClosest) return(objClosest); if(g_vars.trace_debug) trace("get first"); var firstParent = jQuery(objParentsFiltered[0]); return(firstParent); } /** * set parent object */ function setParentObject(){ var objForceParent = getVal(g_vars.init_options, "force_parent_obj"); var widgetID = g_objWidget.attr("id"); if(g_vars.trace_debug) trace("start set parent for: "+widgetID); if(objForceParent){ g_objParent = objForceParent; if(g_vars.trace_debug){ trace("set force parent"); trace(g_objParent); } return(false); } if(!g_parentID) throw new Error("Parent controller ID not found"); if(!g_objParent || g_objParent.length == 0){ if(g_parentID == "auto"){ if(g_vars.trace_debug){ trace("auto detect selected"); } g_objParent = detectClosestParent(); if(g_vars.trace_debug){ trace("detect closest"); trace(g_objParent); } if(!g_objParent) throw new Error("Can't detect remote parent"); } else{ var objParents = jQuery(".uc-remote-parent[data-remoteid='"+g_parentID+"']").not(g_objWidget); if(g_vars.trace_debug) trace("Detect from group: "+g_parentID); g_objParent = detectClosestParent(objParents); if(g_vars.trace_debug){ trace("detected from group"); trace(g_objParent); } if(!g_objParent || g_objParent.length == 0) throw new Error("Parent widget with remote name: '"+g_parentID+"' not found"); } } if(g_objParent && g_objParent.length > 1){ g_objParent = jQuery(g_objParent[0]); } if(g_vars.trace_debug == true){ var parentID = g_objParent.attr("id"); var widgetID = g_objWidget.attr("id"); trace("widget: "+widgetID+" connected to: "+parentID); } if(!g_objParent || g_objParent.length == 0) throw new Error("Remote parent not found"); } /** * init api variable */ function initAPI(){ if(g_vars.trace_debug == true){ trace("start init api function"); } //set type and related objects if(!g_api){ var parentType = getParentType(); if(!parentType){ trace(g_objParent); throw new Error("No parent type found"); } if(g_vars.trace_debug == true){ trace("init api: " + parentType); trace(g_objParent); } //init the api switch(parentType){ case g_types.CAROUSEL: g_api = new UERemoteCarouselAPI(); break; case g_types.GENERAL: g_api = new UERemoteGeneralAPI(); break; case g_types.TABS: //g_api = new UERemoteTabsAPI(); g_api = new UERemoteGeneralAPI(); break; case g_types.GALLERY: g_api = new UERemoteGalleryAPI(); break; default: throw new Error("Wrong parent type: "+parentType); break; } } var optionsFromData = g_objParent.data("uc-remote-options"); var isEditor = isInsideEditor(); if(optionsFromData) g_vars.options_api = optionsFromData; if(g_vars.trace_debug == true){ if(g_vars.options_api) trace(g_vars.options_api); else g_vars.options_api = {}; g_vars.options_api.trace_debug = true; } var isInited = g_api.init(g_objParent, g_vars.options_api, isEditor); if(g_vars.trace_debug == true){ trace("inited: " + isInited); } return(isInited); } /** * init parent */ function initParent(){ setParentObject(); var isInited = initAPI(); return(isInited); } /** init global helper function */ function initGlobal(widgetID, func){ if(!g_objWidget) initWidget(widgetID); //init the debug related var isDebug = g_objWidget.data("debug"); if(isDebug === true || typeof ucRemoteDebugEnabled != "undefined"){ if(g_vars.show_trace_when_debug_on == true) g_vars.trace_debug = true; g_vars.show_connection_debug = true; } g_vars.is_inited = initParent(); if(g_vars.is_inited == false){ if(g_vars.trace_debug == true){ trace(g_objParent); trace("set object ready event"); //onWidgetInit } g_objParent.on("uc-object-ready", func); } } /** * set action, bind to some object * objElement can be jQuery object or selector */ this.setAction = function(action, objElement, allowMultiple){ if(g_vars.trace_debug == true){ trace("set action: "+action); } if(g_vars.is_inited == false) throw new Error("Widget not inited"); if(typeof objElement == "string"){ var selector = objElement; objElement = g_objWidget.find(objElement); if(objElement.length == 0) throw new Error("Remote '"+action+"' action error: element: "+selector+" not found"); } if(!objElement || objElement.length == 0) throw new Error("Element not inited"); if(!g_api) throw new Error("API not inited!"); //avoid double action var linkedAction = objElement.data("uc-action"); if(allowMultiple !== true) if(linkedAction) return(false); objElement.data("uc-action", action); objElement.on("click",function(){ var objElement = jQuery(this); if(objElement.hasClass("uc-disabled")) return(true); t.doAction(action); }); } /** * run this function after the widget is ready to use */ function onWidgetReady(){ checkWidgetDebug(); var isEditorMode = isInsideEditor(); //in editor mode check debug every second if(isEditorMode == true){ hideErrorOnWidget(); setInterval(checkWidgetInsideEditor, 700); } } function _______TEXT_ON_WIDGET_________(){} /** * hide error on widget */ function hideErrorOnWidget(){ if(!g_objWidget || g_objWidget.length == 0) return(false); var objParent = getWidgetContainer(g_objWidget); //don't hide if no message var objError = objParent.find('.uc-remote-error'); if(objError.length == 0) return(false); if(objError.is(":visible") == false) return(false); objError.hide(); g_objWidget.css({ "border" : "none" }); //try to set the debug if avaliable checkWidgetDebug(); } /** * get widget container */ function getWidgetContainer(objWidget){ var objParent = objWidget.parents(".elementor-widget-container"); if(objParent.length == 0) objParent = objWidget.parent(); return(objParent); } /** * add error message div on the widget div * */ function addTextDiv(objWidget, type){ var objParent = getWidgetContainer(objWidget); var isDebug = (type == "debug"); var className = "uc-remote-error"; if(isDebug == true) className = "uc-remote-debug"; var divText = "
"; objParent.append(divText); var objError = objParent.find('.'+className+''); var css = { "position":"absolute", "color":"red", "top":"-30px", "left":"0px", "z-index":"999999", "background-color":"#ffffff" }; if(isDebug == true){ css["color"] = "green"; css["z-index"] = "999998"; } //fix position for bg var objParentsBG = objParent.parents(".unlimited-elements-background-overlay"); if(objParentsBG.length){ css["top"] = "0px"; } objError.css(css); var objError = objParent.find('.'+className+''); return(objError); } /** * display some error on widget interface */ function displayTextOnWidget(objWidget, message, type){ var isDebug = (type == "debug"); var className = "uc-remote-error"; if(isDebug == true) className = "uc-remote-debug"; var objParent = getWidgetContainer(objWidget); objText = objParent.find("."+className); //add error div if missing. pause error in editor //second time the div will be not empty and it will show the message if(objText.length == 0){ objText = addTextDiv(objWidget, type); if(isDebug == false){ var isInEditor = isInsideEditor(); if(isInEditor == true){ setTimeout(function(){ displayTextOnWidget(objWidget, message, type); },2000); return(false); } } } //add the error border if(isDebug == false){ objWidget.css({ "border" : "2px solid red", "position" : "relative" }); } objText.show(); objText.html(message); } /** * display error message */ function displayErrorMessage(message){ //trace(message); //console.trace(); if(g_vars.is_parent_mode == false){ if(g_objWidget && g_objWidget.length) displayTextOnWidget(g_objWidget, message,"error"); }else{ displayTextOnWidget(g_objParent, message, "error"); } //console.log("UE Remote Error: "+message); //console.log(message); } function _______DEBUG_________(){} /** * return if the debug is active */ function isDebugActive(objWidget){ if(!objWidget) objWidget = g_objWidget; var isActive = objWidget.data("debug_active"); if(isActive === true) return(true); return(false); } /** * remove debug visual from the widget */ function removeDebugVisual(objWidget){ if(!objWidget) objWidget = g_objWidget; g_objWidget.data("debug_active", false); g_objWidget.css({ "border-style":"none" }); } /** * set debug visual */ function setDebugVisual(color, objWidget){ if(!objWidget) objWidget = g_objWidget; objWidget.data("debug_active", true); objWidget.css({ "border-style":"solid", "border-width":"3px", "border-color":color }); } /** * check if parent debug is active */ function isParentDebugActive(objParent){ var dataDebug = objParent.data("debug"); var isDebug = (dataDebug === true); return(isDebug); } /** * check widget debug work */ function checkWidgetDebugWork(objWidget, objParent){ if(!objWidget) objWidget = g_objWidget; if(!objParent) objParent = g_objParent; var isDebug = isParentDebugActive(objParent); var isActive = isDebugActive(objWidget); /* trace("check! "+isActive+" "+isDebug); trace(objParent); trace(objWidget); */ //remove debug if active but no need if(isDebug == false){ if(isActive == true) removeDebugVisual(objWidget); return(false); } //add debug is not in debug mode if(isActive == false){ //get parent color var color = addParentDebug(objParent); setDebugVisual(color, objWidget); } } /** * check and put debug connection */ function checkDebugConnectionText(){ if(!g_objWidget) return(false); if(g_vars.show_connection_debug == false) return(false); if(!g_objParent || g_objParent.length == 0) throw new Error("Not conneted to no parent"); var widgetName = g_objParent.data("widgetname"); var widgetID = g_objParent.attr("id"); var text = "connected to " + widgetName + ""; displayTextOnWidget(g_objWidget, text, "debug"); } /** * check widget debug */ function checkWidgetDebug(){ var noDebugCheck = getVal(g_vars.init_options, "no_debug_check"); if(noDebugCheck === true) return(false); //get debug color if(!g_objParent || g_vars.is_inited == false){ removeDebugVisual(); return(false); } checkWidgetDebugWork(); checkDebugConnectionText(); } /** * on api event */ this.onEvent = function(name, func){ g_api.onEvent(name,func); } /** * change item by action (0 - total-1) */ function changeItemByAction(dir){ var current = t.doAction("get_num_current"); var total = t.doAction("get_total_items"); switch(dir){ case "next": var num = current+1; if(num >= total ) num = 0; break; case "prev": var num = current-1; if(num < 0) num = total-1; break; default: throw new Error("wrong direction type: "+dir); break; } t.doAction("change_item", num); } /** * do api action */ this.doAction = function(action, arg1, arg2){ if(g_vars.trace_debug){ trace("Do Action: "); trace(action+ " "+arg1+" "+arg2); } switch(action){ case "prev": case "next": var apiType = g_api.getAPIType(); if(apiType == "carousel"){ g_api.doAction(action); return(false); } changeItemByAction(action); return(false); break; } var response = g_api.doAction(action, arg1, arg2); if(g_vars.trace_debug){ trace("Response: "); trace(response); } return(response); } /** * add the parent some debug color */ function addParentDebug(objParent){ if(!objParent) objParent = g_objParent; var color = g_objParent.data("uc-debug-color"); if(color) return(color); var objBody = jQuery("body"); var dataColors = "uc-remote-debug-colors"; var objColors = objBody.data(dataColors); if(!objColors){ objColors = ["#ffeb00","blue","#808000","#d1e231","#01796f","#8e4585","#ff33cc","#436b95","#eaa221","#b86d29"]; } var color = objColors.pop(); g_objParent.data("uc-debug-color", color); objBody.data(dataColors, objColors); g_objParent.css("border","3px solid "+color); return(color); } /** * update sync debug */ function updateSyncDebug(event, syncID){ //if show id's disable other debug if(g_vars.debug_show_ids == true) return(false); try{ if(syncID != g_vars.syncid){ var name = g_objParent.data("widgetname"); throw new Error("Wrong sync group mishmash "+g_vars.syncid+" and " + syncID); } var debugText = g_objSync.getDebugText(g_objParent); if(!debugText) return(false); displayTextOnWidget(g_objParent, debugText, "debug"); }catch(error){ displayErrorMessage(error); } } function _______EDITOR_RELATED_________(){} /** * check if nside editor */ function isInsideEditor(){ if(g_vars.is_editor !== null) return(g_vars.is_editor); if(typeof window.parent == "undefined"){ g_vars.is_editor = false; return(false); } if(typeof window.parent.elementor != "undefined"){ g_vars.is_editor = true; return(true); } g_vars.is_editor = false; return(false); } /** * reset the settings */ function resetSettingsInsideEditor(){ g_objParent = null; g_api = null; g_vars.is_inited = false; } /** * check widget inside editor */ function checkWidgetInsideEditor(){ //check for disconnect try{ hideErrorOnWidget(); if(g_vars.is_inited == true){ if(g_objParent.is(":hidden")){ //disconnect resetSettingsInsideEditor(); } }else{ //check for connect g_vars.is_inited = initParent(); if(g_vars.is_inited == true){ g_vars.funcOnInit(); } else if(g_vars.is_inited == false){ g_objParent.on("uc-object-ready", function(){ g_vars.is_inited = true; g_vars.funcOnInit(); }); } } checkWidgetDebug(); }catch(message){ displayErrorMessage(message); return(false); } } /** * on widget init */ this.onWidgetInit = function(widgetID, func, options){ try{ if(g_vars.trace_debug == true){ trace("on widget init"); } if(!g_vars.funcOnInit){ if(typeof func != "function") throw new Error("onWidgetInit error: the second parameter should be a function"); g_vars.funcOnInit = func; } if(options && g_vars.init_options == null) g_vars.init_options = options; if(g_vars.debug_show_widget && g_vars.debug_show_widget == widgetID) g_vars.trace_debug = true; initGlobal(widgetID, t.onWidgetInit); if(g_vars.is_inited == false){ if(g_vars.trace_debug == true){ trace(widgetID+" not inited yet, waiting for parent init"); } return(false); } //show id's on the widgets if(g_vars.debug_show_ids == true){ trace("start debug show id's"); displayTextOnWidget(g_objWidget, g_objWidget.attr("id"), "debug"); } if(g_vars.trace_debug == true) trace("start debug - show connect"); if(g_objParent.length > 1){ trace(g_objWidget); trace(g_objParent); throw new Error("Remote widget can't connect to more then 1 parents"); } //widget is inited onWidgetReady(); g_vars.funcOnInit(g_objWidget); }catch(message){ displayErrorMessage(message); var isEditorMode = isInsideEditor(); //in editor mode check debug every second if(isEditorMode == true) setInterval(checkWidgetInsideEditor, 700); return(false); } } /** * start sync */ function startParentSync(){ var syncID = g_objParent.data("syncid"); if(g_vars.trace_debug == true){ trace("Start parent sync"); trace(g_objParent); } if(!syncID){ if(g_vars.trace_debug == true){ trace("no sync id"); } return(false); } var objSync = g_remoteConnection.getSyncObject(syncID); var isEditorMode = isInsideEditor(); objSync.setOptions(syncID, isEditorMode); var isInited = initAPI(); if(isInited == false){ var widgetID = g_objParent.attr("id"); var parentType = getParentType(); var message = "Sync Error - can't init api for "+widgetID; if(parentType == g_types.CAROUSEL){ message += ", please check that the owl carousel js file loading from unlimited elements plugin."; }else{ message += ", please check if the widget is inited and working."; } throw new Error(message); } g_vars.syncid = syncID; //add debug event listener if(g_vars.trace_debug === true) objSync.on("update_debug", updateSyncDebug); g_objSync = objSync; objSync.addAPI(g_api); //if(isEditorMode == true) //setInterval(checkSyncInsideEditor, 700); } /** * parent init, init the debug */ this.onParentInit = function(objParent, optionsAPI){ try{ g_objParent = objParent; if(!g_objParent) return(false); if(g_objParent.length == 0) return(false); g_vars.is_parent_mode = true; var optionsFromData = g_objParent.data("uc-remote-options"); if(optionsFromData) optionsAPI = optionsFromData; if(optionsAPI) g_vars.options_api = optionsAPI; var isDebug = g_objParent.data("debug"); if(typeof ucRemoteDebugEnabled != "undefined") isDebug = true; g_vars.trace_debug = isDebug; if(isDebug === true) addParentDebug(objParent); var isSync = objParent.data("sync"); if(isSync == true) startParentSync(); if(g_vars.debug_show_ids == true){ displayTextOnWidget(g_objParent, g_objParent.attr("id"), "debug"); } }catch(message){ displayErrorMessage(message); return(false); } } /** * show the info */ this.showInfo = function(){ trace("parent"); trace(g_objParent); trace("current widget"); trace(g_objWidget); } /** * get the connected parent */ this.getParent = function(){ return(g_objParent); } } /** * remote connection class - for interacting with outside */ function UERemoteConnection(){ var t = this; /** * get object property */ this.getVal = function(obj, name, defaultValue){ if(!defaultValue) var defaultValue = ""; var val = ""; if(!obj || typeof obj != "object") val = defaultValue; else if(obj.hasOwnProperty(name) == false){ val = defaultValue; }else{ val = obj[name]; } return(val); } /** * get the sync object, if not exists, create one */ this.getSyncObject = function(syncID){ var syncRealID = "uc_sync_"+syncID; var objSync = t.getVal(window, syncRealID); if(objSync) return(objSync); var objSync = new UESyncObject(); window[syncRealID] = objSync; return(objSync); } /** * get object synced other objets id's */ this.getSyncedElements = function(objElement){ if(!objElement) return(null); if(objElement.length == 0) return(null); if(objElement.hasClass("uc-remote-parent") == false) return(null); var isSync = objElement.data("sync"); if(isSync !== true) return(null); var syncID = objElement.data("syncid"); if(!syncID) return(null); var objSync = t.getSyncObject(syncID); var currentID = objElement.attr("id"); var arrElements = objSync.getElements(currentID); return(arrElements); } } //body init jQuery("body").on("uc-remote-parent-init",function(event, objParent, optionsAPI){ var objRemote = new UERemoteWidgets(); objRemote.onParentInit(objParent, optionsAPI); }); window.ueRemoteConnection = new UERemoteConnection();