/*! * jQuery meanMenu v2.0.8 (Drupal Responsive Menus version) * @Copyright (C) 2012-2014 Chris Wharton @ MeanThemes (https://github.com/meanthemes/meanMenu) * */ /* * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT * HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR * FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE * OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.COPYRIGHT HOLDERS WILL NOT * BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL * DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Find more information at http://www.meanthemes.com/plugins/meanmenu/ * */ (function ($) { "use strict"; $.fn.meanmenu = function (options) { var defaults = { meanMenuTarget: jQuery(this), // Target the current HTML markup you wish to replace meanMenuContainer: 'body', // Choose where meanmenu will be placed within the HTML meanMenuClose: "X", // single character you want to represent the close menu button meanMenuCloseSize: "18px", // set font size of close button meanMenuOpen: "", // text/markup you want when menu is closed meanRevealPosition: "right", // left right or center positions meanRevealPositionDistance: "0", // Tweak the position of the menu meanRevealColour: "", // override CSS colours for the reveal background meanScreenWidth: "480", // set the screen width you want meanmenu to kick in at meanNavPush: "", // set a height here in px, em or % if you want to budge your layout now the navigation is missing. meanShowChildren: true, // true to show children in the menu, false to hide them meanExpandableChildren: true, // true to allow expand/collapse children meanExpand: "+", // single character you want to represent the expand for ULs meanContract: "-", // single character you want to represent the contract for ULs meanRemoveAttrs: false, // true to remove classes and IDs, false to keep them onePage: false, // set to true for one page sites meanDisplay: "block", // override display method for table cell based layouts e.g. table-cell removeElements: "" // set to hide page elements }; options = $.extend(defaults, options); // get browser width var currentWidth = document.documentElement.clientWidth || document.body.clientWidth; return this.each(function () { var meanMenu = options.meanMenuTarget; // For Drupal, track the original menu, but make a clone and remove // ul.contextual links for removal of the responsive version. var meanMenuClone = options.meanMenuTarget.clone(); meanMenuClone.find('.contextual-links-wrapper').remove().find('ul.contextual-links').remove(); var meanContainer = options.meanMenuContainer; var meanMenuClose = options.meanMenuClose; var meanMenuCloseSize = options.meanMenuCloseSize; var meanMenuOpen = options.meanMenuOpen; var meanRevealPosition = options.meanRevealPosition; var meanRevealPositionDistance = options.meanRevealPositionDistance; var meanRevealColour = options.meanRevealColour; var meanScreenWidth = options.meanScreenWidth; var meanNavPush = options.meanNavPush; var meanRevealClass = ".meanmenu-reveal"; var meanShowChildren = options.meanShowChildren; var meanExpandableChildren = options.meanExpandableChildren; var meanExpand = options.meanExpand; var meanContract = options.meanContract; var meanRemoveAttrs = options.meanRemoveAttrs; var onePage = options.onePage; var meanDisplay = options.meanDisplay; var removeElements = options.removeElements; //detect known mobile/tablet usage var isMobile = false; if ( (navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) || (navigator.userAgent.match(/iPad/i)) || (navigator.userAgent.match(/Android/i)) || (navigator.userAgent.match(/Blackberry/i)) || (navigator.userAgent.match(/Windows Phone/i)) ) { isMobile = true; } if ( (navigator.userAgent.match(/MSIE 8/i)) || (navigator.userAgent.match(/MSIE 7/i)) ) { // add scrollbar for IE7 & 8 to stop breaking resize function on small content sites jQuery('html').css("overflow-y" , "scroll"); } var meanRevealPos = ""; var meanCentered = function() { if (meanRevealPosition === "center") { var newWidth = document.documentElement.clientWidth || document.body.clientWidth; var meanCenter = ( (newWidth/2)-22 )+"px"; meanRevealPos = "left:" + meanCenter + ";right:auto;"; if (!isMobile) { jQuery('.meanmenu-reveal').css("left",meanCenter); } else { jQuery('.meanmenu-reveal').animate({ left: meanCenter }); } } }; var menuOn = false; var meanMenuExist = false; if (meanRevealPosition === "right") { meanRevealPos = "right:" + meanRevealPositionDistance + ";left:auto;"; } if (meanRevealPosition === "left") { meanRevealPos = "left:" + meanRevealPositionDistance + ";right:auto;"; } // run center function meanCentered(); // set all styles for mean-reveal var $navreveal = ""; var meanInner = function() { // get last class name if (jQuery($navreveal).is(".meanmenu-reveal.meanclose")) { $navreveal.html(meanMenuClose); } else { $navreveal.html(meanMenuOpen); } }; // re-instate original nav (and call this on window.width functions) var meanOriginal = function() { jQuery('.mean-bar,.mean-push').remove(); jQuery(meanContainer).removeClass("mean-container"); jQuery(meanMenu).css('display', meanDisplay); menuOn = false; meanMenuExist = false; jQuery(removeElements).removeClass('mean-remove'); }; // navigation reveal var showMeanMenu = function() { var meanStyles = "color: #fff;"+"font-size: 18px;"+"text-indent: 0;"+meanRevealPos; if (currentWidth <= meanScreenWidth) { jQuery(removeElements).addClass('mean-remove'); meanMenuExist = true; // add class to body so we don't need to worry about media queries here, all CSS is wrapped in '.mean-container' jQuery(meanContainer).addClass("mean-container"); jQuery('.mean-container').prepend(''); //push meanMenu navigation into .mean-nav var meanMenuContents = jQuery(meanMenuClone).html(); jQuery('.mean-nav').html(meanMenuContents); // remove all classes from EVERYTHING inside meanmenu nav if(meanRemoveAttrs) { jQuery('nav.mean-nav ul, nav.mean-nav ul *').each(function() { // First check if this has mean-remove class if (jQuery(this).is('.mean-remove')) { jQuery(this).attr('class', 'mean-remove'); } else { jQuery(this).removeAttr("class"); } jQuery(this).removeAttr("id"); }); } // push in a holder div (this can be used if removal of nav is causing layout issues) jQuery(meanMenu).before('
'); jQuery('.mean-push').css("margin-top",meanNavPush); // hide current navigation and reveal mean nav link jQuery(meanMenu).hide(); jQuery(".meanmenu-reveal").show(); // turn 'X' on or off jQuery(meanRevealClass).html(meanMenuOpen); $navreveal = jQuery(meanRevealClass); //hide mean-nav ul jQuery('.mean-nav ul').hide(); // hide sub nav if(meanShowChildren) { // allow expandable sub nav(s) if(meanExpandableChildren){ jQuery('.mean-nav ul ul').each(function() { if(jQuery(this).children().length){ jQuery(this,'li:first').parent().append(''+ meanExpand +''); } }); jQuery('.mean-expand').on("click",function(e){ e.preventDefault(); if (jQuery(this).hasClass("mean-clicked")) { jQuery(this).text(meanExpand); jQuery(this).prev('ul').slideUp(300, function(){}); } else { jQuery(this).text(meanContract); jQuery(this).prev('ul').slideDown(300, function(){}); } jQuery(this).toggleClass("mean-clicked"); }); } else { jQuery('.mean-nav ul ul').show(); } } else { jQuery('.mean-nav ul ul').hide(); } // add last class to tidy up borders jQuery('.mean-nav ul li').last().addClass('mean-last'); $navreveal.removeClass("meanclose"); jQuery($navreveal).click(function(e){ e.preventDefault(); if( menuOn === false ) { $navreveal.css("text-align", "center"); $navreveal.css("text-indent", "0"); $navreveal.css("font-size", meanMenuCloseSize); jQuery('.mean-nav ul:first').slideDown(); menuOn = true; } else { jQuery('.mean-nav ul:first').slideUp(); menuOn = false; } $navreveal.toggleClass("meanclose"); meanInner(); jQuery(removeElements).addClass('mean-remove'); }); // for one page websites, reset all variables... if ( onePage ) { jQuery('.mean-nav ul > li > a:first-child').on( "click" , function () { jQuery('.mean-nav ul:first').slideUp(); menuOn = false; jQuery($navreveal).toggleClass("meanclose").html(meanMenuOpen); }); } } else { meanOriginal(); } }; if (!isMobile) { // reset menu on resize above meanScreenWidth jQuery(window).resize(function () { currentWidth = document.documentElement.clientWidth || document.body.clientWidth; if (currentWidth > meanScreenWidth) { meanOriginal(); } else { meanOriginal(); } if (currentWidth <= meanScreenWidth) { showMeanMenu(); meanCentered(); } else { meanOriginal(); } }); } jQuery(window).resize(function () { // get browser width currentWidth = document.documentElement.clientWidth || document.body.clientWidth; if (!isMobile) { meanOriginal(); if (currentWidth <= meanScreenWidth) { showMeanMenu(); meanCentered(); } } else { meanCentered(); if (currentWidth <= meanScreenWidth) { if (meanMenuExist === false) { showMeanMenu(); } } else { meanOriginal(); } } }); // run main menuMenu function on load showMeanMenu(); }); }; })(jQuery); ; /** * @file * Integrate Mean Menu library with Responsive Menus module. */ (function ($) { Drupal.behaviors.responsive_menus_mean_menu = { attach: function (context, settings) { settings.responsive_menus = settings.responsive_menus || {}; $.each(settings.responsive_menus, function(ind, iteration) { if (iteration.responsive_menus_style != 'mean_menu') { return true; } if (!iteration.selectors.length) { return; } // Set 1/0 to true/false respectively. $.each(iteration, function(key, value) { if (value == 0) { iteration[key] = false; } if (value == 1) { iteration[key] = true; } }); // Call meanmenu() with our custom settings. $(iteration.selectors).once('responsive-menus-mean-menu', function() { $(this).meanmenu({ meanMenuContainer: iteration.container || "body", meanMenuClose: iteration.close_txt || "X", meanMenuCloseSize: iteration.close_size || "18px", meanMenuOpen: iteration.trigger_txt || "", meanRevealPosition: iteration.position || "right", meanScreenWidth: iteration.media_size || "480", meanExpand: iteration.expand_txt || "+", meanContract: iteration.contract_txt || "-", meanShowChildren: iteration.show_children, meanExpandableChildren: iteration.expand_children, meanRemoveAttrs: iteration.remove_attrs }); }); }); } }; }(jQuery)); ; (function ($) { Drupal.googleanalytics = {}; $(document).ready(function() { // Attach mousedown, keyup, touchstart events to document only and catch // clicks on all elements. $(document.body).bind("mousedown keyup touchstart", function(event) { // Catch the closest surrounding link of a clicked element. $(event.target).closest("a,area").each(function() { // Is the clicked URL internal? if (Drupal.googleanalytics.isInternal(this.href)) { // Skip 'click' tracking, if custom tracking events are bound. if ($(this).is('.colorbox') && (Drupal.settings.googleanalytics.trackColorbox)) { // Do nothing here. The custom event will handle all tracking. //console.info("Click on .colorbox item has been detected."); } // Is download tracking activated and the file extension configured for download tracking? else if (Drupal.settings.googleanalytics.trackDownload && Drupal.googleanalytics.isDownload(this.href)) { // Download link clicked. ga("send", { "hitType": "event", "eventCategory": "Downloads", "eventAction": Drupal.googleanalytics.getDownloadExtension(this.href).toUpperCase(), "eventLabel": Drupal.googleanalytics.getPageUrl(this.href), "transport": "beacon" }); } else if (Drupal.googleanalytics.isInternalSpecial(this.href)) { // Keep the internal URL for Google Analytics website overlay intact. ga("send", { "hitType": "pageview", "page": Drupal.googleanalytics.getPageUrl(this.href), "transport": "beacon" }); } } else { if (Drupal.settings.googleanalytics.trackMailto && $(this).is("a[href^='mailto:'],area[href^='mailto:']")) { // Mailto link clicked. ga("send", { "hitType": "event", "eventCategory": "Mails", "eventAction": "Click", "eventLabel": this.href.substring(7), "transport": "beacon" }); } else if (Drupal.settings.googleanalytics.trackOutbound && this.href.match(/^\w+:\/\//i)) { if (Drupal.settings.googleanalytics.trackDomainMode !== 2 || (Drupal.settings.googleanalytics.trackDomainMode === 2 && !Drupal.googleanalytics.isCrossDomain(this.hostname, Drupal.settings.googleanalytics.trackCrossDomains))) { // External link clicked / No top-level cross domain clicked. ga("send", { "hitType": "event", "eventCategory": "Outbound links", "eventAction": "Click", "eventLabel": this.href, "transport": "beacon" }); } } } }); }); // Track hash changes as unique pageviews, if this option has been enabled. if (Drupal.settings.googleanalytics.trackUrlFragments) { window.onhashchange = function() { ga("send", { "hitType": "pageview", "page": location.pathname + location.search + location.hash }); }; } // Colorbox: This event triggers when the transition has completed and the // newly loaded content has been revealed. if (Drupal.settings.googleanalytics.trackColorbox) { $(document).bind("cbox_complete", function () { var href = $.colorbox.element().attr("href"); if (href) { ga("send", { "hitType": "pageview", "page": Drupal.googleanalytics.getPageUrl(href) }); } }); } }); /** * Check whether the hostname is part of the cross domains or not. * * @param string hostname * The hostname of the clicked URL. * @param array crossDomains * All cross domain hostnames as JS array. * * @return boolean */ Drupal.googleanalytics.isCrossDomain = function (hostname, crossDomains) { /** * jQuery < 1.6.3 bug: $.inArray crushes IE6 and Chrome if second argument is * `null` or `undefined`, http://bugs.jquery.com/ticket/10076, * https://github.com/jquery/jquery/commit/a839af034db2bd934e4d4fa6758a3fed8de74174 * * @todo: Remove/Refactor in D8 */ if (!crossDomains) { return false; } else { return $.inArray(hostname, crossDomains) > -1 ? true : false; } }; /** * Check whether this is a download URL or not. * * @param string url * The web url to check. * * @return boolean */ Drupal.googleanalytics.isDownload = function (url) { var isDownload = new RegExp("\\.(" + Drupal.settings.googleanalytics.trackDownloadExtensions + ")([\?#].*)?$", "i"); return isDownload.test(url); }; /** * Check whether this is an absolute internal URL or not. * * @param string url * The web url to check. * * @return boolean */ Drupal.googleanalytics.isInternal = function (url) { var isInternal = new RegExp("^(https?):\/\/" + window.location.host, "i"); return isInternal.test(url); }; /** * Check whether this is a special URL or not. * * URL types: * - gotwo.module /go/* links. * * @param string url * The web url to check. * * @return boolean */ Drupal.googleanalytics.isInternalSpecial = function (url) { var isInternalSpecial = new RegExp("(\/go\/.*)$", "i"); return isInternalSpecial.test(url); }; /** * Extract the relative internal URL from an absolute internal URL. * * Examples: * - http://mydomain.com/node/1 -> /node/1 * - http://example.com/foo/bar -> http://example.com/foo/bar * * @param string url * The web url to check. * * @return string * Internal website URL */ Drupal.googleanalytics.getPageUrl = function (url) { var extractInternalUrl = new RegExp("^(https?):\/\/" + window.location.host, "i"); return url.replace(extractInternalUrl, ''); }; /** * Extract the download file extension from the URL. * * @param string url * The web url to check. * * @return string * The file extension of the passed url. e.g. "zip", "txt" */ Drupal.googleanalytics.getDownloadExtension = function (url) { var extractDownloadextension = new RegExp("\\.(" + Drupal.settings.googleanalytics.trackDownloadExtensions + ")([\?#].*)?$", "i"); var extension = extractDownloadextension.exec(url); return (extension === null) ? '' : extension[1]; }; })(jQuery); ;