/* ********************************************************************************* * Weaver Xtreme JavaScript support Library * * Author: WeaverTheme - www.weavertheme.com * @version 3.1.12 * @license GNU Lesser General Public License, http://www.gnu.org/copyleft/lesser.html * @author Bruce Wampler * * Notes - this library requires jQuery to be loaded * this library was cobbled together over a long period of time, so it contains a * bit of a jumble of straight JavaScript and jQuery calls. So it goes. It works. * * ************************************************************************************* */ //Initial load of page var agent = navigator.userAgent; // Safari is breaking our generated extend width CSS, so by removing the .wvrx-not-safari class from body, // we can force the JS to fix it. For whatever reason, the Safari agend string included both Chrome and Safari. Bizarre! if (agent.match(/Safari/i) && !agent.match(/Chrome/i)) { // run document ready just for Safari to get around full width issues jQuery(document).ready(weaverxOnResize); } //jQuery(document).ready(weaverxOnResize); // don't really nned this for non-safari - it results in a double call on initial load // *********************************** >>> JavaScript Functions <<< ******************************************* // *********************************** >>> weaverxBrowserWidth <<< ******************************************* function weaverxBrowserWidth() { // This is a cross-browser way to get the window width. We will use it in all script // tht need the width to endure consistent treatement of the width. var width = 768; if (typeof(window.innerWidth) == 'number') { width = window.innerWidth; //Non-IE } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) { width = document.documentElement.clientWidth; //IE 6+ in 'standards compliant mode' } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) { width = document.body.clientWidth; //IE 4 compatible } return width; } (function($) { "use strict"; })(window.jQuery); // *********************************** >>> Detect Element Resize Plugin for jQuery <<< ******************************************* /** * Detect Element Resize Plugin for jQuery * * https://github.com/sdecima/javascript-detect-element-resize * Sebastian Decima * * version: 0.5.3 * * Weaver X Mod - clean up name space: resize -> resizeX just jquery definition (4 of them) **/ (function($) { function resetTriggers(element) { var triggers = element.__resizeTriggers__, expand = triggers.firstElementChild, contract = triggers.lastElementChild, expandChild = expand.firstElementChild; contract.scrollLeft = contract.scrollWidth; contract.scrollTop = contract.scrollHeight; expandChild.style.width = expand.offsetWidth + 1 + 'px'; expandChild.style.height = expand.offsetHeight + 1 + 'px'; expand.scrollLeft = expand.scrollWidth; expand.scrollTop = expand.scrollHeight; } function checkTriggers(element) { return element.offsetWidth != element.__resizeLast__.width || element.offsetHeight != element.__resizeLast__.height; } function scrollListener(e) { var element = this; resetTriggers(this); if (this.__resizeRAF__) cancelFrame(this.__resizeRAF__); this.__resizeRAF__ = requestFrame(function() { if (checkTriggers(element)) { element.__resizeLast__.width = element.offsetWidth; element.__resizeLast__.height = element.offsetHeight; element.__resizeListeners__.forEach(function(fn) { fn.call(element, e); }); } }); } var attachEvent = document.attachEvent, stylesCreated = false; var jQuery_resizeX = $.fn.resizeX; $.fn.resizeX = function(callback) { return this.each(function() { if (this == window) jQuery_resizeX.call(jQuery(this), callback); else addResizeListener(this, callback); }); }; $.fn.removeResize = function(callback) { return this.each(function() { removeResizeListener(this, callback); }); }; if (!attachEvent) { var requestFrame = (function() { var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || function(fn) { return window.setTimeout(fn, 20); }; return function(fn) { return raf(fn); }; })(); var cancelFrame = (function() { var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.clearTimeout; return function(id) { return cancel(id); }; })(); /* Detect CSS Animations support to detect element display/re-attach */ var animation = false, animationstring = 'animation', keyframeprefix = '', animationstartevent = 'animationstart', domPrefixes = 'Webkit Moz O ms'.split(' '), startEvents = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(' '), pfx = ''; { var elm = document.createElement('fakeelement'); if (elm.style.animationName !== undefined) { animation = true; } if (animation === false) { for (var i = 0; i < domPrefixes.length; i++) { if (elm.style[domPrefixes[i] + 'AnimationName'] !== undefined) { pfx = domPrefixes[i]; animationstring = pfx + 'Animation'; keyframeprefix = '-' + pfx.toLowerCase() + '-'; animationstartevent = startEvents[i]; animation = true; break; } } } } var animationName = 'resizeanim'; var animationKeyframes = '@' + keyframeprefix + 'keyframes ' + animationName + ' { from { opacity: 0; } to { opacity: 0; } } '; var animationStyle = keyframeprefix + 'animation: 1ms ' + animationName + '; '; } function createStyles() { if (!stylesCreated) { //opacity:0 works around a chrome bug https://code.google.com/p/chromium/issues/detail?id=286360 var css = (animationKeyframes ? animationKeyframes : '') + '.resize-triggers { ' + (animationStyle ? animationStyle : '') + 'visibility: hidden; opacity: 0; } ' + '.resize-triggers, .resize-triggers > div, .contract-trigger:before { content: \" \"; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before { width: 200%; height: 200%; }', head = document.head || document.getElementsByTagName('head')[0], style = document.createElement('style'); style.type = 'text/css'; if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } head.appendChild(style); stylesCreated = true; } } window.addResizeListener = function(element, fn) { if (attachEvent) element.attachEvent('onresize', fn); else { if (!element.__resizeTriggers__) { if (getComputedStyle(element).position == 'static') element.style.position = 'relative'; createStyles(); element.__resizeLast__ = {}; element.__resizeListeners__ = []; (element.__resizeTriggers__ = document.createElement('div')).className = 'resize-triggers'; element.__resizeTriggers__.innerHTML = '
' + ''; element.appendChild(element.__resizeTriggers__); resetTriggers(element); element.addEventListener('scroll', scrollListener, true); /* Listen for a css animation to detect element display/re-attach */ animationstartevent && element.__resizeTriggers__.addEventListener(animationstartevent, function(e) { if (e.animationName == animationName) resetTriggers(element); }); } element.__resizeListeners__.push(fn); } }; window.removeResizeListener = function(element, fn) { if (attachEvent) element.detachEvent('onresize', fn); else { element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1); if (!element.__resizeListeners__.length) { element.removeEventListener('scroll', scrollListener); element.__resizeTriggers__ = !element.removeChild(element.__resizeTriggers__); } } }; }(jQuery)); // *********************************** >>> Menu Script from Sigma <<< ******************************************* /*! Menu Script from Sigma - v0.1.2 * http://stephenharris.info * Copyright (c) 2014; * Licensed GPLv2+ * * Modified by WeaverTheme * This code requires the Android Drop-Down fix included in this library to handle older Android devices. * */ if (!Object.create) { // IE8 shim for Object.create Object.create = (function() { function F() {} return function(o) { if (arguments.length != 1) { throw new Error('Object.create implementation only accepts one parameter.'); } F.prototype = o; return new F(); }; })(); } (function($, window, undefined) { 'use strict'; var Menu = { options: { mobileBreakpoint: 768, // don't change this - corresponds to small-tablet/desktop split hideToggle: false, // set to true if want a tablet sized vertical accordion menu toggleButtonID: 'menu-toggle-button', hoverClass: 'menu-hover', arrowClass: 'menu-arrows', mobileClass: 'is-mobile-menu', hideMobileClass: 'is-hidden', // this shows/hides the top level menu items on the mobile view, set to not-hidden to not hide hasSubmenuClass: 'has-submenu', openSubmenuClass: 'is-open-submenu', toggleSubmenuClass: 'toggle-submenu' }, init: function(el, options) { var menu = this, doCallback = true, // Window resize throttle flag. mo; menu.el = $(el); menu.isTouch = false; mo = menu.options = $.extend({}, menu.options, options); // Check for device touch support. // This code doesn't work for whatever reason - breaks iOS // So, we will use the force Android to mobile //if ('ontouchstart' in document.documentElement ) { // menu.isTouch = true; // menu.el.removeClass(mo.hoverClass); //} // Initialize the menu container. menu.initContainer(); // Initialize the toggle button. menu.initToggleButton(); menu.el.addClass(mo.arrowClass) .find('ul').parent().addClass(mo.hasSubmenuClass) .children('a').attr('aria-haspopup', true).append(''); // prepend/append // Catch click events on submenu toggle handlers. menu.el.on('click', '.' + mo.toggleSubmenuClass, function(e) { if (menu.el.hasClass(mo.mobileClass)) { e.preventDefault(); menu.toggleSubmenu(this); } }); // Initialize the mobile menu. menu.toggleMobile(); // User resizeX lib to handle menu resizing $('#wrapper').resizeX(function() { menu.toggleMobile(); }); /* original resizer via timer // Throttle the resize event. $(window).on('resize', function() { if ( doCallback ) { doCallback = false; setTimeout( function() { menu.toggleMobile(); doCallback = true; }, 150 ); } }); */ }, /** * Select or create a container around the menu. * * The menu container is used for determining the width of the menu when * it's hidden as well as to provide a context for inserting a toggle * button if one doesn't already exist. */ initContainer: function() { // Select the toggle button. this.container = this.el.closest('.wvrx-menu-container'); // Automatically add a container div if one doesn't exist. if (this.container.length < 1) { this.container = this.el.wrap('').parent(); } }, /** * Select or create a mobile toggle button. * * The mobile toggle button will show or hide the menu when it's in a * mobile state. */ initToggleButton: function() { var menu = this, mo = menu.options; // Select the toggle button. menu.toggleButton = $('#' + mo.toggleButtonID); // Automatically insert a toggle button icon - dashicon if (menu.toggleButton.length < 1) { if (!mo.hideToggle) { if (typeof wvrxOpts !== 'undefined' && wvrxOpts.mobileAltLabel === '') menu.toggleButton = menu.container.prepend('').find('#' + mo.toggleButtonID).hide(); else menu.toggleButton = menu.container.prepend('').find('#' + mo.toggleButtonID).hide(); } else { menu.toggleButton = menu.container.find('#' + mo.toggleButtonID).hide(); } } // Add listener to the menu toggle button. menu.toggleButton.on('click', function() { menu.el.toggleClass(mo.hideMobileClass); }); // Add listener to the menu items to close mobile menu when an item is clicked. // Useful if menu items link to anchors in the same page and therefore do not load a new page menu.el.find('a').click(function() { if( $(this).children('span.toggle-submenu').length === 0 ) { //dont close mobile menu when clicking to open a sub menu menu.el.toggleClass(mo.hideMobileClass); } }); }, /** * Toggle the menu's mobile state depending on the width of the viewport. * */ toggleMobile: function() { var mo = this.options, width = 0; width = weaverxBrowserWidth(); // Check if viewport width is less than the mobile breakpoint setting and the mobile menu is not displayed yet. if ((width < mo.mobileBreakpoint) && !this.el.hasClass(mo.mobileClass)) { // Show the menu toggle button. this.toggleButton.show(); //this.toggleButton.css('display', 'inline'); // Add the mobile class to the menu element. this.el.addClass(mo.mobileClass).addClass(mo.hideMobileClass).removeClass(mo.hoverClass); } // Check if viewport width is greater than the mobile breakpoint setting and the mobile menu is still displayed. if (width >= mo.mobileBreakpoint && this.el.hasClass(mo.mobileClass)) { // Hides mobile menu toggle button this.toggleButton.hide(); // Remove hide mobile class to ensure menu is never hidden in desktop view. this.el.removeClass(mo.hideMobileClass).removeClass(mo.mobileClass); // Check for lack of touch support. if (!this.isTouch) { // Add the hover class and remove any left over open submenu classes. this.el.addClass(mo.hoverClass).find('.' + mo.openSubmenuClass).removeClass(mo.openSubmenuClass); } } }, /** * Toggle the visibility of a submenu. * * @param {object} menuItem Submenu HTML element. */ toggleSubmenu: function(menuItem) { var mo = this.options, submenu = $(menuItem).closest('.' + mo.hasSubmenuClass); // Toggle the submenu open class and remove from any other submenus at the same level. submenu.toggleClass(mo.openSubmenuClass).parent().find('.' + mo.openSubmenuClass).not(submenu).removeClass(mo.openSubmenuClass); } }; /** * Add responsive menu support to jQuery. * * @param object settings The settings for this menu (options, custom class names, etc.). */ $.fn.thmfdnMenu = function(settings) { return this.each(function() { var menu = Object.create(Menu); menu.init(this, settings); }); }; })(jQuery, window); // *********************************** >>> Fix drop-down menus for Android devices <<< ******************************************* /* ------------------------------------------------------ Fix drop-down menus for Android devices Credits: Based on:Marco Chiesi - Black Studio Touch Dropedown Menu plugin - www.blackstudio.it Originally partially inspired by the one from Ross McKay found here http://snippets.webaware.com.au/snippets/make-css-drop-down-menus-work-on-touch-devices/ */ (function($) { /* Detect device in use */ if (typeof wvrxOpts !== 'undefined' && wvrxOpts.useSmartMenus != '0') return; var weaverx_isTouch = ("ontouchstart" in window) || (navigator.MaxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0); var weaverx_isIOS5 = /iPad|iPod|iPhone/.test(navigator.platform) && "matchMedia" in window; var weaverx_touch_dropdown_menu_apply = weaverx_isTouch || weaverx_isIOS5; //&& ! weaverx_isIOS5; var selector = 'li:has(ul) > a'; // set these to work with weaver x var selector_leaf = 'li li li:not(:has(ul)) > a'; /* Apply dropdown effect on first click */ if (weaverx_touch_dropdown_menu_apply && weaverxBrowserWidth() > 767) { // don't need if mobile menu $(document).ready(function() { $(selector).each(function() { var $this = $(this); // Fix for IE //$this.attr( 'aria-haspopup', true ); // Initial setting to handle first click $this.data('dataNoclick', false); // Touch Handler $this.bind('touchstart', function() { var noclick = !($this.data('dataNoclick')); $(selector).each(function() { $(this).data('dataNoclick', false); }); $this.data('dataNoclick', noclick); $this.focus(); }); // end touchstart // Click Handler $this.bind('click', function(event) { if ($this.data('dataNoclick')) { event.preventDefault(); } $this.focus(); }); // end click }); // end each // Fix for 3rd+ level menus not working in some circumstances $(selector_leaf).each(function() { $(this).bind('touchstart', function() { window.location = this.href; }); // end touchstart }); // end each }); // end ready } //end if })(jQuery); // end self-invoked wrapper function // *********************************** >>> our above the fold jQuery functions <<< ******************************************* (function($) { "use strict"; // *********************************** >>> wvrx_fixWvrxFixedTop <<< ******************************************* $.fn.wvrx_fixWvrxFixedTop = function() { var addHeight = 0; var adjust = 1; if ($('body').hasClass('admin-bar')) { // fix on wide screens only, will be overlap on mobile addHeight = $('#wpadminbar').outerHeight(); } // built-in fixed-top items, by priority: #inject_fixedtop, #nav-secondary, #nav-primary, #header-widget-area var multiTop = 0; var curHeight = $('#inject_fixedtop.wvrx-fixedtop').outerHeight() - 1; // put #inject_fixedtop first if (addHeight > 0) { $('#inject_fixedtop.wvrx-fixedtop').css('top', addHeight); } multiTop = curHeight; curHeight = $('#nav-secondary .wvrx-fixedtop').outerHeight() - adjust; if (curHeight > 0) { $('#nav-secondary .wvrx-fixedtop').css('top', addHeight + multiTop); } multiTop = multiTop + curHeight; // calc widget area before primary since this is the most common case. // Widget area always after fixed top secondary menu and before fixed top primary menu curHeight = $('#header-widget-area.wvrx-fixedtop').outerHeight() - adjust; if (curHeight > 0) { $('#header-widget-area.wvrx-fixedtop').css('top', addHeight + multiTop); } multiTop = multiTop + curHeight; curHeight = $('#nav-primary .wvrx-fixedtop').outerHeight() - adjust; if (curHeight > 0) { $('#nav-primary .wvrx-fixedtop').css('top', addHeight + multiTop ); } multiTop = multiTop + curHeight; if (multiTop > 0) { $('body').css('margin-top', multiTop - adjust); // now maker room for the top fixed areas } else { // none of the built-in fixed top items used, so see if user added own wvrx-fixed top class to anyting var fixedHeight = $('.wvrx-fixedtop').outerHeight(); if (fixedHeight > 0) { // a fixed top area is diplayed // There is a height on a fixed-top area, so adjust the body margin-top $('body').css('margin-top', fixedHeight + addHeight); if (addHeight > 0) $('.wvrx-fixedtop').css('top', addHeight); } } var botFixed = $('#inject_fixedbottom').outerHeight(); if (botFixed !== 0) { $('body').css('margin-bottom', botFixed); } }; // *********************************** >>> wvrx_fixbranding <<< ******************************************* // Change overflow to visible on widget area with widget that contain an extra menu shortcode if ($('.widget .menu-extra').length) { $('.widget .menu-extra').each(function () { $(this).closest('.widget').css('overflow', 'visible'); $(this).closest('.widget-area').css('overflow', 'visible'); }); } })(window.jQuery); // *********************************** >>> weaverxOnResize <<< ******************************************* function weaverxOnResize() { // this function is called on initial window load, and again on resizes var width; if (typeof wvrxOpts.menuAltswitch == 'undefined' || wvrxOpts.menuAltswitch === null) wvrxOpts.menuAltswitch = 767; width = weaverxBrowserWidth(); var theBody = jQuery('body'); if (width <= wvrxOpts.menuAltswitch) { // check for switch point for changing mobile menu theBody.addClass("is-menu-mobile"); theBody.removeClass("is-menu-desktop"); } else { theBody.addClass("is-menu-desktop"); theBody.removeClass("is-menu-mobile"); } if (wvrxOpts.menuAltswitch <= 767 && width > wvrxOpts.menuAltswitch) { theBody.removeClass("is-menu-default"); // remove class for space where needs to say full } if (width > 767) theBody.addClass('is-menu-default'); var device = 'is-desktop'; // do things when we resize if (width >= 768) { // on the desktop theBody.removeClass("is-phone is-smalltablet is-mobile"); device = 'is-desktop'; } else if (width > 580) { // small tablet theBody.removeClass("is-phone is-desktop"); device = 'is-smalltablet is-mobile'; } else { // phone theBody.removeClass("is-desktop is-smalltablet"); device = 'is-phone is-mobile'; } var agent = navigator.userAgent; // Safari is breaking our generated extend width CSS, so by removing the .wvrx-not-safari class from body, // we can force the JS to fix it. For whatever reason, the Safari agend string included both Chrome and Safari. Bizarre! if (agent.match(/Safari/i) && !agent.match(/Chrome/i)) { //alert('Safari'); theBody.removeClass('wvrx-not-safari'); // Changed 3.1.11 to fix safari extended width issue theBody.addClass('wvrx-is-safari') // Added V 4.0 for controlling Safari fullwidth } // Note that these classes must be added at runtime on the client to avoid page caching issues. if (agent.match(/iPad/i) || agent.match(/iPhone/i) || agent.match(/iPod/i)) { device = device + ' is-ios'; if (agent.match(/iPad/i)) device = device + ' is-ipad'; if (agent.match(/iPod/i)) device = device + ' is-ipod'; if (agent.match(/iPhone/i)) device = device + ' is-iphone'; } if (agent.match(/Android/i)) device = device + ' is-android'; if (agent.match(/Windows/i)) device = device + ' is-windows'; if (agent.match(/Intel Mac OS X/i)) device = device + ' is-macos'; theBody.addClass(device); jQuery('.wvrx_fixedtop').wvrx_fixWvrxFixedTop(); // jQuery('#monitor-device').html('Device:' + device); // + ' / Agent: ' + agent); } jQuery(window).scroll(function() { var scrolledY = jQuery(window).scrollTop(); jQuery('#header.header-as-bg-parallax').css('background-position-y', ((scrolledY)) + 'px'); }); // *********************************** >>> Page Load Startup <<< ******************************************* jQuery(function($) { $('.wrapper').resizeX(weaverxOnResize); if (typeof wvrxOpts !== 'undefined' && wvrxOpts.useSmartMenus == '0') { // SmartMenus handled inline $('#nav-primary .weaverx-theme-menu').thmfdnMenu({ toggleButtonID: 'primary-toggle-button' }); $('#nav-secondary .weaverx-theme-menu').thmfdnMenu({ toggleButtonID: 'secondary-toggle-button' }); } }); // Add header video class after the video is loaded. jQuery( document ).on( 'wp-custom-header-video-loaded', function() { if (typeof wvrxOpts !== 'undefined') jQuery('body').addClass( wvrxOpts.headerVideoClass ); });