Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /home/oliver1/public_html/grandprairiecomputerrepair.com/wp-content/plugins/essential-grid/includes/item-skin.class.php on line 1142

Deprecated: Function create_function() is deprecated in /home/oliver1/public_html/grandprairiecomputerrepair.com/wp-content/plugins/essential-grid/essential-grid.php on line 98

Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; flickrRSS has a deprecated constructor in /home/oliver1/public_html/grandprairiecomputerrepair.com/wp-content/plugins/flickr-rss/flickrrss.php on line 13

Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; SEOLinks has a deprecated constructor in /home/oliver1/public_html/grandprairiecomputerrepair.com/wp-content/plugins/seo-automatic-links/seo-links.php on line 13

Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; udesignShortcodeInsert has a deprecated constructor in /home/oliver1/public_html/grandprairiecomputerrepair.com/wp-content/plugins/udesign-shortcode-insert-button/udesignShortcodeInsert.php on line 27

Deprecated: Function create_function() is deprecated in /home/oliver1/public_html/grandprairiecomputerrepair.com/wp-content/plugins/udesign-shortcode-insert-button/udesignShortcodeInsert.php on line 55

Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; add_udesignShortcodeInsert_button has a deprecated constructor in /home/oliver1/public_html/grandprairiecomputerrepair.com/wp-content/plugins/udesign-shortcode-insert-button/tinymce/tinymce.php on line 3

Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/oliver1/public_html/grandprairiecomputerrepair.com/wp-content/plugins/js_composer/include/classes/core/class-vc-mapper.php on line 111

Warning: Cannot modify header information - headers already sent by (output started at /home/oliver1/public_html/grandprairiecomputerrepair.com/wp-content/plugins/essential-grid/includes/item-skin.class.php:1142) in /home/oliver1/public_html/grandprairiecomputerrepair.com/wp-content/themes/upfront/library/class_upfront_server.php on line 73
jQuery(function($){ window.get_breakpoint_ie8 = function(width) { if(width >= 1080) { return 'desktop'; } if(width >= 570 && width <= 1079) { return 'tablet'; } if(width >= 0 && width <= 569) { return 'mobile'; } } }); /* upfront-layout */ jQuery(document).ready(function($){ var throttle = function(a,b,c){var d,e,f,g=null,h=0;c||(c={});var i=function(){h=c.leading===!1?0:new Date().getTime(),g=null,f=a.apply(d,e),g||(d=e=null)};return function(){var j=new Date().getTime();h||c.leading!==!1||(h=j);var k=b-(j-h);return d=this,e=arguments,0>=k||k>b?(clearTimeout(g),g=null,h=j,f=a.apply(d,e),g||(d=e=null)):g||c.trailing===!1||(g=setTimeout(i,k)),f}}; var lastKey = new Date(); var lastClick = new Date(); function css_support( property ) { var div = document.createElement('div'), reg = new RegExp("(khtml|moz|ms|webkit|)"+property, "i"); for ( s in div.style ) { if ( s.match(reg) ) return true; } return false; } var previous_breakpoint = ''; var current_breakpoint = ''; function get_breakpoint(){ if (!window.getComputedStyle) { window.getComputedStyle = function(el, pseudo) { this.el = el; this.getPropertyValue = function(prop) { var re = /(\-([a-z]){1})/g; if (prop == 'float') prop = 'styleFloat'; if (re.test(prop)) { prop = prop.replace(re, function () { return arguments[2].toUpperCase(); }); } return el.currentStyle[prop] ? el.currentStyle[prop] : null; } return this; } } var breakpoint = window.getComputedStyle(document.body,':after').getPropertyValue('content'); if(breakpoint === null && $('html').hasClass('ie8')) { breakpoint = window.get_breakpoint_ie8($( window ).width()); $(window).trigger('resize'); } if(breakpoint) { breakpoint = breakpoint.replace(/['"]/g, '') if (current_breakpoint != breakpoint) { previous_breakpoint = current_breakpoint; current_breakpoint = breakpoint; } return breakpoint; } } window.upfront_get_breakpoint = get_breakpoint; // Expose to global /** * Get the previously used breakpoint * * @return {String} Previous breakpoint */ function get_previous_breakpoint () { get_breakpoint(); return previous_breakpoint; } window.upfront_get_previous_breakpoint = get_previous_breakpoint; // Expose to global /* Youtube API */ var youtube_api_loaded = false; var youtube_api_ready = false; var youtube_player_ids = []; function change_youtube_video (id, type) { youtube_player_ids.push(id); if ( !youtube_api_loaded ){ var tag = document.createElement('script'); tag.src = "https://www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); window.onYouTubeIframeAPIReady = function () { youtube_api_ready = true; create_youtube_players(type); } youtube_api_loaded = true; return; } if ( youtube_api_ready ) { create_youtube_players(type); } } function create_youtube_players (type) { for ( var i = 0; i < youtube_player_ids.length; i++ ) // Only Loop video. if (type === 'loop') { var player = new YT.Player(youtube_player_ids[i], { events: { 'onReady': on_loop_youtube_ready } }); } else if (type === 'loopAndMute') { // Loop and mute video. var player = new YT.Player(youtube_player_ids[i], { events: { 'onReady': function(e) { on_loop_youtube_ready(e); on_mute_youtube_ready(e); } } }); // Only mute: } else { var player = new YT.Player(youtube_player_ids[i], { events: { 'onReady': on_mute_youtube_ready } }); } youtube_player_ids = []; } function on_mute_youtube_ready (event) { return event.target.mute(); } function on_loop_youtube_ready (event) { var time, duration; return setInterval(function(){ time = event.target.getCurrentTime(); duration = event.target.getDuration(); if(time > duration - 0.5) { event.target.seekTo(0); event.target.playVideo(); } }, 200); } /* Vimeo API */ var vimeo_listened = false; function mute_vimeo_video (id) { if ( !vimeo_listened ) { if (window.addEventListener) window.addEventListener('message', on_vimeo_message, false); else window.attachEvent('onmessage', on_vimeo_message, false); vimeo_listened = true; } } function on_vimeo_message (e) { if ( !e.origin.match(/vimeo\./) ) return; var data = JSON.parse(e.data); if ( data.event == 'ready' ) { var player = $('#'+data.player_id), url = player.attr('src').split('?'), data = { method: 'setVolume', value: 0 }; player[0].contentWindow.postMessage(data, url); } } /* Responsive background */ var windowWidth = $(window).width(); var initialUpdateBackgroundDone = false; function update_background () { var newWindowWidth = $(window).width(); // Update background only on width change, do initial update always if (initialUpdateBackgroundDone && windowWidth === newWindowWidth) { return; } initialUpdateBackgroundDone = true; windowWidth = newWindowWidth; var breakpoint = get_breakpoint(); breakpoint = !breakpoint ? 'desktop' : breakpoint; $('[data-bg-type-'+breakpoint+']').each(function(){ var type = $(this).attr('data-bg-type-'+breakpoint), $overlay = $(this).find('> .upfront-output-bg-'+breakpoint) ; $(this).find('> .upfront-output-bg-overlay').not($overlay).each(function(){ if ( $(this).is('.upfront-output-bg-video') ) { $(this).children().not('script.video-embed-code').remove(); } if ( $(this).attr('data-bg-parallax') && $(this).data('uparallax') ) { $(this).uparallax('destroy'); } }); if ( $overlay.attr('data-bg-parallax') ) { setTimeout(function () { // Zero timeout to shift it out var $container = $overlay.closest('.upfront-output-region-container'); if ( $container.length ) { var $next = $container.next('.upfront-output-region-container'), $next_bg = $next.find('.upfront-region-container-bg'), $prev = $container.prev('.upfront-output-region-container'), $prev_bg = $prev.find('.upfront-region-container-bg'), next_bg_color = $next_bg.css('background-color'), next_type = $next_bg.attr('data-bg-type-' + breakpoint), prev_bg_color = $prev_bg.css('background-color'), prev_type = $prev_bg.attr('data-bg-type-' + breakpoint), has_alpha = function (color) { if (!color) return false; if ("transparent" == color) return true; var matches = color.match(/(rgba|hsla)\(.*?,.*?,.*?,.*?([\d.]+).*?\)/); if (matches && matches[2] && parseFloat(matches[2]) < 1) return true; return false; }, overflow_top = ( $prev.length > 0 && prev_type == 'color' && prev_bg_color && has_alpha(prev_bg_color) ? 0 : false ), overflow_bottom = ( $next.length > 0 && next_type == 'color' && next_bg_color && has_alpha(next_bg_color) ? 0 : false ) ; // No overlow if the next/prev container is contained if ( $prev.length > 0 && $prev.hasClass('upfront-region-container-clip') ) overflow_top = 0; if ( $next.length > 0 && $next.hasClass('upfront-region-container-clip') ) overflow_bottom = 0; $overlay.uparallax({ element: $overlay.attr('data-bg-parallax') }); if (false === overflow_top && $prev.length > 0 && $prev.height() < 200) overflow_top = $prev.height() * 0.5; if (false === overflow_bottom && $next.length > 0 && $next.height() < 200) overflow_bottom = $next.height() * 0.5; if (false !== overflow_top) $overlay.uparallax('setOption', 'overflowTop', overflow_top); if (false !== overflow_bottom) $overlay.uparallax('setOption', 'overflowBottom', overflow_bottom); $(document).on('upfront-responsive-nav-open upfront-responsive-nav-close', function () { if ( $overlay.data('uparallax') ) { $overlay.uparallax('refresh'); } }); } }, 0); } if ( type == 'image' || type == 'featured' ) { var is_overlay = $(this).attr('data-bg-overlay-'+breakpoint), $el = is_overlay ? $overlay.children('.upfront-bg-image') : $(this), before_src = $el.attr('data-src'), src = $el.attr('data-src-'+breakpoint), ratio = $el.attr('data-bg-image-ratio-'+breakpoint) ; if ( is_overlay ) { $(this).css('background-image', 'none'); } if ( src ) { $el.attr('data-src', src); } else { $el.removeAttr('data-src'); } if ( ratio ) { $el.attr('data-bg-image-ratio', ratio); } else { $el.removeAttr('data-bg-image-ratio').css('background-position', '').css('background-size', ''); } if ( src && before_src != src && $el.hasClass('upfront-image-lazy') ){ $el.removeClass('upfront-image-lazy-loaded'); } else { $el.css('background-image', 'url("' + src + '")'); } } else if ( type == 'color' ) { $(this).css('background-image', 'none'); } else { $(this).css('background-image', 'none'); $overlay.each(function(){ if ( $(this).is('.upfront-output-bg-video') && $(this).children().length == 1 ){ var $iframe = $($(this).children('script.video-embed-code').html()), id = $iframe.attr('id'); $(this).append($iframe); // If mute is enabled: var src; if ( $(this).attr('data-bg-video-mute') == 1 ) { src = $iframe.attr('src'); if ( src.match(/youtube\.com/i) ) { // If loop is enabled too. if ( $(this).attr('data-bg-video-loop') == 1 ) { change_youtube_video(id, 'loopAndMute'); } else { change_youtube_video(id, 'mute'); } } else if ( src.match(/vimeo\./i) ) { mute_vimeo_video(id); } // If only loop is enabled: } else if ( $(this).attr('data-bg-video-loop') == 1 ) { src = $iframe.attr('src'); // Only loop via this method if youtube video. if ( src.match(/youtube\.com/i) ) { change_youtube_video(id, 'loop'); } } } }); } }); } update_background(); var lazyUpdateBackground = throttle(update_background, 300); $(window).on('resize.uf_layout', lazyUpdateBackground); // Making sure sidebar region height is fixed function fix_region_height () { set_full_screen(); $('.upfront-output-region-container').each(function(){ var $regions = $(this).find('.upfront-output-region').filter('.upfront-region-center, .upfront-region-side-left, .upfront-region-side-right'), is_full_screen = $(this).hasClass('upfront-region-container-full'), min_height = height = 0; if ( $regions.length > 1 ){ $regions.each(function(){ var min = parseInt($(this).css('min-height'), 10), h = $(this).outerHeight(); if ( min ) min_height = min > min_height ? min : min_height; height = h > height ? h : height; }); $regions.css({ minHeight: height, height: "", maxHeight: "" }); } }); } function set_full_screen () { $('.upfront-output-region-container.upfront-region-container-full').each(function(){ var $region = $(this).find('.upfront-region-center'), $sub = $(this).find('.upfront-region-side-top, .upfront-region-side-bottom'), body_off = $('body').offset(), height = $(window).height() - body_off.top, $bg_overlay = $(this).find('.upfront-output-bg-overlay') ; if ( $bg_overlay.length ) $bg_overlay.css('height', height); $sub.each(function(){ height -= $(this).outerHeight(); }); $region.css({ minHeight: height }); // Keep element position to ratio if enabled var behavior = $(this).attr('data-behavior'), original_height = parseInt($(this).attr('data-original-height'), 10) ; if ( behavior == 'keep-ratio' && original_height > 0 ){ var $wrappers = $region.find('> .upfront-region-wrapper > .upfront-output-wrapper'), region_off = $region.offset(), modules = [], lines = [], line_index = -1, total_height = 0, total_fill = 0, ori_bottom_space = 0, avail_bottom_space = 0, available_space = 0, original_space = 0 ; $wrappers.each(function(){ var $modules = $(this).find('> .upfront-output-module, > .upfront-output-module-group'); if ( $modules.length == 0 ) return; var wrap_obj = { $el: $(this), top_space: 0, bottom_space: 0, fill: 0, modules: [] }; $modules.each(function(module_index){ var $el = $(this).hasClass('upfront-output-module-group') ? $(this) : $(this).find('> .upfront-output-object'); $el.css({ paddingTop: '', paddingBottom: '', minHeight: '' }); var padding_top = parseFloat($el.css('padding-top')), padding_bottom = parseFloat($el.css('padding-bottom')), height = parseFloat($(this).css('height')), min_height = parseFloat($el.css('min-height')) ; if ( module_index == 0 ) { wrap_obj.top_space = padding_top; } wrap_obj.bottom_space = padding_bottom; wrap_obj.fill += height; wrap_obj.modules.push({ $el: $el, top: padding_top, bottom: padding_bottom, height: height - padding_top - padding_bottom, min_height: min_height !== min_height ? 0 : min_height }); }); wrap_obj.fill -= wrap_obj.top_space + wrap_obj.bottom_space; var wrap_off = $(this).offset(), wrap_left = parseFloat($(this).css('margin-left')), wrap_height = parseFloat($(this).css('height')) ; if ( Math.abs(wrap_off.left-wrap_left-region_off.left) < 5 ){ line_index++; lines[line_index] = { wrappers: [wrap_obj], height: wrap_height, top_space: wrap_obj.top_space, bottom_space: wrap_obj.bottom_space }; } else { lines[line_index].top_space = wrap_obj.top_space < lines[line_index].top_space ? wrap_obj.top_space : lines[line_index].top_space; if ( wrap_height >= lines[line_index].height ) { lines[line_index].height = wrap_height; lines[line_index].bottom_space = wrap_obj.bottom_space < lines[line_index].bottom_space ? wrap_obj.bottom_space : lines[line_index].bottom_space; } lines[line_index].wrappers.push(wrap_obj); } }); $.each(lines, function(index, line){ total_height += line.height; total_fill += line.height - line.top_space - line.bottom_space; original_space += line.top_space + line.bottom_space; }); ori_bottom_space = original_height > total_height ? original_height-total_height : 0; original_space += ori_bottom_space; available_space = height > total_fill ? height - total_fill : 0; var count_space = function (from, until) { var total_space = 0, from = typeof from == "number" ? from : 0, until = typeof until == "number" ? until : -1 ; $.each(lines, function(index, line){ if ( index < from || ( until > -1 && index > until ) ) return; var top_space = false, bottom_space = false, line_height = 0 ; $.each(line.wrappers, function(w, wrap){ var wrap_height = wrap.fill + wrap.top_space + wrap.bottom_space; line_height = wrap_height > line_height ? wrap_height : line_height; }); $.each(line.wrappers, function(w, wrap){ var wrap_bottom_space = line_height - wrap.fill - wrap.top_space; top_space = ( top_space === false || wrap.top_space < top_space ) ? wrap.top_space : top_space; bottom_space = ( bottom_space === false || wrap_bottom_space < bottom_space ) ? wrap_bottom_space : bottom_space; }); total_space += top_space + bottom_space; }); return total_space; } $.each(lines, function(index, line){ var line_top_space = Math.round(line.top_space/original_space * available_space), line_bottom_space = Math.round(line.bottom_space/original_space * available_space) ; $.each(line.wrappers, function(w, wrap){ $.each(wrap.modules, function(m, module){ var new_top = module.top - line.top_space + line_top_space, new_bottom = module.bottom - line.bottom_space + line_bottom_space, min_height = module.min_height ; if ( m == 0 ) { module.$el.css('padding-top', new_top + 'px'); min_height -= module.top - new_top; } if ( m == wrap.modules.length - 1 ) { module.$el.css('padding-bottom', new_bottom + 'px'); min_height -= module.bottom - new_bottom; } min_height = min_height > 0 ? min_height : 0; module.$el.css('min-height', min_height + 'px'); }); }); }); } }); } var lazySetFullScreen = throttle(set_full_screen, 100); var lazyFixRegionHeight = throttle(fix_region_height, 100); if ( css_support('flex') ){ $('html').addClass('flexbox-support'); set_full_screen(); $(window).on('load.uf_layout', set_full_screen); $(window).on('resize.uf_layout', lazySetFullScreen); } else { fix_region_height(); $(window).on('load.uf_layout', fix_region_height); $(window).on('resize.uf_layout', lazyFixRegionHeight); } // Full width image and video background function fix_full_bg () { var body_off = $('body').offset(); $('[data-bg-image-ratio]').each(function(){ var is_layout = $(this).is('.upfront-output-layout'), is_full_screen = ( ( $(this).is('.upfront-region-container-bg') || $(this).is('.upfront-output-region') ) && $(this).closest('.upfront-region-container-full').length > 0 ), width = is_layout ? $(window).width() : $(this).outerWidth(), height = is_layout ? $(window).height() : ( is_full_screen ? $(window).height()-body_off.top : $(this).outerHeight() ), ratio = parseFloat($(this).attr('data-bg-image-ratio')); // If Parallax, do not change background size/position. if (this.parentNode.getAttribute('data-bg-parallax')) { return; } if ( Math.round(height/width*100)/100 > ratio ) { $(this).data('bg-position-y', 0); $(this).data('bg-position-x', '50%'); $(this).css({ 'background-position': '50% 0', 'background-size': Math.round(height/ratio) + "px " + height + "px" /*"auto 100%"*/ }); } else { $(this).data('bg-position-y', Math.round( ( height - (width*ratio) ) / 2 )); $(this).data('bg-position-x', '0'); $(this).css({ 'background-position': '0 ' + Math.round( ( ( height - (width*ratio) ) / 2) ) + 'px', 'background-size': width + "px " + Math.round(width*ratio) + "px" /*"100% auto"*/ }); } }); $('[data-bg-video-ratio]').each(function(){ var is_layout = $(this).parent().is('.upfront-output-layout'), is_full_screen = ( $(this).parent().is('.upfront-output-region, .upfront-region-container-bg') && $(this).closest('.upfront-region-container-full').length > 0 ), width = is_layout ? $(window).width() : $(this).outerWidth(), height = is_layout ? $(window).height() : ( is_full_screen ? $(window).height()-body_off.top : $(this).outerHeight() ), ratio = parseFloat($(this).attr('data-bg-video-ratio')), style = $(this).attr('data-bg-video-style') || 'crop', $embed = $(this).children('iframe'); if ( $embed.length === 0) { $embed = $(this).find('video'); } $(this).css('overflow', 'hidden'); $embed.css({ position: 'absolute' }); if ( style == 'crop' ){ if ( Math.round(height/width*100)/100 > ratio ){ var embed_w = Math.round(height/ratio); $embed.css({ width: embed_w, height: height, top: 0, left: Math.round((width-embed_w)/2) }); } else { var embed_h = Math.round(width*ratio); $embed.css({ width: width, height: embed_h, top: Math.round((height-embed_h)/2), left: 0 }); } } else if ( style == 'full' ) { $embed.css({ top: 0, left: 0, width: width, height: height }); } else if ( style == 'inside' ) { if ( Math.round(height/width*100)/100 < ratio ){ var embed_w = Math.round(height/ratio); $embed.css({ width: embed_w, height: height, top: 0, left: Math.round((width-embed_w)/2) }); } else { var embed_h = Math.round(width*ratio); $embed.css({ width: width, height: embed_h, top: Math.round((height-embed_h)/2), left: 0 }); } } }); $('.upfront-output-object .upfront-featured-image-smaller').each(function() { var $img = $(this), $container = $img.parent(), data = $img.data('featured-image'), align = $img.data('featured-align'), valign = $img.data('featured-valign'), dotalign = $img.data('featured-dotalign'), mode = $img.data('featured-mode'), imgHeight = $img.height(), imgWidth = $img.width(), breakpoint = get_breakpoint() ; // If table or mobile breakpoint, image is smaller than container and dotAlign is true make it inline if((breakpoint === "tablet" || breakpoint === "mobile") && ((mode === "small" || mode === "vertical" ) && dotalign === true)) { // Set text-align for parent container $container.css({ 'textAlign': align, 'maxWidth': '100%' }); // Make image inline $img.css({ 'position': 'static', 'display': 'inline-block' }); // Update margin to position image top or bottom /*if(valign === "center") { $img.css({ 'marginTop': (data.offsetHeight / 2) - (imgHeight / 2), }); } else if (valign === "bottom") { $img.css({ 'marginTop': (data.offsetHeight - imgHeight), }); }*/ } else { if((breakpoint === "tablet" || breakpoint === "mobile") && mode === "small") { // Null above $container.css({ 'textAlign': 'center', 'maxWidth': '100%', 'width': '100%' }); $img.css({ 'position': 'static', 'display': 'inline-block' }); } else if ((breakpoint === "tablet" || breakpoint === "mobile") && mode !== "small") { // Set image 100% width $container.css({ 'width': '100%', 'height': 'auto' }); $img.css({ 'width': '100%', 'height': 'auto', 'left': 0 }); } else { // Null above and position image into parent container $img.css({ 'top': data.offsetTop, 'left': data.offsetLeft, 'position': 'relative', 'display': 'block', 'marginTop': 0, 'width': 'initial' }); $container.css({ 'width': data.offsetWidth, 'height': data.offsetHeight}); } } }); $('.upfront-output-object .uf-post .thumbnail, .uf-post-data .upostdata-part.thumbnail').each(function(){ var is_upostdata = $(this).hasClass('upostdata-part'), $object = $(this).closest('.upfront-output-object'), height = is_upostdata ? parseInt($object.css('min-height'), 10) : $(this).height(), width = $(this).width(), padding_top = parseInt($object.css('padding-top'), 10), padding_bottom = parseInt($object.css('padding-bottom'), 10), $img = $(this).find('img'), $container = $(this), imgHeight = $img.height(), imgWidth = $img.width(), breakpoint = get_breakpoint(), img = new Image, img_h, img_w ; if ( is_upostdata ) { if(breakpoint === "tablet" || breakpoint === "mobile") { // Set image 100% width $container.css({ 'width': '100%', 'height': 'auto' }); $img.css({ 'width': '100%', 'height': 'auto' }); // Set height to image height = imgHeight; $object.css('min-height', height); $object.closest('.upfront-output-object-group').css('min-height', height); } else { $object.css('min-height', ''); $object.closest('.upfront-output-object-group').css('min-height', ''); } if ( !$img.hasClass('upfront-featured-image-fit-wrapper') ) return; // No fit for this height -= padding_top + padding_bottom; $(this).css('height', height); } if ( $(this).attr('data-resize') == "1" ) { img.src = $img.attr('src'); img_h = img.height; img_w = img.width; if ( height/width > img_h/img_w ) { $img.css({ height: '100%', width: 'auto', marginLeft: (width-Math.round(height/img_h*img_w))/2, marginTop: "" }); } else { $img.css({ height: 'auto', width: '100%', marginLeft: "", marginTop: (height-Math.round(width/img_w*img_h))/2 }); } } else { img_h = $img.height(); if ( height != img_h ) { $img.css('margin-top', (height-img_h)/2); } } }); } fix_full_bg(); var lazyFixFullBg = throttle(fix_full_bg, 500); $(window).on('resize.uf_layout', lazyFixFullBg); $(window).on('load.uf_layout', lazyFixFullBg); // Regions behavior on scroll var _scroll_data = {}; function regions_scroll_update () { var breakpoint = get_breakpoint(), body_off = typeof _scroll_data.body_off != 'undefined' ? _scroll_data.body_off : $('body').offset(), scroll_top = $(window).scrollTop(), win_height = $(window).height(), scroll_bottom = scroll_top + win_height, $sticky_regions = typeof _scroll_data.$sticky_regions != 'undefined' ? _scroll_data.$sticky_regions : $('.upfront-output-region-container[data-sticky="1"], .upfront-output-region-sub-container[data-sticky="1"]'), $floating_regions = typeof _scroll_data.$floating_regions != 'undefined' ? _scroll_data.$floating_regions : $('.upfront-output-region-container.upfront-region-container-full, .upfront-output-region-container.upfront-region-container-full .upfront-output-region-sub-container:not(.upfront-output-region-container-sticky), .upfront-output-region.upfront-region-side-fixed[data-restrict-to-container="1"]') ; _scroll_data.body_off = body_off; _scroll_data.$sticky_regions = $sticky_regions; _scroll_data.$floating_regions = $floating_regions; if ( body_off.top > 0 ){ scroll_top += body_off.top; win_height -= body_off.top; } scroll_top = scroll_top < body_off.top ? body_off.top : scroll_top; // Sticky region behavior $sticky_regions.each(function(){ var is_sub_container = $(this).hasClass('upfront-output-region-sub-container'), is_top = ( is_sub_container && $(this).nextAll('.upfront-grid-layout').length > 0 ), offset = $(this).offset(), sticky_top = $(this).data('sticky-top'), css = {}; if ( typeof sticky_top != 'number' && scroll_top > offset.top ) { css.position = 'fixed'; css.top = $('#wpadminbar').css('position') != 'fixed' ? 0 : body_off.top; css.left = 0; css.right = 0; css.bottom = 'auto'; $(this).addClass('upfront-output-region-container-sticky'); $(this).data('sticky-top', offset.top); if ( is_sub_container ) { $(this).closest('.upfront-region-container-bg').css( ( is_top ? 'padding-top' : 'padding-bottom' ), $(this).height() ); $(this).find('.upfront-region-container-bg').css({position: 'fixed', top: 0}); } else { $(this).next('.upfront-output-region-container').css('padding-top', $(this).height()); } } else if ( typeof sticky_top == 'number' && scroll_top <= sticky_top ) { css.position = ''; css.top = ''; css.left = ''; css.right = ''; css.bottom = ''; $(this).removeClass('upfront-output-region-container-sticky'); $(this).removeData('sticky-top'); if ( is_sub_container ) $(this).closest('.upfront-region-container-bg').css( ( is_top ? 'padding-top' : 'padding-bottom' ), ''); else $(this).next('.upfront-output-region-container').css('padding-top', ''); } $(this).css(css); }); // Floating behavior $floating_regions.each(function(){ var is_float = $(this).is('.upfront-region-side-fixed'), is_full_screen = $(this).is('.upfront-region-container-full'), is_sub_container = $(this).is('.upfront-output-region-sub-container'), $container = $(this).closest('.upfront-output-region-container'), container_height = $container.outerHeight(), container_offset = $container.offset(), container_bottom = container_offset.top + container_height, height = $(this).height(), top = is_float ? parseInt($(this).attr('data-top'), 10) : 0, is_top = is_float ? ( typeof $(this).attr('data-top') != "undefined" ) : ( $(this).nextAll('.upfront-grid-layout').length > 0 ), bottom = is_float ? parseInt($(this).attr('data-bottom'), 10) : 0, is_bottom = is_float ? ( typeof $(this).attr('data-bottom') != "undefined" ) : ( $(this).prevAll('.upfront-grid-layout').length > 0 ), css = {} ; if ( is_full_screen ) { var $bg_image = $(this).find('.upfront-region-container-bg'), is_bg_image = ( $bg_image.css('background-image') != 'none' ), $bg_overlay = $(this).find('.upfront-output-bg-overlay:visible'), is_bg_overlay = ( $bg_overlay.length > 0 ), bg_position_y = 0, bg_position_x = 0, bg_position_css = $bg_image.css('background-position') ; if ( is_bg_image ) { if ( typeof $bg_image.data('bg-position-y') == 'undefined' ) $bg_image.data('bg-position-y', bg_position_css.match(/\d+(%|px|)$/)[0]); if ( typeof $bg_image.data('bg-position-x') == 'undefined' ) $bg_image.data('bg-position-x', bg_position_css.match(/^\d+(%|px|)/)[0]); bg_position_y = $bg_image.data('bg-position-y'); bg_position_x = $bg_image.data('bg-position-x'); if ( typeof bg_position_y == 'string' && bg_position_y.match(/%$/) ){ var img = new Image; img.src = $bg_image.css('background-image').replace(/^url\(\s*['"]?\s*/, '').replace(/\s*['"]?\s*\)$/, ''); bg_position_y = parseInt(bg_position_y, 10)/100 * (height-img.height); } else { bg_position_y = parseInt(bg_position_y, 10); } } } if ( scroll_top >= container_offset.top && scroll_bottom <= container_bottom ){ if ( is_float || is_sub_container ) { css.position = 'fixed'; if ( is_top ) css.top = top + body_off.top; else { css.top = 'auto'; css.bottom = bottom; } } if ( is_sub_container ){ css.left = 0; css.right = 0; if ( is_top ) $container.find('> .upfront-region-container-bg').css('padding-top', height); else $container.find('> .upfront-region-container-bg').css('padding-bottom', height); } if ( is_full_screen ){ if ( is_bg_image ) { $bg_image.css({ backgroundAttachment: 'fixed', backgroundPosition: bg_position_x + ' ' + bg_position_y + 'px' }); } else if ( is_bg_overlay ) { $bg_overlay.css({ position: 'fixed', top: ( scroll_top - body_off.top ) }); } } } else { if ( is_float ) { css.position = 'absolute'; if ( is_top ) { if ( container_height > win_height && scroll_top >= ( container_offset.top + container_height - win_height ) ) css.top = container_height - win_height + top; else css.top = top; } else { if ( container_height > win_height && scroll_bottom <= ( container_offset.top + win_height ) ) css.bottom = container_height - win_height + bottom; else css.bottom = bottom; } } else if ( is_sub_container ) { css.position = 'relative'; if ( is_top ) { css.top = container_height - win_height + top; } // If sticky subregion. if ($(this).data('sticky') === 1) { // If scrolled to top of subregion's home, switch to position relative. if (is_top ? $(window).scrollTop() < body_off.top : $(window).scrollTop() < container_bottom - $(this).height()) { $(this).find('.upfront-region-container-bg').css({position: 'relative', top: ''}); // Make sure subregion is on top of page (scrolling fast made it forget to go to the top). css.top = 0; } else { // Else switch to fixed position. $(this).find('.upfront-region-container-bg').css({position: 'fixed', top: body_off.top}); } } css.bottom = ''; css.left = ''; css.right = ''; $container.find('> .upfront-region-container-bg').css({ paddingTop: '', paddingBottom: '' }); } else if ( is_full_screen ) { if ( is_bg_image ) { $bg_image.css({ backgroundAttachment: '', backgroundPosition: bg_position_x + ' ' + ( bg_position_y + ( container_height - win_height ) ) + 'px' }); } else if ( is_bg_overlay ) { $bg_overlay.css({ position: '', top: ( container_height - win_height ) }); } } } $(this).css(css); }); } regions_scroll_update(); $(window).on('load.uf_layout', regions_scroll_update); var lazyScrollUpdate = throttle(regions_scroll_update, 100); $(window).on('scroll.uf_layout', regions_scroll_update); $(window).on('resize.uf_layout', lazyScrollUpdate); /* Lightbox front end logic */ var overlay = $('
'), close= $('
'), close_icon= $('
'); $("[data-group-link]").css({'cursor': 'pointer'}); $(document).on("click", "[data-group-link]", function () { var url = $(this).data("groupLink"); var target = $(this).data("groupTarget") || '_self'; if(url.indexOf('#') === -1) { // Not an anchor, follow link window.open(url, target); return; } // It is an anchor if (url.match(/^#.*/) !== null) { // Starts with #, it's safe to do the jQuery stuff var nav = $('.upfront-output-region-container[data-sticky="1"], .upfront-output-region-sub-container[data-sticky="1"]').first(); var height = nav.height() ? nav.height() : 0; $('html,body').animate({scrollTop: $(url).offset().top - height },'slow'); return; } // It's an absolute url with anchor var urlParts = url.split('#'); if (urlParts[0] === location.origin + location.pathname) { // Target is on the current page var nav = $('.upfront-output-region-container[data-sticky="1"], .upfront-output-region-sub-container[data-sticky="1"]').first(); var height = nav.height() ? nav.height() : 0; $('html,body').animate({scrollTop: $('#' + urlParts[1]).offset().top - height },'slow'); return; } // It's not on the current page if ($(this).attr('target') === '_blank') { // Open in a new window window.open(url); return; } // Open in this window window.location = url; }); $(document).on('click', 'a', function(e) { //If we are in the editor the lightbox is open using the region. //if(typeof(Upfront) != 'undefined' && Upfront.Views) //return; if($(e.target).closest('div.redactor_box') > 0) return; if($('div#sidebar-ui').length > 0 && $('div#sidebar-ui').css('display') == 'block') { if($(e.target).hasClass('upfront_cta')) { e.preventDefault(); return; } var url = $(e.target).attr('href'); if(url && url.indexOf && url.indexOf('#ltb-') > -1) { e.preventDefault(); var regions = Upfront.Application.layout.get('regions'); var urlanchor = url.split('#'); region = regions ? regions.get_by_name(urlanchor[1]) : false; if(region){ //hide other lightboxes _.each(regions.models, function(model) { if(model.attributes.sub == 'lightbox') Upfront.data.region_views[model.cid].hide(); }); var regionview = Upfront.data.region_views[region.cid]; regionview.show(); } } return; } var url = $(this).attr('href'); if(!url) { return; } if(url.indexOf('#') === -1) return; if($(this).closest('div.upfront-navigation').data('style') == 'burger' && $(this).parent('li.menu-item.menu-item-has-children').length > 0) { var linkitem = $(this).parent('li.menu-item.menu-item-has-children'); if(linkitem.children('ul.sub-menu').closest('li.menu-item').hasClass('burger_sub_display')) linkitem.children('ul.sub-menu').closest('li.menu-item').removeClass('burger_sub_display'); else linkitem.children('ul.sub-menu').closest('li.menu-item').addClass('burger_sub_display'); var menu = linkitem.closest('ul.menu'); var menucontainer = menu.closest('div.upfront-output-unewnavigation').children('div'); if(menucontainer.data('burger_over') == 'pushes' && menucontainer.data('burger_alignment') == 'top') { $('div#page').css('margin-top', menu.height()); //var topbar_height = $('div#upfront-ui-topbar').outerHeight(); var adminbar_height = $('div#wpadminbar').outerHeight(); menu.offset({top:adminbar_height, left:$('div').offset().left}); //menu.width($('div#page').width()); } } e.preventDefault(); var tempurl = url.split('#'); if(tempurl[1].trim() === '') { return; } if (tempurl[1].trim().indexOf('ltb-') == 0) { var lightbox = $('div.upfront-region-'+tempurl[1].trim()); overlay.css('background-color', lightbox .data('overlay')).insertBefore(lightbox); if(lightbox.data('closeicon') == 'yes' || lightbox.data('addclosetext') == 'yes') { lightbox.prepend(close); if(lightbox.data('addclosetext') == 'yes') { close.append($('

'+lightbox.data('closetext')+'

')); if(lightbox.data('closeicon') == 'yes') close.children('h3').css('margin-right', '40px'); } if(lightbox.data('closeicon') == 'yes') close.append(close_icon); close.bind('click', function() { lightboxhide(); }); } if(lightbox.data('clickout') == 'yes') { overlay.bind('click', function() { lightboxhide(); }); } // If Grid exists, use that. Otherwise default to 45px per column. var column_width = typeof Upfront !== 'undefined' && Upfront.Settings ? Upfront.Settings.LayoutEditor.Grid.column_width : 45; // Note that max-width and max-height are set in global.css for responsive design. // translate width in columns to width in pixels var lightbox_width = column_width * lightbox.data('col'); var lightbox_height = lightbox.data('height'); lightbox.show().css({'width': lightbox_width, 'height': lightbox_height, 'min-height': 200}); // Based upon above CSS. lightbox.css({'margin-left': -(parseInt(lightbox.width()/2, 10)), 'margin-top': -(parseInt(lightbox.height()/2, 10))}); /* elements can subscribe to the following event to * to render their content based * on the dimensions of the lightbox * itself, such elements are gallery and slider */ $(document).trigger("upfront-lightbox-open", lightbox); e.preventDefault(); function lightboxhide() { close.html('').remove() overlay.remove(); lightbox.hide(); // Stop YT video if any var yt_video = lightbox.find('.upfront-youtube-container iframe'); if(yt_video.length) { var yt_src = yt_video.attr('src'); yt_video.attr('src', '').attr('src', yt_src); } } return; } var nav = $('.upfront-output-region-container[data-sticky="1"], .upfront-output-region-sub-container[data-sticky="1"]').first(); var height = nav.height() ? nav.height() : 0; //It is an anchor // Starts with #, it's safe to do the jQuery stuff if (url.match(/^#.*/) !== null) { $('html,body').animate({scrollTop: $(url).offset().top - height },'slow'); return; } // It's an absolute url with anchor var urlParts = url.split('#'); if (urlParts[0] === location.origin + location.pathname) { // Target is on the current page $('html,body').animate({scrollTop: $('#' + urlParts[1]).offset().top - height },'slow'); return; } // It's not on the current page if ($(this).attr('target') === '_blank') { // Open in a new window window.open(url); return; } // Open in this window window.location = url; }); /* Lazy loaded image */ var image_lazy_load_t; var image_lazy_scroll = window._upfront_image_lazy_scroll; function image_lazy_load () { clearTimeout(image_lazy_load_t); image_lazy_load_t = setTimeout(function(){ var scroll = $(window).scrollTop(), w_height = $(window).height(), w_width = $(window).width(); $('.upfront-image-lazy').each(function(){ if ( $(this).hasClass('upfront-image-lazy-loading') ) return; var me = this, offset = $(this).offset(), height = $(this).height(), width = $(this).width(), source, src, closest; if ( ( ( image_lazy_scroll && offset.top+height >= scroll && offset.top < scroll+w_height ) || !image_lazy_scroll ) && ( width > 0 && height > 0 ) ){ source = $(this).attr('data-sources'); if ( source ) source = JSON.parse(source); else src = $(this).attr('data-src'); if ( typeof source != 'undefined' && source.length || src ){ if ( typeof source != 'undefined' && source.length ){ for ( var s = 0; s < source.length; s++ ) { if ( source[s][1] <= width || ( closest >= 0 && source[closest][1] < width && source[s][1] > width ) ) closest = s; } if ( $(this).data('loaded') == closest ) return; src = source[closest][0]; $(this).data('loaded', closest); } else if ( src && $(this).hasClass('upfront-image-lazy-loaded') ){ return; } $(this).removeClass('upfront-image-lazy-loaded').addClass('upfront-image-lazy-loading'); $('').attr('src', src).on('load', function(){ if ( $(me).hasClass('upfront-image-lazy-bg') ) $(me).css('background-image', 'url("' + $(this).attr('src') + '")'); else $(me).attr('src', $(this).attr('src')); $(me).removeClass('upfront-image-lazy-loading').addClass('upfront-image-lazy-loaded'); }); } } }); }, 100); } /** * The queue object, used to chain-load images within a load level. */ function LazyLoad_Queue () { var deferreds = [], targets = [] ; function get_lazy_loading_image_promise (obj) { var deferred = new $.Deferred(); obj.$el.removeClass('upfront-image-lazy-loaded').addClass('upfront-image-lazy-loading'); $('') .attr('src', obj.url) .on('load', function () { if (obj.$el.is(".upfront-image-lazy-bg")) obj.$el.css('background-image', 'url("' + obj.url + '")'); else (obj.$el.attr('src', obj.url)); obj.$el.removeClass('upfront-image-lazy-loading').addClass('upfront-image-lazy-loaded'); deferred.resolve(); }) .on('error abort', function () { deferred.reject(); }) ; return deferred.promise(); } function add (src, $img) { targets.push({ url: src, $el: $img }); } function start () { var semaphore = new $.Deferred(); $.each(targets, function (idx, obj) { deferreds.push(get_lazy_loading_image_promise(obj)); }); $.when.apply($, deferreds) .always(function () { semaphore.resolve(); }) ; return semaphore.promise(); } return { add: add, start: start } } /** * The stack of queues, used to chain-load queued levels. */ function LazyLoad_QueueStack (queues) { function start () { queues.reverse(); execute(); } function execute () { var q = queues.pop(); if (!q) return false; q.start().done(execute); } return { start: start }; } /** * Initial background loading of the images. * Separate images into priority queues and load each one appropriately. */ function image_lazy_load_bg () { var secondary_delta = 1500, // Sources $images = $('.upfront-image-lazy'), // Queues primary = new LazyLoad_Queue(), secondary = new LazyLoad_Queue(), tertiary = new LazyLoad_Queue(), // Misc scroll = $(window).scrollTop(), w_height = $(window).height(), w_width = $(window).width(), breakpoint = get_breakpoint() ; breakpoint = !breakpoint || 'none' === breakpoint ? 'desktop' : breakpoint; // "none" in FF if (!$images.length) return false; $images.each(function () { var $img = $(this), offset = $img.offset(), source = $img.attr('data-sources'), src = $img.attr('data-src'), point_src = $img.attr('data-src-' + breakpoint), height = $img.height(), width = $img.width() ; //Remove blank.gif to calculate width correctly $img.attr('src', ''); if ($img.is(".upfront-image-lazy-loaded")) return true; // already loaded if (!source && !src && !point_src) return true; // we don't know how to load if (height <= 0 && width <= 0) return true; // Don't lazy load backgrounds for hidden regions. if (source) { // Deal with source JSON and populate `src` from there var width = $img.width(), closest = 0 ; source = JSON.parse(source); for ( var s = 0; s < source.length; s++ ) { if ( source[s][1] <= width || ( closest >= 0 && source[closest][1] < width && source[s][1] > width ) ) closest = s; } if ( $(this).data('loaded') == closest ) return true; src = source[closest][0]; // Use this to load $(this).data('loaded', closest); } else if (point_src) src = point_src; if (offset.top+height >= scroll && offset.top < scroll+w_height) { primary.add(src, $img); } else if (offset.top+height+secondary_delta >= scroll && offset.top < scroll+w_height+secondary_delta) { secondary.add(src, $img); } else { tertiary.add(src, $img); } }); $(window).off('scroll', image_lazy_load); // Since we scheduled image loads, kill the scroll load // We're ready now var stack = new LazyLoad_QueueStack([ // Order is significant primary, secondary, tertiary ]).start(); } // Initialize appropriate behavior var lazyImageLazyLoad = throttle(image_lazy_load, 100); $(window).on('resize', lazyImageLazyLoad); // Okay, so this should keep on happening on resizes if ( image_lazy_scroll ) { $(window).on('scroll', lazyImageLazyLoad); image_lazy_load(); } else { $(image_lazy_load_bg); // Do background load instead } /* Responsive custom theme styles */ function update_theme_styles () { var breakpoint = get_breakpoint(); $('[data-theme-styles]').each(function(){ var theme_styles = $(this).attr('data-theme-styles'), classes = []; theme_styles = theme_styles.replace("\"default\":", "\"defaults\":"); if ( theme_styles ) theme_styles = JSON.parse(theme_styles); $.each(theme_styles, function(id, style_class){ classes.push(style_class); }); $(this).removeClass(classes.join(' ')); if ( !breakpoint && theme_styles.defaults ) $(this).addClass( theme_styles.defaults ); else if ( breakpoint && ( theme_styles[breakpoint] || theme_styles.defaults ) ) $(this).addClass( theme_styles[breakpoint] ? theme_styles[breakpoint] : theme_styles.defaults ); }); } update_theme_styles(); var lazyUpdateThemeStyles = throttle(update_theme_styles, 100); $(window).on('resize.uf_layout', lazyUpdateThemeStyles); /* Apply responsive class */ function update_responsive_class () { var breakpoint = get_breakpoint(); if ( $('#page').hasClass('upfront-layout-view') ){ return remove_responsive_class(); } if (previous_breakpoint) { $('#page').removeClass(previous_breakpoint + '-breakpoint'); } if ( breakpoint && breakpoint !== 'none' && breakpoint !== 'desktop' ) { $('html').addClass('uf-responsive'); $('#page').removeClass('desktop-breakpoint default-breakpoint').addClass('responsive-breakpoint ' + breakpoint + '-breakpoint'); } else { $('#page').removeClass('responsive-breakpoint').addClass('default-breakpoint desktop-breakpoint'); remove_responsive_class(); } } function remove_responsive_class () { $('html').removeClass('uf-responsive'); } function reset_responsive_class () { var breakpoint = get_breakpoint(); if ( breakpoint ) { $('#page').removeClass(breakpoint + '-breakpoint'); } } update_responsive_class(); var lazyUpdateResponsiveClass = throttle(update_responsive_class, 100); $(window).on('resize.uf_layout', lazyUpdateResponsiveClass); /** * Trigger DOM event on breakpoint change, * so elements can subscribe to it * * Front-end responsive presets propagation depends on this * event being fired properly */ function propagate_breakpoint_change () { var breakpoint = get_breakpoint() || 'desktop', previous = get_previous_breakpoint() || 'desktop' ; if (breakpoint !== previous) { /** * Trigger a DOM event on actual breakpoint change * Responsive presets propagation listens for this event */ $(document).trigger("upfront-breakpoint-change", breakpoint); } } var lazy_propagate_breakpoint_change = throttle(propagate_breakpoint_change, 20, {trailing: false}); $(window).on('resize.uf_layout', lazy_propagate_breakpoint_change); // done propagating breakpoint change /** * Swap preset classes per breakpoint for each of the object elements * Happens only on breakpoint change event */ function propagate_responsive_presets (e, breakpoint) { breakpoint = breakpoint || get_breakpoint() || 'desktop'; if (!breakpoint) return; $("[data-preset_map]").each(function () { var $me = $(this), rmap = $me.attr("data-preset_map"), map = rmap ? JSON.parse(rmap) : {}, current_preset_class, final_preset_class ; // Edge case, for when we don't have a preset for this // breakpoint in an element - it should retain its classes // if (!map[breakpoint]) return true; // we have to provide proper fallback here, mobile -> tablet -> desktop if ( breakpoint == 'mobile' ) { map[breakpoint] = map[breakpoint] || map['tablet'] || map['desktop']; } else if ( breakpoint == 'tablet' ) { map[breakpoint] = map[breakpoint] || map['desktop']; } else { map[breakpoint] = map[breakpoint]; } $.each(map, function (bp, preset) { if ( $me.hasClass(preset) ) { current_preset_class = preset; $me.removeClass(preset); } if (bp === breakpoint && !final_preset_class) final_preset_class = preset; }); if (final_preset_class) { $me.addClass(final_preset_class); // find all children with such preset class, some elements do have this $me.find('.' + current_preset_class).each(function(){ $(this).removeClass(current_preset_class); $(this).addClass(final_preset_class); }); } }); /** * Trigger a DOM event on responsive presets change * The legacy preset elements (accordion, tabs, button) listen to this event */ $(document).trigger("upfront-responsive_presets-changed", breakpoint); } var lazy_propagate_responsive_presets = throttle(propagate_responsive_presets, 200, {trailing: false}); $(document).on("upfront-breakpoint-change", lazy_propagate_responsive_presets); // done propagating presets // Make sure breakpoint change is propagated propagate_breakpoint_change(); // end function remove_all_bound_events () { $(window).off('resize.uf_layout'); $(window).off('scroll.uf_layout'); $(window).off('load.uf_layout'); // Also destroy parallax $('.upfront-output-layout .upfront-parallax').uparallax('destroy'); } $(document).on('upfront-load', function(){ Upfront.Events.once("application:mode:before_switch", remove_all_bound_events); Upfront.Events.once("application:mode:before_switch", reset_responsive_class); Upfront.Events.once("layout:render", remove_responsive_class); }); // remove inline panels on Image Insert redactor-box FE var $image_insert_inline_panels = $('.upfront-output-wrapper .upfront-inserted_image-basic-wrapper').find('.upfront-inline-panel-item'); if ( $image_insert_inline_panels.length > 0 ) { $image_insert_inline_panels.remove(); } // Keyboard Focus Styles http://codepen.io/fusco/pen/4de5926b34d3a76c9ac9854b6beefebb $(this).on('focusin', function (e) { $('.keyboard-outline').removeClass('keyboard-outline'); var wasByKeyboard = lastClick < lastKey; if (wasByKeyboard) { $(e.target).addClass('keyboard-outline'); } }); $(this).on('mousedown', function () { lastClick = new Date(); }); $(this).on('keydown', function () { lastKey = new Date(); }); }); /* upfront-effect */ (function( $ ) { var rAFPollyfill = function(callback){ var currTime = new Date().getTime(), lastTime, timeToCall = Math.max(0, 16 - (currTime - lastTime)), id = setTimeout(function() { callback(currTime + timeToCall); }, timeToCall) ; lastTime = currTime + timeToCall; return id; }; var rgba_to_rba = function(color){ if( typeof Upfront !== "undefined" && Upfront.Util ) // If we are in editor then delegate to Upfront.Util.colors.rgba_to_rgb return Upfront.Util.colors.rgba_to_rgb( color ); return color.replace(/ /g,'').replace(/^rgba\((\d+)\,(\d+)\,(\d+)\,(\d+\.?\d{0,}?)\)$/, "rgb($1, $2, $3)"); }; var requestAnimationFrame = $.proxy(window.requestAnimationFrame, window) || $.proxy(window.webkitRequestAnimationFrame, window) || $.proxy(window.mozRequestAnimationFrame, window) || $.proxy(window.oRequestAnimationFrame, window) || $.proxy(window.msRequestAnimationFrame, window) || rAFPollyfill ; $.fn.uparallax = function (args) { var isMethod = typeof args === 'string', callArgs = isMethod ? Array.prototype.slice.call(arguments, 1) : [], result ; this.each(function () { var $el = $(this), object = $el.data('uparallax') ; if (object) { if (isMethod) { result = object.callMethod(args, callArgs); } } else { if (isMethod) { $.error('Can\'t call the method ' + args + '. The object is not initialized'); } else { // Initialize object args.bgColor = rgba_to_rba( $el.parent().css("background-color") ); $el.data('uparallax', new Upfront_Parallax($el, args)); } } }); if (this.length == 1 & typeof result != 'undefined') { return result; } return this; }; var Upfront_Parallax = function ($el, args) { var me = this, data = $.extend({ autostart: true, element: '', effect: 'scroll', // Available: scroll, rotate, scale, opacity movement: 30, // px rotation: 15, // degrees scaling: 1.1, opacity: 0.5, renderer: this.getDefaultRenderer(), // Available: canvas, absolute, fixed, overflowTop: 100, // px, render more than the background height to prevent artifact on late refresh overflowBottom: 100, // px, render more than the background height to prevent artifact on late refresh bgColor: "#fff" }, args) ; this.opts = data; this.$parent = $el.parent(); this.$element = $el; this.$moveElement = typeof this.opts.element === 'string' ? $el.find(this.opts.element) : this.opts.element; Upfront_Parallax.id++; this.id = Upfront_Parallax.id; Upfront_Parallax.instances[this.id] = this; if (this.opts.autostart) { this.start(); } }; // Static ID Upfront_Parallax.id = 0; Upfront_Parallax.instances = {}; Upfront_Parallax.prevTime = 0; Upfront_Parallax.started = false; Upfront_Parallax.cache = { lastScrollTop: -1, scrollTop: 0, winHeight: 0, scrollBottom: 0 }; Upfront_Parallax.canvas = false; Upfront_Parallax.context = false; Upfront_Parallax.start = function () { if (Upfront_Parallax.started) return; Upfront_Parallax.started = true; Upfront_Parallax.draw(); }; Upfront_Parallax.draw = function (time) { var scrollTop = Upfront_Parallax.cache.scrollTop; if ( Upfront_Parallax.cache.lastScrollTop == scrollTop && time - Upfront_Parallax.prevTime < 5000 // Re-draw every 5 second ) { requestAnimationFrame(Upfront_Parallax.draw); return; } var winHeight = $(window).height(), scrollBottom = Math.round(scrollTop + winHeight); Upfront_Parallax.cache.lastScrollTop = scrollTop; Upfront_Parallax.cache.winHeight = winHeight; Upfront_Parallax.cache.scrollBottom = scrollBottom; for (var id in Upfront_Parallax.instances) { Upfront_Parallax.instances[id].draw(time); } Upfront_Parallax.prevTime = time; requestAnimationFrame(Upfront_Parallax.draw); }; Upfront_Parallax.updateScroll = function (e) { var scrollTop = window.pageYOffset; Upfront_Parallax.cache.scrollTop = scrollTop; }; $(window).one('load.upfront_paralax', Upfront_Parallax.updateScroll); $(window).on('load.upfront_paralax', Upfront_Parallax.draw); $(window).on('scroll.upfront_paralax', Upfront_Parallax.updateScroll); Upfront_Parallax.prototype = { cache: {}, canvas: false, context: false, imgCanvas: false, imgContext: false, callMethod: function (method, args) { switch (method) { case 'start': this.start(); break; case 'stop': this.stop(); break; case 'destroy': this.destroy(); break; case 'refresh': this.refresh(); break; case 'setOption': this.setOption(args[0], args[1]); break; case 'setEffect': this.setOption('effect', args[0]); break; case 'setMovement': this.setOption('movement', args[0]); break; case 'setOpacity': this.setOption('opacity', args[0]); break; case 'setRotation': this.setOption('rotation', args[0]); break; case 'setScaling': this.setOption('scaling', args[0]); break; } }, bindEvents: function () { //$(window).on('scroll.upfront_parallax_' + this.id, $.proxy(this.update, this)); $(window).on('load.upfront_parallax_' + this.id, $.proxy(this.refresh, this)); $(window).on('resize.upfront_parallax_' + this.id, $.proxy(this.refresh, this)); }, unbindEvents: function () { //$(window).off('scroll.upfront_parallax_' + this.id); $(window).off('load.upfront_parallax_' + this.id); $(window).off('resize.upfront_parallax_' + this.id); }, setOption: function (option, value) { this.opts[option] = value; this.refresh(); }, getDefaultRenderer: function () { return 'canvas'; }, start: function () { this.$element.addClass('upfront-parallax'); this.$moveElement.addClass('upfront-parallax-element'); this.reset_cache(); if ('fixed' == this.opts.renderer) { this.prepareFixedPos(); } else if ('canvas' == this.opts.renderer) { this.prepareCanvas(); } this.refresh(); this.bindEvents(); Upfront_Parallax.start(); }, stop: function () { this.$element.removeClass('upfront-parallax'); this.$moveElement.removeClass('upfront-parallax-element'); if ('fixed' == this.opts.renderer) { this.restorePos(); } else if ('canvas' == this.opts.renderer) { this.removeCanvas(); } this.reset(); this.unbindEvents(); }, reset_cache: function() { this.cache = { translate: 0, offsetTop: 0, offsetBottom: 0, offsetLeft: 0, height: 0, width: 0, visible: true, img: false, imgCanvas: false, imgContext: false }; }, reset: function () { this.$moveElement.css({ transform: '', opacity: '', top: '', bottom: '' }); }, destroy: function () { this.stop(); delete Upfront_Parallax.instances[this.id]; this.$element.removeData('uparallax'); }, prepareFixedPos: function () { this.$element.css({ position: 'fixed', top: 0, left: 0 }); }, restorePos: function () { this.$element.css({ position: '', top: '', left: '', transform: '' }); }, prepareCanvas: function () { if (this.canvas === false) { this.canvas = document.createElement('canvas'); this.canvas.id = 'uparallax-' + this.id; $(this.canvas).css({ position: 'fixed', top: 0, left: 0, zIndex: -1, display: 'block', pointerEvents: 'none' }); $('.upfront-output-layout, .upfront-layout').append(this.canvas); } this.context = this.canvas.getContext('2d'); if( this.is_image_png() ) this.context.fillStyle = this.opts.bgColor; this.updateCanvas(); }, updateCanvas: function () { if (this.canvas === false) return; this.canvas.width = $(window).width(); this.canvas.height = $(window).height(); }, removeCanvas: function () { // this.canvas.remove(); // This does not work on IE11 and crash the UF editor $(this.canvas).remove(); }, prepareImage: function () { if (this.cache.img) { if (!this.imgCanvas) this.renderImage(); this.$element.css('display', 'none'); return; } var me = this, img = new Image(), src = this.$moveElement.css('background-image').replace(/^url\(\s*['"]?\s*/, '').replace(/\s*['"]?\s*\)$/, ''), position = this.$moveElement.css('background-position').split(' ') ; // Convert percent to decimal. this.size_percentage = parseInt(this.$moveElement.css('background-size'), 10) * 0.01; // Get user set positions (convert percentage to decimal). this.percent_x = parseInt(position[0], 10) * 0.01; this.percent_y = parseInt(position[1], 10) * 0.01; // Check if scaling is NaN, if it is, we set default parameter if ( isNaN(this.size_percentage) ) { this.size_percentage = 1; this.percent_x = 0.5; this.percent_y = 0.5; } if (src != 'none') { this.cache.img = img; this.cache.background_color = this.$parent.css("background-color") || "#fff"; img.src = src; this.$element.css('display', 'none'); this.$parent.css({ background: 'none' }); } }, renderImage: function () { if (!this.cache.img) return; if (!this.imgCanvas) { this.imgCanvas = document.createElement('canvas'); $(this.imgCanvas).css({ display: 'block' }); this.imgContext = this.imgCanvas.getContext('2d', {alpha: false}); } var width = this.cache.width, height = this.cache.height, parallaxHeight = height + (this.movementOffset*2), winHeight = Upfront_Parallax.cache.winHeight, ratio = this.cache.img.height/this.cache.img.width, imgWidth = width, imgHeight = parallaxHeight, imgY = 0, drawWidth = 0, drawHeight = 0, drawX = 0, drawY = 0 ; this.imgCanvas.width = width; this.imgCanvas.height = parallaxHeight; if (parallaxHeight/width > ratio) { imgWidth = parallaxHeight/ratio; drawWidth = Math.floor(width/imgWidth * this.cache.img.width); } else { imgHeight = width*ratio; drawWidth = this.cache.img.width; } imgY = (height-imgHeight) / 2; drawHeight = Math.floor(parallaxHeight/imgHeight * this.cache.img.height); drawX = (this.cache.img.width - drawWidth) / 2; drawY = (this.cache.img.height - drawHeight) / 2; scale = this.size_percentage; // Offset X and Y by user set position. position_x = (-0.5 * width * scale) + (width * scale * this.percent_x); position_y = (-0.5 * height * scale) + (height * scale * this.percent_y); if ( this.is_image_png() ) { this.fillCanvas(width, parallaxHeight); } try { this.imgContext.drawImage(this.cache.img, drawX, drawY, drawWidth, drawHeight, position_x, position_y, (width * scale), (parallaxHeight * scale)); } catch (e) { Upfront.Util.log('Broken image provided for Parallax'); } }, refresh: function () { this.refreshCache(); var height = this.cache.height, winHeight = $(window).height(), heightOff = Math.round((winHeight - height) / 2) ; if (heightOff - this.opts.movement > this.opts.movement) { this.movementOffset = heightOff - this.opts.movement; } else { this.movementOffset = this.opts.movement; } /* * this.$moveElement must have position absolute, with top and bottom set to 0 initially, height auto * */ this.$moveElement.css({ top: this.movementOffset*-1, bottom: this.movementOffset*-1 //height: height+this.movementOffset*2 }); if ('fixed' == this.opts.renderer) { this.$element.css({ left: this.cache.offsetLeft, height: this.cache.height, width: this.cache.width }); } else if ('canvas' == this.opts.renderer) { this.updateCanvas(); this.renderImage(); } this.update(); }, refreshCache: function () { var offset = this.$parent.offset(), height = this.$parent.height(), width = this.$parent.width() ; this.cache.offsetTop = offset.top; this.cache.offsetBottom = offset.top + height; this.cache.offsetLeft = offset.left; this.cache.height = height; this.cache.width = width; }, update: function () { requestAnimationFrame($.proxy(this.draw, this)); }, draw: function (time) { if ( !(this.id in Upfront_Parallax.instances) ) return; var offsetTop = this.cache.offsetTop, offsetBottom = this.cache.offsetBottom, height = this.cache.height, scrollTop = Upfront_Parallax.cache.scrollTop, scrollBottom = Upfront_Parallax.cache.scrollBottom, winHeight = Upfront_Parallax.cache.winHeight, moveHeight = (this.movementOffset * 2) + (this.opts.movement * 2), range = 2 * this.movementOffset, movement = (this.movementOffset > 0 ? range / moveHeight : 1), translate = Math.round(movement * (scrollBottom - offsetTop - height)) - this.movementOffset, maxTranslate = Math.round(movement * (winHeight)) - this.movementOffset, minTranslate = maxTranslate*-1, effects = this.opts.effect.split(','), transform = '' ; if ('canvas' == this.opts.renderer) { this.prepareImage(); if (!this.cache.img) return; } if (offsetBottom > scrollTop && offsetTop < scrollBottom) { if ('fixed' == this.opts.renderer) { if (!this.cache.visible) { this.$element.css('visibility', 'visible'); } this.$element.css({ //transform: 'translate3d(0, ' + (offsetTop-scrollTop) + 'px, 0)' transform: 'translateY(' + (offsetTop-scrollTop) + 'px)' }); } this.cache.visible = true; } else { if (this.cache.visible) { if ('fixed' == this.opts.renderer) { this.$element.css({ visibility: 'hidden' }); } else if ('canvas' == this.opts.renderer) { this.clearCanvas(); } this.cache.visible = false; } } if (translate > maxTranslate) { translate = maxTranslate; } else if (translate < minTranslate) { translate = minTranslate; } if (!this.cache.visible) return; this.cache.translate = translate; if ('canvas' == this.opts.renderer) { this.drawCanvas(translate, maxTranslate); } else { for (var i in effects) { var effect = this.getEffect(effects[i], translate, maxTranslate); if (effect.property == 'transform') { transform += (transform == '' ? '' : ' '); transform += effect.value; } else { this.$moveElement.css(effect.property, effect.value); } } if (transform !== '') { this.$moveElement.css('transform', transform); } } }, drawCanvas: function (translate, maxTranslate) { if (!this.cache.img || !this.imgCanvas) return; var offsetTop = this.cache.offsetTop, offsetBottom = this.cache.offsetBottom, offsetLeft = this.cache.offsetLeft, width = this.cache.width, height = this.cache.height, parallaxHeight = height + (this.movementOffset*2), scrollTop = Upfront_Parallax.cache.scrollTop, scrollBottom = Upfront_Parallax.cache.scrollBottom, winHeight = Upfront_Parallax.cache.winHeight, visibleHeight = height, ratio = this.cache.img.height/this.cache.img.width, imgWidth = width, imgHeight = parallaxHeight, imgY = 0, drawWidth = 0, drawHeight = 0, drawVisibleHeight = 0, drawX = 0, drawY = 0, drawRelY = 0, closest = this.findClosestInstances(), clearTop = offsetTop, clearBottom = offsetBottom ; if (offsetTop < scrollTop) { visibleHeight = offsetBottom - scrollTop; } else if (offsetBottom > scrollBottom) { visibleHeight = scrollBottom - offsetTop; } visibleHeight = Math.min(winHeight, visibleHeight); drawY = (parallaxHeight > height ? Math.round((parallaxHeight - height) / 2) : 0); if (offsetTop < scrollTop) { drawRelY = scrollTop - offsetTop; drawY += drawRelY; } drawY += translate * -1; if (closest.top && closest.top.cache.offsetBottom < offsetTop) { clearTop -= Math.min(this.opts.overflowTop, Math.ceil((offsetTop - closest.top.cache.offsetBottom) / 2)); } else if (!closest.top) { clearTop -= this.opts.overflowTop; } if (closest.bottom && closest.bottom.cache.offsetTop > offsetBottom) { clearBottom += Math.min(this.opts.overflowBottom, Math.floor((closest.bottom.cache.offsetTop - offsetBottom) / 2)); } else if (!closest.bottom) { clearBottom += this.opts.overflowBottom; } this.context.drawImage(this.imgCanvas, 0, 0, width, parallaxHeight, offsetLeft, offsetTop-this.movementOffset-scrollTop+translate, width, parallaxHeight); if (clearTop > scrollTop) { this.context.clearRect(offsetLeft, 0, width, clearTop-scrollTop); } if (winHeight > clearBottom-scrollTop) { this.context.clearRect(offsetLeft, clearBottom-scrollTop, width, winHeight-(clearBottom-scrollTop)); } }, /** * Checks if image src image in png * @returns {boolean|*|Array|{index: number, input: string}} */ is_image_png: function(){ return this.cache.img && this.cache.img.src && this.cache.img.src.toLowerCase().match(/.png/); }, fillCanvas: function(width, parallaxHeight){ this.imgContext.fillStyle = this.opts.bgColor; this.imgContext.rect(0, 0, width, parallaxHeight); this.imgContext.fill(); }, clearCanvas: function () { this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); }, findClosestInstances: function () { var current = false, closestTop = false, closestBottom = false ; for (var id in Upfront_Parallax.instances) { current = Upfront_Parallax.instances[id]; if (current.id == this.id) continue; if (current.cache.offsetBottom <= this.cache.offsetTop) { if (closestTop !== false && closestTop.cache.offsetBottom > current.cache.offsetBottom) continue; closestTop = current; } else if (current.cache.offsetTop >= this.cache.offsetBottom) { if (closestBottom !== false && closestBottom.cache.offsetTop < current.cache.offsetTop) continue; closestBottom = current; } } return { top: closestTop, bottom: closestBottom }; }, getEffect: function (effect, translate, maxTranslate) { var property = 'transform', value = '', position = translate/maxTranslate ; switch (effect) { case 'scroll': //value = 'translate3d(0, ' + translate + 'px, 0)'; value = 'translateY(' + translate + 'px)'; //property = 'margin-top'; //value = translate; break; case 'rotate': value = 'rotate(' + (position*this.opts.rotation) + 'deg)'; break; case 'scale': value = 'scale(' + (1 - ( (1-this.opts.scaling) * Math.abs(position) )) + ')'; break; case 'opacity': property = 'opacity'; value = 1 - ( (1-this.opts.opacity) * Math.abs(position) ); break; } return { property: property, value: value }; } }; }( jQuery )); /* upfront-default-map */ // If Google Maps has Authentication error (must be global function). function gm_authFailure() {return google_maps_auth_error = true}; (function($){ var throttle = function(a,b,c){var d,e,f,g=null,h=0;c||(c={});var i=function(){h=c.leading===!1?0:new Date().getTime(),g=null,f=a.apply(d,e),g||(d=e=null)};return function(){var j=new Date().getTime();h||c.leading!==!1||(h=j);var k=b-(j-h);return d=this,e=arguments,0>=k||k>b?(clearTimeout(g),g=null,h=j,f=a.apply(d,e),g||(d=e=null)):g||c.trailing===!1||(g=setTimeout(i,k)),f}}; function init_map ($el) { if ( $el.data('map') ) return; var data = JSON.parse($el.attr('data-bg-map')), options = { center: new google.maps.LatLng(data.center[0], data.center[1]), zoom: parseInt(data.zoom, 10) || 0, mapTypeId: google.maps.MapTypeId[data.style], panControl: (data.controls && data.controls.indexOf("pan") >= 0), zoomControl: (data.controls && data.controls.indexOf("zoom") >= 0), mapTypeControl: (data.controls && data.controls.indexOf("map_type") >= 0), scaleControl: (data.controls && data.controls.indexOf("scale") >= 0), streetViewControl: (data.controls && data.controls.indexOf("street_view") >= 0), overviewMapControl: (data.controls && data.controls.indexOf("overview_map") >= 0), scrollwheel: false, styles: (data.use_custom_map_code ? JSON.parse(data.styles) || false : false) }, map = new google.maps.Map($el.get(0), options) ; $el.data('map', map); if (!!data.show_markers) { var mrk = new google.maps.Marker({ position: options.center, draggable: false, map: map }); } } function load_google_maps () { if ($(document).data("upfront-google_maps-loading")) return false; $(document).data("upfront-google_maps-loading", true); if (typeof google === 'object' && typeof google.maps === 'object' && typeof google.maps.Map === 'object') return upfront_bg_map_init(); var protocol = '', key = (window._upfront_api_keys || {})['gmaps'] || false, script = document.createElement("script") ; try { protocol = document.location.protocol; } catch (e) { protocol = 'http:'; } key = key ? '&key=' + key : ''; script.type = "text/javascript"; script.src = protocol + "//maps.google.com/maps/api/js?v=4" + key + "&libraries=places&sensor=false&callback=upfront_maps_loaded"; document.body.appendChild(script); } function upfront_bg_map_init () { $("[data-bg-map]").each(function () { if ( $(this).css('display') != 'none' ) init_map($(this)); }); } function init () { if (!("Upfront" in window || $("[data-bg-map]").length)) { // No Upfront object, no region maps - nothing to do return false; } $(document).on('upfront-google_maps-loaded', upfront_bg_map_init); var lazyUpfrontBgMapInit = throttle(upfront_bg_map_init, 100); if (!window.upfront_maps_loaded) { window.upfront_maps_loaded = window.upfront_maps_loaded || function () { $(document).trigger("upfront-google_maps-loaded"); $(document).data("upfront-google_maps-loading", false); $(window).on('resize', lazyUpfrontBgMapInit); }; load_google_maps(); } } $(init); })(jQuery); /* upfront-default-slider */ (function( $ ) { var throttle = function(a,b,c){var d,e,f,g=null,h=0;c||(c={});var i=function(){h=c.leading===!1?0:new Date().getTime(),g=null,f=a.apply(d,e),g||(d=e=null)};return function(){var j=new Date().getTime();h||c.leading!==!1||(h=j);var k=b-(j-h);return d=this,e=arguments,0>=k||k>b?(clearTimeout(g),g=null,h=j,f=a.apply(d,e),g||(d=e=null)):g||c.trailing===!1||(g=setTimeout(i,k)),f}}; $.fn.upfront_default_slider = function (args) { var isMethod = typeof args === 'string', result ; this.each(function(){ var $slider = $(this), uslider = $slider.data('uslider') ; if(uslider){ if(isMethod) result = uslider.callMethod(args); } else{ if(isMethod) $.error('Can\'t call the ueditor method ' + args + '. The slider is not initialized'); else { // Initialize slider $slider.data('uslider', new JQueryUslider($slider, args)); } } }); if( this.length == 1 & typeof result != 'undefined') return result; return this; }; var JQueryUslider = function($slider, args){ //debugger; var me = this, data = $.extend({ auto: true, interval: 5000, // in ms auto_height: true, // true | false control: 'outside', // outside | inside control_num: true, control_next_prev: true, show_control: 'always', // always | hover effect: 'crossfade', // crossfade | slide-down | slide-up | slide-left | slide-right classname: { slider: 'upfront-default-slider', slider_wrap: 'upfront-default-slider-wrap', item: 'upfront-default-slider-item', nav: 'upfront-default-slider-nav', nav_item: 'upfront-default-slider-nav-item', prev: 'upfront-default-slider-nav-prev', next: 'upfront-default-slider-nav-next' }, adjust_slide_size: true, starting_slide: 0, caption_height: false }, args), $items = data.item ? $slider.find('>'+data.item) : $slider.find('>.'+data.classname.item) ; this.$slider = $slider.data('slider-applied', true) .addClass(data.classname.slider) .append('
') ; this.opts = data; this.index = 0; this.pause = false; this.timer = false; this.update_configs(); this.update_items($items); this.$slider.append($('
')); this.update_nav(); // Next and previous navigation if ( data.control_next_prev ) this.prev_next_navigation(); // Control slides with arrow keys if ( data.keyboard_control ) this.keyboard_controls(); this.slider_switch(data.starting_slide); this.update_auto_slide(); this.bind_events(); this.$slider.trigger('rendered'); }; JQueryUslider.prototype = { callMethod: function(method){ switch(method) { case 'next': this.next(); break; case 'prev': this.prev(); break; } }, update_configs: function(){ var $slider = this.$slider, slider_auto = $slider.attr('data-slider-auto'), data = this.opts ; $slider.removeClass(data.classname.slider + '-control-' + data.control); $slider.removeClass(data.classname.slider + '-control-' + data.show_control); if ( typeof slider_auto != 'string' ) { slider_auto = data.auto; } else { slider_auto = slider_auto == '0' ? false : true; } data.auto = slider_auto; data.interval = parseInt($slider.attr('data-slider-interval') || data.interval, 10); data.effect = $slider.attr('data-slider-effect') || data.effect; data.control = $slider.attr('data-slider-control') || data.control; data.show_control = $slider.attr('data-slider-show-control') || data.show_control; data.caption_height = parseInt($slider.attr('data-caption_height') || data.caption_height, 10) === 1; $slider.addClass(data.classname.slider + '-control-' + data.control); $slider.addClass(data.classname.slider + '-control-' + data.show_control); }, update_items: function($new_items){ var $slider = this.$slider, data = this.opts, $slider_wrap = $slider.find('.' + data.classname.slider_wrap) ; this.items = $new_items; $slider_wrap.html('') .append(this.items) ; //add texts this.items.each(function(idx, item){ var slide = $(item), captionSelector = slide.data('caption-selector'), caption = slide.data('caption'), text = slide.find('.uslide-caption') ; if(captionSelector || caption){ if(!text.length){ text = $('
'); slide.append(text); } if(captionSelector) { text.html($(captionSelector).html()); } else { text.html(caption); } } else if(text.length) { text.remove(); } }); this.items.addClass(data.classname.item); if ( data.auto_height ){ // Auto height adjustment to the highest slide this.calc_height(); $slider.find('img').one('load', $.proxy(this.calc_height, this)); } else if(data.adjust_slide_size) { // Adjust slides to available space this.adjust_slide_size(); } }, calc_height: function(){ var me = this, max_height ; this.$slider.css('height', 9999); this.items.each(function(){ var $img = $(this).find('.uslide-image'), $text = $(this).find('.uslide-caption'), textHeight = me.opts.caption_height ? $text.outerHeight(true) : 0, img_h = $img.outerHeight(true) + textHeight ; max_height = max_height > img_h ? max_height : img_h; }); this.$slider.css({ 'padding-top': Math.ceil(max_height/15)*15, 'height': 'auto' }); }, adjust_slide_size: function(){ var height = this.$slider.outerHeight(), width = this.$slider.outerWidth() ; this.items.each(function(){ var $img = $(this).find('img'), img_h, img_w ; $img.css({ height: "", width: "" }); img_h = $img.height(); img_w = $img.width(); if ( height/width > img_h/img_w ) $img.css({ height: '100%', width: 'auto', marginLeft: (width-Math.round(height/img_h*img_w))/2, marginTop: "" }); else $img.css({ height: 'auto', width: '100%', marginLeft: "", marginTop: (height-Math.round(width/img_w*img_h))/2 }); }); }, update_nav: function(){ var me = this, data = this.opts, $nav = this.$slider.find('.' + data.classname.nav) ; $nav.html(''); if ( data.control_num ){ this.items.each(function(index){ $nav.append(''+index+''); }); this.$slider.on('click', '.'+data.classname.nav_item, function(e){ e.preventDefault(); var index = $(this).data('slider-index'); me.slider_switch(index); me.pause = true; }); } }, keyboard_controls: function() { var me = this, data = this.opts, $slider = this.$slider.closest('.uslider') ; // Handle key press $slider.keydown(function(e) { // Previous slide if (e.which == 37) { me.prev(); } // Next slide if (e.which == 39) { me.next(); } }); }, prev_next_navigation: function(){ var me = this, data = this.opts ; this.$slider.append('
') .on('click', '.'+data.classname.prev, function(e){ e.preventDefault(); me.prev(); }) .on('click', '.'+data.classname.next, function(e){ e.preventDefault(); me.next(); }) ; }, next: function(){ var data = this.opts, fx = data.effect ; this.slider_switch(this.index+1 >= this.items.length ? 0 : this.index+1, false, fx); this.pause = true; }, prev: function(){ var data = this.opts, fx = ( data.effect == 'slide-left' ? 'slide-right' : ( data.effect == 'slide-right' ? 'slide-left' : ( data.effect == 'slide-down' ? 'slide-up' : ( data.effect == 'slide-up' ? 'slide-down' : 'crossfade' ) ) ) ) ; this.slider_switch(this.index > 0 ? this.index-1 : this.items.length-1, false, fx); this.pause = true; }, slider_switch: function(index, is_auto, effect){ var data = this.opts, $nav = this.$slider.find(data.classname.nav), $slider = this.$slider, $n = $nav.find('.'+data.classname.nav_item).eq(index), $item = this.items.eq(index), current = $slider.find('.'+data.classname.item+'-current'), event_end = 'animationend.slider webkitAnimationEnd.slider MSAnimationEnd.slider oAnimationEnd.slider webkitTransitionEnd.slider otransitionend.slider oTransitionEnd.slider msTransitionEnd.slider transitionend.slider' ; if(!effect) effect = data.effect; if ( !$item.hasClass(data.classname.item+'-current') && !(is_auto && this.pause) ){ $slider.trigger('slideout', current) .find('div.slide-previous').removeClass('slide-previous'); current.removeClass(data.classname.item+'-current').addClass('slide-previous'); $item.addClass(data.classname.item+'-current'); $nav.find('.'+data.classname.nav_item+'-selected').removeClass(data.classname.nav_item+'-selected'); $n.addClass(data.classname.nav_item+'-selected'); this.index = index; // Animation effect $item.addClass(data.classname.item+'-effect-'+effect); $item.one(event_end, function () { $(this).removeClass(data.classname.item+'-effect-'+effect); if($item.hasClass(data.classname.item+'-current')) $slider.trigger('slidein', [$item, index]); $item.off(event_end); }); $slider.find('.upfront-default-slider-nav-item').removeClass('uslider-dotnav-current'); $slider.find('.uslider-dotnav-' + index).addClass('uslider-dotnav-current'); } this.pause = false; }, update_auto_slide: function() { var me = this, data = this.opts ; if ( this.timer ) clearInterval(this.timer); if ( data.auto && data.interval > 999 ){ this.timer = setInterval(function(){ me.slider_switch( me.index+1 >= me.items.length ? 0 : me.index+1, true ); }, data.interval); } }, bind_events: function(){ var me = this, $slider = me.$slider, data = me.opts ; $slider.on('refresh', function(){ var $new_items = data.item ? $slider.find('>'+data.item) : $slider.find('>.'+data.classname.item), new_length = $new_items.length, length = me.items.length ; me.update_configs(); me.update_auto_slide(); if ( new_length ){ me.update_items($new_items); me.update_nav(); if ( new_length != length ) { me.slider_switch(data.starting_slide); } } else { if ( data.auto_height ) { me.calc_height(); } } if ( !data.auto_height && data.adjust_slide_size){ me.adjust_slide_size(); me.items.find('img').one('load', $.proxy(me.adjust_slide_size, me)); } }) .on('pause', function(){ clearInterval(me.timer); }) .on('resume', function(){ me.update_auto_slide(); }); } }; $(document).ready(function(){ // Inline post slider setup var inline_slider = { item: '.upfront-inserted_image-wrapper', control_next_prev: false }; $('.upfront-inline_post-slider').upfront_default_slider(inline_slider); // Bg slider var bg_slider = { auto_height: false, control: 'inside' }, init_bg_slider = function () { $('.upfront-bg-slider').each(function(){ if ( $(this).closest('.upfront-output-bg-overlay').css('display') != 'none' ) $(this).upfront_default_slider(bg_slider); }); }; init_bg_slider(); // Refresh size on window.load and window.resize $(window).on('load', function(){ $('.upfront-inline_post-slider, .upfront-bg-slider').trigger('refresh'); }); var lazyInitBgSlider = throttle(function(){ init_bg_slider(); $('.upfront-inline_post-slider, .upfront-bg-slider').trigger('refresh'); }, 100); $(window).on('resize', lazyInitBgSlider); // Integration with Upfront editor $(document).on('upfront-load', function(){ Upfront.Events.on('application:mode:after_switch', function(){ $('.upfront-inline_post-slider').upfront_default_slider(inline_slider); }); Upfront.Events.on('entity:background:update', function(view, model){ var $s = view.$el.find('.upfront-region-bg-slider'); if ( $s.length ){ $s.each(function(){ if ( $(this).data('slider-applied') ) $(this).trigger('refresh'); else $(this).upfront_default_slider(bg_slider); }); } }); }); /* CKEDITOR.on('currentInstance', function(){ editor = CKEDITOR.currentInstance; //$('.upfront-inline_post-slider').upfront_default_slider(inline_slider); if ( !editor ) return; editor.on('insertHtml', function(){ // $('.upfront-inline_post-slider').upfront_default_slider(inline_slider); }); }); */ }); }( jQuery )); /* jquery-plugin */ /* Simple JavaScript Inheritance * By John Resig http://ejohn.org/ * MIT Licensed. */ // Inspired by base2 and Prototype (function(){ var initializing = false; // The base JQClass implementation (does nothing) window.JQClass = function(){}; // Collection of derived classes JQClass.classes = {}; // Create a new JQClass that inherits from this class JQClass.extend = function extender(prop) { var base = this.prototype; // Instantiate a base class (but only create the instance, // don't run the init constructor) initializing = true; var prototype = new this(); initializing = false; // Copy the properties over onto the new prototype for (var name in prop) { // Check if we're overwriting an existing function prototype[name] = typeof prop[name] == 'function' && typeof base[name] == 'function' ? (function(name, fn){ return function() { var __super = this._super; // Add a new ._super() method that is the same method // but on the super-class this._super = function(args) { return base[name].apply(this, args || []); }; var ret = fn.apply(this, arguments); // The method only need to be bound temporarily, so we // remove it when we're done executing this._super = __super; return ret; }; })(name, prop[name]) : prop[name]; } // The dummy class constructor function JQClass() { // All construction is actually done in the init method if (!initializing && this._init) { this._init.apply(this, arguments); } } // Populate our constructed prototype object JQClass.prototype = prototype; // Enforce the constructor to be what we expect JQClass.prototype.constructor = JQClass; // And make this class extendable JQClass.extend = extender; return JQClass; }; })(); (function($) { // Ensure $, encapsulate /** Abstract base class for collection plugins v1.0.1. Written by Keith Wood (kbwood{at}iinet.com.au) December 2013. Licensed under the MIT (http://keith-wood.name/licence.html) license. @module $.JQPlugin @abstract */ JQClass.classes.JQPlugin = JQClass.extend({ /** Name to identify this plugin. @example name: 'tabs' */ name: 'plugin', /** Default options for instances of this plugin (default: {}). @example defaultOptions: { selectedClass: 'selected', triggers: 'click' } */ defaultOptions: {}, /** Options dependent on the locale. Indexed by language and (optional) country code, with '' denoting the default language (English/US). @example regionalOptions: { '': { greeting: 'Hi' } } */ regionalOptions: {}, /** Names of getter methods - those that can't be chained (default: []). @example _getters: ['activeTab'] */ _getters: [], /** Retrieve a marker class for affected elements. @private @return {string} The marker class. */ _getMarker: function() { return 'is-' + this.name; }, /** Initialise the plugin. Create the jQuery bridge - plugin name xyz produces $.xyz and $.fn.xyz. */ _init: function() { // Apply default localisations $.extend(this.defaultOptions, (this.regionalOptions && this.regionalOptions['']) || {}); // Camel-case the name var jqName = camelCase(this.name); // Expose jQuery singleton manager $[jqName] = this; // Expose jQuery collection plugin $.fn[jqName] = function(options) { var otherArgs = Array.prototype.slice.call(arguments, 1); if ($[jqName]._isNotChained(options, otherArgs)) { return $[jqName][options].apply($[jqName], [this[0]].concat(otherArgs)); } return this.each(function() { if (typeof options === 'string') { if (options[0] === '_' || !$[jqName][options]) { throw 'Unknown method: ' + options; } $[jqName][options].apply($[jqName], [this].concat(otherArgs)); } else { $[jqName]._attach(this, options); } }); }; }, /** Set default values for all subsequent instances. @param options {object} The new default options. @example $.plugin.setDefauls({name: value}) */ setDefaults: function(options) { $.extend(this.defaultOptions, options || {}); }, /** Determine whether a method is a getter and doesn't permit chaining. @private @param name {string} The method name. @param otherArgs {any[]} Any other arguments for the method. @return {boolean} True if this method is a getter, false otherwise. */ _isNotChained: function(name, otherArgs) { if (name === 'option' && (otherArgs.length === 0 || (otherArgs.length === 1 && typeof otherArgs[0] === 'string'))) { return true; } return $.inArray(name, this._getters) > -1; }, /** Initialise an element. Called internally only. Adds an instance object as data named for the plugin. @param elem {Element} The element to enhance. @param options {object} Overriding settings. */ _attach: function(elem, options) { elem = $(elem); if (elem.hasClass(this._getMarker())) { return; } elem.addClass(this._getMarker()); options = $.extend({}, this.defaultOptions, this._getMetadata(elem), options || {}); var inst = $.extend({name: this.name, elem: elem, options: options}, this._instSettings(elem, options)); elem.data(this.name, inst); // Save instance against element this._postAttach(elem, inst); this.option(elem, options); }, /** Retrieve additional instance settings. Override this in a sub-class to provide extra settings. @param elem {jQuery} The current jQuery element. @param options {object} The instance options. @return {object} Any extra instance values. @example _instSettings: function(elem, options) { return {nav: elem.find(options.navSelector)}; } */ _instSettings: function(elem, options) { return {}; }, /** Plugin specific post initialisation. Override this in a sub-class to perform extra activities. @param elem {jQuery} The current jQuery element. @param inst {object} The instance settings. @example _postAttach: function(elem, inst) { elem.on('click.' + this.name, function() { ... }); } */ _postAttach: function(elem, inst) { }, /** Retrieve metadata configuration from the element. Metadata is specified as an attribute: data-<plugin name>="<setting name>: '<value>', ...". Dates should be specified as strings in this format: 'new Date(y, m-1, d)'. @private @param elem {jQuery} The source element. @return {object} The inline configuration or {}. */ _getMetadata: function(elem) { try { var data = elem.data(this.name.toLowerCase()) || ''; data = data.replace(/'/g, '"'); data = data.replace(/([a-zA-Z0-9]+):/g, function(match, group, i) { var count = data.substring(0, i).match(/"/g); // Handle embedded ':' return (!count || count.length % 2 === 0 ? '"' + group + '":' : group + ':'); }); data = $.parseJSON('{' + data + '}'); for (var name in data) { // Convert dates var value = data[name]; if (typeof value === 'string' && value.match(/^new Date\((.*)\)$/)) { data[name] = eval(value); } } return data; } catch (e) { return {}; } }, /** Retrieve the instance data for element. @param elem {Element} The source element. @return {object} The instance data or {}. */ _getInst: function(elem) { return $(elem).data(this.name) || {}; }, /** Retrieve or reconfigure the settings for a plugin. @param elem {Element} The source element. @param name {object|string} The collection of new option values or the name of a single option. @param [value] {any} The value for a single named option. @return {any|object} If retrieving a single value or all options. @example $(selector).plugin('option', 'name', value) $(selector).plugin('option', {name: value, ...}) var value = $(selector).plugin('option', 'name') var options = $(selector).plugin('option') */ option: function(elem, name, value) { elem = $(elem); var inst = elem.data(this.name); if (!name || (typeof name === 'string' && value == null)) { var options = (inst || {}).options; return (options && name ? options[name] : options); } if (!elem.hasClass(this._getMarker())) { return; } var options = name || {}; if (typeof name === 'string') { options = {}; options[name] = value; } this._optionsChanged(elem, inst, options); $.extend(inst.options, options); }, /** Plugin specific options processing. Old value available in inst.options[name], new value in options[name]. Override this in a sub-class to perform extra activities. @param elem {jQuery} The current jQuery element. @param inst {object} The instance settings. @param options {object} The new options. @example _optionsChanged: function(elem, inst, options) { if (options.name != inst.options.name) { elem.removeClass(inst.options.name).addClass(options.name); } } */ _optionsChanged: function(elem, inst, options) { }, /** Remove all trace of the plugin. Override _preDestroy for plugin-specific processing. @param elem {Element} The source element. @example $(selector).plugin('destroy') */ destroy: function(elem) { elem = $(elem); if (!elem.hasClass(this._getMarker())) { return; } this._preDestroy(elem, this._getInst(elem)); elem.removeData(this.name).removeClass(this._getMarker()); }, /** Plugin specific pre destruction. Override this in a sub-class to perform extra activities and undo everything that was done in the _postAttach or _optionsChanged functions. @param elem {jQuery} The current jQuery element. @param inst {object} The instance settings. @example _preDestroy: function(elem, inst) { elem.off('.' + this.name); } */ _preDestroy: function(elem, inst) { } }); /** Convert names from hyphenated to camel-case. @private @param value {string} The original hyphenated name. @return {string} The camel-case version. */ function camelCase(name) { return name.replace(/-([a-z])/g, function(match, group) { return group.toUpperCase(); }); } /** Expose the plugin base. @namespace "$.JQPlugin" */ $.JQPlugin = { /** Create a new collection plugin. @memberof "$.JQPlugin" @param [superClass='JQPlugin'] {string} The name of the parent class to inherit from. @param overrides {object} The property/function overrides for the new class. @example $.JQPlugin.createPlugin({ name: 'tabs', defaultOptions: {selectedClass: 'selected'}, _initSettings: function(elem, options) { return {...}; }, _postAttach: function(elem, inst) { ... } }); */ createPlugin: function(superClass, overrides) { if (typeof superClass === 'object') { overrides = superClass; superClass = 'JQPlugin'; } superClass = camelCase(superClass); var className = camelCase(overrides.name); JQClass.classes[className] = JQClass.classes[superClass].extend(overrides); new JQClass.classes[className](); } }; })(jQuery); /* jquery-realperson */ /* http://keith-wood.name/realPerson.html Real Person Form Submission for jQuery v2.0.1. Written by Keith Wood (kwood{at}iinet.com.au) June 2009. Available under the MIT (http://keith-wood.name/licence.html) license. Please attribute the author if you use it. */ (function($) { // Hide scope, no $ conflict var pluginName = 'realperson'; var ALPHABETIC = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; var ALPHANUMERIC = ALPHABETIC + '0123456789'; var DOTS = [ [' * ', ' * * ', ' * * ', ' * * ', ' ***** ', '* *', '* *'], ['****** ', '* *', '* *', '****** ', '* *', '* *', '****** '], [' ***** ', '* *', '* ', '* ', '* ', '* *', ' ***** '], ['****** ', '* *', '* *', '* *', '* *', '* *', '****** '], ['*******', '* ', '* ', '**** ', '* ', '* ', '*******'], ['*******', '* ', '* ', '**** ', '* ', '* ', '* '], [' ***** ', '* *', '* ', '* ', '* ***', '* *', ' ***** '], ['* *', '* *', '* *', '*******', '* *', '* *', '* *'], ['*******', ' * ', ' * ', ' * ', ' * ', ' * ', '*******'], [' *', ' *', ' *', ' *', ' *', '* *', ' ***** '], ['* *', '* ** ', '* ** ', '** ', '* ** ', '* ** ', '* *'], ['* ', '* ', '* ', '* ', '* ', '* ', '*******'], ['* *', '** **', '* * * *', '* * *', '* *', '* *', '* *'], ['* *', '** *', '* * *', '* * *', '* * *', '* **', '* *'], [' ***** ', '* *', '* *', '* *', '* *', '* *', ' ***** '], ['****** ', '* *', '* *', '****** ', '* ', '* ', '* '], [' ***** ', '* *', '* *', '* *', '* * *', '* * ', ' **** *'], ['****** ', '* *', '* *', '****** ', '* * ', '* * ', '* *'], [' ***** ', '* *', '* ', ' ***** ', ' *', '* *', ' ***** '], ['*******', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '], ['* *', '* *', '* *', '* *', '* *', '* *', ' ***** '], ['* *', '* *', ' * * ', ' * * ', ' * * ', ' * * ', ' * '], ['* *', '* *', '* *', '* * *', '* * * *', '** **', '* *'], ['* *', ' * * ', ' * * ', ' * ', ' * * ', ' * * ', '* *'], ['* *', ' * * ', ' * * ', ' * ', ' * ', ' * ', ' * '], ['*******', ' * ', ' * ', ' * ', ' * ', ' * ', '*******'], [' *** ', ' * * ', '* * *', '* * *', '* * *', ' * * ', ' *** '], [' * ', ' ** ', ' * * ', ' * ', ' * ', ' * ', '*******'], [' ***** ', '* *', ' *', ' * ', ' ** ', ' ** ', '*******'], [' ***** ', '* *', ' *', ' ** ', ' *', '* *', ' ***** '], [' * ', ' ** ', ' * * ', ' * * ', '*******', ' * ', ' * '], ['*******', '* ', '****** ', ' *', ' *', '* *', ' ***** '], [' **** ', ' * ', '* ', '****** ', '* *', '* *', ' ***** '], ['*******', ' * ', ' * ', ' * ', ' * ', ' * ', '* '], [' ***** ', '* *', '* *', ' ***** ', '* *', '* *', ' ***** '], [' ***** ', '* *', '* *', ' ******', ' *', ' * ', ' **** ']]; /** Create the real person plugin.

Displays a challenge to confirm that the viewer is a real person.

Expects HTML like:

<input...>

Provide inline configuration like:

<input data-realperson="name: 'value'">...>
@module RealPerson @augments JQPlugin @example $(selector).realperson() $(selector).realperson({length: 200, toggle: false}) */ $.JQPlugin.createPlugin({ /** The name of the plugin. */ name: pluginName, /** The set of alphabetic characters. */ alphabetic: ALPHABETIC, /** The set of alphabetic and numeric characters. */ alphanumeric: ALPHANUMERIC, /** The set dots that make up each character. */ defaultDots: DOTS, /** More/less change callback. Triggered when the more/less button is clicked. @callback changeCallback @param expanding {boolean} True if expanding the text, false if collapsing. */ /** Default settings for the plugin. @property [length=6] {number} Number of characters to use. @property [regenerate='Click to change'] {string} Instruction text to regenerate. @property [hashName='{n}Hash'] {string} Name of the hash value field to compare with, use {n} to substitute with the original field name. @property [dot='*'] {string} The character to use for the dot patterns. @property [dots=defaultDots] {string[][]} The dot patterns per letter in chars. @property [chars=alphabetic] {string} The characters allowed. */ defaultOptions: { length: 6, regenerate: 'Click to change', hashName: '{n}Hash', dot: '*', dots: DOTS, chars: ALPHABETIC }, _getters: ['getHash'], _challengeClass: pluginName + '-challenge', _disabledClass: pluginName + '-disabled', _hashClass: pluginName + '-hash', _regenerateClass: pluginName + '-regen', _textClass: pluginName + '-text', _optionsChanged: function(elem, inst, options) { $.extend(inst.options, options); var text = ''; for (var i = 0; i < inst.options.length; i++) { text += inst.options.chars.charAt(Math.floor(Math.random() * inst.options.chars.length)); } inst.hash = hash(text + salt); var self = this; elem.closest('form').off('.' + inst.name). on('submit.' + inst.name, function() { var name = inst.options.hashName.replace(/\{n\}/, elem.attr('name')); var form = $(this); form.find('input[name="' + name + '"]').remove(); form.append(''); setTimeout(function() { form.find('input[name="' + name + '"]').remove(); }, 0); }); elem.prevAll('.' + this._challengeClass + ',.' + this._hashClass).remove().end(). before(this._generateHTML(inst, text)). prevAll('div.' + this._challengeClass).click(function() { if (!$(this).hasClass(self._disabledClass)) { elem.realperson('option', {}); } }); }, /* Enable the plugin functionality for a control. @param elem {element} The control to affect. */ enable: function(elem) { elem = $(elem); if (!elem.hasClass(this._getMarker())) { return; } elem.removeClass(this._disabledClass).prop('disabled', false). prevAll('.' + this._challengeClass).removeClass(this._disabledClass); }, /* Disable the plugin functionality for a control. @param elem {element} The control to affect. */ disable: function(elem) { elem = $(elem); if (!elem.hasClass(this._getMarker())) { return; } elem.addClass(this._disabledClass).prop('disabled', true). prevAll('.' + this._challengeClass).addClass(this._disabledClass); }, /* Retrieve the hash value. @param elem {Element} The control with the hash. @return {number} The hash value. */ getHash: function(elem) { var inst = this._getInst(elem); return inst ? inst.hash : 0; }, /* Generate the additional content for this control. @param inst {object} The current instance settings. @param text {string} The text to display. @return {string} The additional content. */ _generateHTML: function(inst, text) { var html = '
' + '
'; for (var i = 0; i < inst.options.dots[0].length; i++) { for (var j = 0; j < text.length; j++) { html += inst.options.dots[inst.options.chars.indexOf(text.charAt(j))][i]. replace(/ /g, ' ').replace(/\*/g, inst.options.dot) + '  '; } html += '
'; } html += '
' + inst.options.regenerate + '
'; return html; }, _preDestroy: function(elem, inst) { elem.closest('form').off('.' + inst.name); elem.prevAll('.' + this._challengeClass + ',.' + this._hashClass).remove(); } }); /* Load salt value and clear. */ var salt = $.salt || '#salt'; delete $.salt; $(function() { var saltElem = $(salt); if (saltElem.length) { salt = saltElem.text(); saltElem.remove(); } if (salt === '#salt') { salt = ''; } }); /* Compute a hash value for the given text. @param value {string} The text to hash. @return {number} The corresponding hash value. */ function hash(value) { var hash = 5381; for (var i = 0; i < value.length; i++) { hash = ((hash << 5) + hash) + value.charCodeAt(i); } return hash; } })(jQuery); /* ucontact-front */ ;(function($){ var check_email = function(email){ return /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/.test(email); }, show_message = function($form, message, info){ var infoclass = info ? 'info' : 'error'; $form.find('.ucontact-message-container').html( $('
').addClass('ucontact-msg msg ' + infoclass).html(message) ); }, hide_message = function($form){ $form.find('.ucontact-message-container').html(''); }, add_error = function(error, errors, $elem){ $elem.addClass('ucontact-field-error'); return errors.push(error); } ; if(!String.prototype.trim){ String.prototype.trim = function(){ return this.replace(/^\s+|\s+$/g, ''); }; } jQuery(function($){ // Boot realperson with proper options $('[name="realPerson"]').each(function () { var $me = $(this), refresh = $me.attr('data-string'), opts = {} ; if (refresh) opts.regenerate = refresh; $me.realperson(opts); }); var $form = $('div.upfront-contact-form'); $form.on('blur', '.ucontact-validate-field', function(e){ var $elem = $(this), $container = $elem.parents('.upfront-contact-form'), field = $elem.attr('name'), errors = [] ; switch(field){ case 'sendername': error = $elem.val().trim() ? false : ($elem.attr('data-string') || 'You must write your name.'); break; case 'senderemail': error = check_email($elem.val().trim()) ? false : ($elem.attr('data-string') || 'The email address is not valid.'); break; case 'subject': error = $elem.val().trim() ? false : ($elem.attr('data-string') || 'You must write a subject for the message.'); break; case 'sendermessage': error = $elem.val().trim() ? false : ($elem.attr('data-string') || 'You forgot to write a message.'); } if (error){ $elem.addClass('ucontact-field-error'); show_message($container, error); } else{ $elem.removeClass('ucontact-field-error'); hide_message($container); } }); $form.find('form').on('submit', function(e){ e.preventDefault(); e.stopPropagation(); var $this = $(this), name = $this.find('input[name=sendername]'), email = $this.find('input[name=senderemail]'), subject = $this.find('input[name=subject]'), message = $this.find('textarea[name=sendermessage]'), realPerson = $this.find('input[name="realPerson"]'), errors = [] ; if (!name.val().trim()) add_error( (name.attr("data-string") || 'You must write your name.'), errors, name ); if (!check_email(email.val().trim())) add_error( (email.attr("data-string") || 'The email address is not valid.'), errors, email ); if (subject.length > 0 && !subject.val().trim()) add_error( (subject.attr("data-string") || 'You must write a subject for the message.'), errors, subject ); if(!message.val().trim()) add_error( (message.attr("data-string") || 'You forgot to write a message.'), errors, message ); if (typeof realPerson !== "undefined" && typeof realPerson.val() !== "undefined" && !realPerson.val().trim()) add_error( 'You must write CAPTCHA number.', errors, realPerson ); if (errors.length > 0){ //Stop sending show_message($this.parent(), errors.join('
')); } else{ //Everything ok, try to send it via ajax $.ajax({ url: ajax_url, type: 'POST', data: { action: 'upfront_contact-form', sendername: name.val().trim(), senderemail: email.val().trim(), subject: subject.length ? subject.val().trim() : '', sendermessage: message.val().trim(), ucontact: $this.find('input[name=ucontact]').val(), contactformid: $this.find('input[name=contactformid]').val(), entity_ids: $this.find('input[name=entity_ids]').val(), realPerson: realPerson.length ? realPerson.val() : '', realPersonHash: realPerson.length ? realPerson.realperson('getHash') : '' }, success: function(data){ var msg = (data.data && "message" in data.data ? data.data.message : ''), err = (data.data && "error" in data.data ? !!data.data.error : true) ; if (!err) { msg = '

' + msg + '

'; } show_message($this, msg, !err); if (!err) { $form.find(".ucontact-message-container").addClass("ucontact-success-response"); //$form.find("input,button,textarea").attr("disabled", true); $form.find(".ucontact-message-container").bind('click', function() { $(this).removeClass("ucontact-success-response").html(""); $(this).unbind('click'); }); name.val(''); email.val(''); if (subject.length) {subject.val('');} message.val(''); if (realPerson.length) { realPerson.val(''); realPerson.realperson('destroy'); realPerson.realperson(); } } }, error: function(error){ var response = JSON.parse(error.responseText); show_message($this, response.error); } }); } return false; }); }); })(jQuery); /* magnific */ // Magnific Popup v0.9.3 by Dmitry Semenov // http://bit.ly/magnific-popup#build=inline+image+gallery+retina (function(a){var b="Close",c="BeforeClose",d="AfterClose",e="BeforeAppend",f="MarkupParse",g="Open",h="Change",i="mfp",j="."+i,k="mfp-ready",l="mfp-removing",m="mfp-prevent-close",n,o=function(){},p=!!window.jQuery,q,r=a(window),s,t,u,v,w,x=function(a,b){n.ev.on(i+a+j,b)},y=function(b,c,d,e){var f=document.createElement("div");return f.className="mfp-"+b,d&&(f.innerHTML=d),e?c&&c.appendChild(f):(f=a(f),c&&f.appendTo(c)),f},z=function(b,c){n.ev.triggerHandler(i+b,c),n.st.callbacks&&(b=b.charAt(0).toLowerCase()+b.slice(1),n.st.callbacks[b]&&n.st.callbacks[b].apply(n,a.isArray(c)?c:[c]))},A=function(){(n.st.focus?n.content.find(n.st.focus).eq(0):n.wrap).trigger("focus")},B=function(b){if(b!==w||!n.currTemplate.closeBtn)n.currTemplate.closeBtn=a(n.st.closeMarkup.replace("%title%",n.st.tClose)),w=b;return n.currTemplate.closeBtn},C=function(){a.magnificPopup.instance||(n=new o,n.init(),a.magnificPopup.instance=n)},D=function(b){if(a(b).hasClass(m))return;var c=n.st.closeOnContentClick,d=n.st.closeOnBgClick;if(c&&d)return!0;if(!n.content||a(b).hasClass("mfp-close")||n.preloader&&b===n.preloader[0])return!0;if(b!==n.content[0]&&!a.contains(n.content[0],b)){if(d&&a.contains(document,b))return!0}else if(c)return!0;return!1},E=function(){var a=document.createElement("p").style,b=["ms","O","Moz","Webkit"];if(a.transition!==undefined)return!0;while(b.length)if(b.pop()+"Transition"in a)return!0;return!1};o.prototype={constructor:o,init:function(){var b=navigator.appVersion;n.isIE7=b.indexOf("MSIE 7.")!==-1,n.isIE8=b.indexOf("MSIE 8.")!==-1,n.isLowIE=n.isIE7||n.isIE8,n.isAndroid=/android/gi.test(b),n.isIOS=/iphone|ipad|ipod/gi.test(b),n.supportsTransition=E(),n.probablyMobile=n.isAndroid||n.isIOS||/(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent),s=a(document.body),t=a(document),n.popupsCache={}},open:function(b){var c;if(b.isObj===!1){n.items=b.items.toArray(),n.index=0;var d=b.items,e;for(c=0;c(a||r.height())},_parseMarkup:function(b,c,d){var e;d.data&&(c=a.extend(d.data,c)),z(f,[b,c,d]),a.each(c,function(a,c){if(c===undefined||c===!1)return!0;e=a.split("_");if(e.length>1){var d=b.find(j+"-"+e[0]);if(d.length>0){var f=e[1];f==="replaceWith"?d[0]!==c[0]&&d.replaceWith(c):f==="img"?d.is("img")?d.attr("src",c):d.replaceWith(''):d.attr(e[1],c)}}else b.find(j+"-"+a).html(c)})},_getScrollbarSize:function(){if(n.scrollbarSize===undefined){var a=document.createElement("div");a.id="mfp-sbm",a.style.cssText="width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;",document.body.appendChild(a),n.scrollbarSize=a.offsetWidth-a.clientWidth,document.body.removeChild(a)}return n.scrollbarSize}},a.magnificPopup={instance:null,proto:o.prototype,modules:[],open:function(a,b){return C(),a||(a={}),a.isObj=!0,a.index=b||0,this.instance.open(a)},close:function(){return a.magnificPopup.instance.close()},registerModule:function(b,c){c.options&&(a.magnificPopup.defaults[b]=c.options),a.extend(this.proto,c.proto),this.modules.push(b)},defaults:{disableOn:0,key:null,midClick:!1,mainClass:"",preloader:!0,focus:"",closeOnContentClick:!1,closeOnBgClick:!0,closeBtnInside:!0,showCloseBtn:!0,enableEscapeKey:!0,modal:!1,alignTop:!1,removalDelay:0,fixedContentPos:"auto",fixedBgPos:"auto",overflowY:"auto",closeMarkup:'',tClose:"Close (Esc)",tLoading:"Loading..."}},a.fn.magnificPopup=function(b){C();var c=a(this);if(typeof b=="string")if(b==="open"){var d,e=p?c.data("magnificPopup"):c[0].magnificPopup,f=parseInt(arguments[1],10)||0;e.items?d=e.items[f]:(d=c,e.delegate&&(d=d.find(e.delegate)),d=d.eq(f)),n._openClick({mfpEl:d},c,e)}else n.isOpen&&n[b].apply(n,Array.prototype.slice.call(arguments,1));else p?c.data("magnificPopup",b):c[0].magnificPopup=b,n.addGroup(c,b);return c};var F="inline",G,H,I,J=function(){I&&(H.after(I.addClass(G)).detach(),I=null)};a.magnificPopup.registerModule(F,{options:{hiddenClass:"hide",markup:"",tNotFound:"Content not found"},proto:{initInline:function(){n.types.push(F),x(b+"."+F,function(){J()})},getInline:function(b,c){J();if(b.src){var d=n.st.inline,e=a(b.src);if(e.length){var f=e[0].parentNode;f&&f.tagName&&(H||(G=d.hiddenClass,H=y(G),G="mfp-"+G),I=e.after(H).detach().removeClass(G)),n.updateStatus("ready")}else n.updateStatus("error",d.tNotFound),e=a("
");return b.inlineElement=e,e}return n.updateStatus("ready"),n._parseMarkup(c,{},b),c}}});var K,L=function(b){if(b.data&&b.data.title!==undefined)return b.data.title;var c=n.st.image.titleSrc;if(c){if(a.isFunction(c))return c.call(n,b);if(b.el)return b.el.attr(c)||""}return""};a.magnificPopup.registerModule("image",{options:{markup:'
',cursor:"mfp-zoom-out-cur",titleSrc:"title",verticalFit:!0,tError:'The image could not be loaded.'},proto:{initImage:function(){var a=n.st.image,c=".image";n.types.push("image"),x(g+c,function(){n.currItem.type==="image"&&a.cursor&&s.addClass(a.cursor)}),x(b+c,function(){a.cursor&&s.removeClass(a.cursor),r.off("resize"+j)}),x("Resize"+c,n.resizeImage),n.isLowIE&&x("AfterChange",n.resizeImage)},resizeImage:function(){var a=n.currItem;if(!a.img)return;if(n.st.image.verticalFit){var b=0;n.isLowIE&&(b=parseInt(a.img.css("padding-top"),10)+parseInt(a.img.css("padding-bottom"),10)),a.img.css("max-height",n.wH-b)}},_onImageHasSize:function(a){a.img&&(a.hasSize=!0,K&&clearInterval(K),a.isCheckingImgSize=!1,z("ImageHasSize",a),a.imgHidden&&(n.content&&n.content.removeClass("mfp-loading"),a.imgHidden=!1))},findImageSize:function(a){var b=0,c=a.img[0],d=function(e){K&&clearInterval(K),K=setInterval(function(){if(c.naturalWidth>0){n._onImageHasSize(a);return}b>200&&clearInterval(K),b++,b===3?d(10):b===40?d(50):b===100&&d(500)},e)};d(1)},getImage:function(b,c){var d=0,e=function(){b&&(b.img[0].complete?(b.img.off(".mfploader"),b===n.currItem&&(n._onImageHasSize(b),n.updateStatus("ready")),b.hasSize=!0,b.loaded=!0,z("ImageLoadComplete")):(d++,d<200?setTimeout(e,100):f()))},f=function(){b&&(b.img.off(".mfploader"),b===n.currItem&&(n._onImageHasSize(b),n.updateStatus("error",g.tError.replace("%url%",b.src))),b.hasSize=!0,b.loaded=!0,b.loadError=!0)},g=n.st.image,h=c.find(".mfp-img");if(h.length){var i=new Image;i.className="mfp-img",b.img=a(i).on("load.mfploader",e).on("error.mfploader",f),i.src=b.src,h.is("img")&&(b.img=b.img.clone()),b.img[0].naturalWidth>0&&(b.hasSize=!0)}return n._parseMarkup(c,{title:L(b),img_replaceWith:b.img},b),n.resizeImage(),b.hasSize?(K&&clearInterval(K),b.loadError?(c.addClass("mfp-loading"),n.updateStatus("error",g.tError.replace("%url%",b.src))):(c.removeClass("mfp-loading"),n.updateStatus("ready")),c):(n.updateStatus("loading"),b.loading=!0,b.hasSize||(b.imgHidden=!0,c.addClass("mfp-loading"),n.findImageSize(b)),c)}}});var M,N=function(){return M===undefined&&(M=document.createElement("p").style.MozTransform!==undefined),M};a.magnificPopup.registerModule("zoom",{options:{enabled:!1,easing:"ease-in-out",duration:300,opener:function(a){return a.is("img")?a:a.find("img")}},proto:{initZoom:function(){var a=n.st.zoom,d=".zoom";if(!a.enabled||!n.supportsTransition)return;var e=a.duration,f=function(b){var c=b.clone().removeAttr("style").removeAttr("class").addClass("mfp-animated-image"),d="all "+a.duration/1e3+"s "+a.easing,e={position:"fixed",zIndex:9999,left:0,top:0,"-webkit-backface-visibility":"hidden"},f="transition";return e["-webkit-"+f]=e["-moz-"+f]=e["-o-"+f]=e[f]=d,c.css(e),c},g=function(){n.content.css("visibility","visible")},h,i;x("BuildControls"+d,function(){if(n._allowZoom()){clearTimeout(h),n.content.css("visibility","hidden"),image=n._getItemToZoom();if(!image){g();return}i=f(image),i.css(n._getOffset()),n.wrap.append(i),h=setTimeout(function(){i.css(n._getOffset(!0)),h=setTimeout(function(){g(),setTimeout(function(){i.remove(),image=i=null,z("ZoomAnimationEnded")},16)},e)},16)}}),x(c+d,function(){if(n._allowZoom()){clearTimeout(h),n.st.removalDelay=e;if(!image){image=n._getItemToZoom();if(!image)return;i=f(image)}i.css(n._getOffset(!0)),n.wrap.append(i),n.content.css("visibility","hidden"),setTimeout(function(){i.css(n._getOffset())},16)}}),x(b+d,function(){n._allowZoom()&&(g(),i&&i.remove())})},_allowZoom:function(){return n.currItem.type==="image"},_getItemToZoom:function(){return n.currItem.hasSize?n.currItem.img:!1},_getOffset:function(b){var c;b?c=n.currItem.img:c=n.st.zoom.opener(n.currItem.el||n.currItem);var d=c.offset(),e=parseInt(c.css("padding-top"),10),f=parseInt(c.css("padding-bottom"),10);d.top-=a(window).scrollTop()-e;var g={width:c.width(),height:(p?c.innerHeight():c[0].offsetHeight)-f-e};return N()?g["-moz-transform"]=g.transform="translate("+d.left+"px,"+d.top+"px)":(g.left=d.left,g.top=d.top),g}}});var O=function(a){var b=n.items.length;return a>b-1?a-b:a<0?b+a:a},P=function(a,b,c){return a.replace("%curr%",b+1).replace("%total%",c)};a.magnificPopup.registerModule("gallery",{options:{enabled:!1,arrowMarkup:'',preload:[0,2],navigateByImgClick:!0,arrows:!0,tPrev:"Previous (Left arrow key)",tNext:"Next (Right arrow key)",tCounter:"%curr% of %total%"},proto:{initGallery:function(){var c=n.st.gallery,d=".mfp-gallery",e=Boolean(a.fn.mfpFastClick);n.direction=!0;if(!c||!c.enabled)return!1;v+=" mfp-gallery",x(g+d,function(){c.navigateByImgClick&&n.wrap.on("click"+d,".mfp-img",function(){if(n.items.length>1)return n.next(),!1}),t.on("keydown"+d,function(a){a.keyCode===37?n.prev():a.keyCode===39&&n.next()})}),x("UpdateStatus"+d,function(a,b){b.text&&(b.text=P(b.text,n.currItem.index,n.items.length))}),x(f+d,function(a,b,d,e){var f=n.items.length;d.counter=f>1?P(c.tCounter,e.index,f):""}),x("BuildControls"+d,function(){if(n.items.length>1&&c.arrows&&!n.arrowLeft){var b=c.arrowMarkup,d=n.arrowLeft=a(b.replace("%title%",c.tPrev).replace("%dir%","left")).addClass(m),f=n.arrowRight=a(b.replace("%title%",c.tNext).replace("%dir%","right")).addClass(m),g=e?"mfpFastClick":"click";d[g](function(){n.prev()}),f[g](function(){n.next()}),n.isIE7&&(y("b",d[0],!1,!0),y("a",d[0],!1,!0),y("b",f[0],!1,!0),y("a",f[0],!1,!0)),n.container.append(d.add(f))}}),x(h+d,function(){n._preloadTimeout&&clearTimeout(n._preloadTimeout),n._preloadTimeout=setTimeout(function(){n.preloadNearbyImages(),n._preloadTimeout=null},16)}),x(b+d,function(){t.off(d),n.wrap.off("click"+d),n.arrowLeft&&e&&n.arrowLeft.add(n.arrowRight).destroyMfpFastClick(),n.arrowRight=n.arrowLeft=null})},next:function(){n.direction=!0,n.index=O(n.index+1),n.updateItemHTML()},prev:function(){n.direction=!1,n.index=O(n.index-1),n.updateItemHTML()},goTo:function(a){n.direction=a>=n.index,n.index=a,n.updateItemHTML()},preloadNearbyImages:function(){var a=n.st.gallery.preload,b=Math.min(a[0],n.items.length),c=Math.min(a[1],n.items.length),d;for(d=1;d<=(n.direction?c:b);d++)n._preloadItem(n.index+d);for(d=1;d<=(n.direction?b:c);d++)n._preloadItem(n.index-d)},_preloadItem:function(b){b=O(b);if(n.items[b].preloaded)return;var c=n.items[b];c.parsed||(c=n.parseEl(b)),z("LazyLoad",c),c.type==="image"&&(c.img=a('').on("load.mfploader",function(){c.hasSize=!0}).on("error.mfploader",function(){c.hasSize=!0,c.loadError=!0,z("LazyLoadError",c)}).attr("src",c.src)),c.preloaded=!0}}});var Q="retina";a.magnificPopup.registerModule(Q,{options:{replaceSrc:function(a){return a.src.replace(/\.\w+$/,function(a){return"@2x"+a})},ratio:1},proto:{initRetina:function(){if(window.devicePixelRatio>1){var a=n.st.retina,b=a.ratio;b=isNaN(b)?b():b,b>1&&(x("ImageHasSize."+Q,function(a,c){c.img.css({"max-width":c.img[0].naturalWidth/b,width:"100%"})}),x("ElementParse."+Q,function(c,d){d.src=a.replaceSrc(d,b)}))}}}})})(window.jQuery||window.Zepto) /* jquery-shuffle */ // IMPORTANT! // If you're already using Modernizr, delete it from this file. If you don't know what Modernizr is, leave it :) /* Modernizr 2.8.3 (Custom Build) | MIT & BSD * Build: http://modernizr.com/download/#-csstransforms-csstransforms3d-csstransitions-mq-cssclasses-prefixed-teststyles */ if(typeof window.Modernizr == 'undefined') window.Modernizr=function(a,b,c){function A(a){j.cssText=a}function B(a,b){return A(m.join(a+";")+(b||""))}function C(a,b){return typeof a===b}function D(a,b){return!!~(""+a).indexOf(b)}function E(a,b){for(var d in a){var e=a[d];if(!D(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function F(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:C(f,"function")?f.bind(d||b):f}return!1}function G(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+o.join(d+" ")+d).split(" ");return C(b,"string")||C(b,"undefined")?E(e,b):(e=(a+" "+p.join(d+" ")+d).split(" "),F(e,b,c))}var d="2.8.3",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m=" -webkit- -moz- -o- -ms- ".split(" "),n="Webkit Moz O ms",o=n.split(" "),p=n.toLowerCase().split(" "),q={},r={},s={},t=[],u=t.slice,v,w=function(a,c,d,e){var f,i,j,k,l=b.createElement("div"),m=b.body,n=m||b.createElement("body");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:h+(d+1),l.appendChild(j);return f=["­",'"].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},x=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b)&&c(b).matches||!1;var d;return w("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},y={}.hasOwnProperty,z;!C(y,"undefined")&&!C(y.call,"undefined")?z=function(a,b){return y.call(a,b)}:z=function(a,b){return b in a&&C(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=u.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(u.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(u.call(arguments)))};return e}),q.csstransforms=function(){return!!G("transform")},q.csstransforms3d=function(){var a=!!G("perspective");return a&&"webkitPerspective"in g.style&&w("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},q.csstransitions=function(){return G("transition")};for(var H in q)z(q,H)&&(v=H.toLowerCase(),e[v]=q[H](),t.push((e[v]?"":"no-")+v));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)z(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},A(""),i=k=null,e._version=d,e._prefixes=m,e._domPrefixes=p,e._cssomPrefixes=o,e.mq=x,e.testProp=function(a){return E([a])},e.testAllProps=G,e.testStyles=w,e.prefixed=function(a,b,c){return b?G(a,b,c):G(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+t.join(" "):""),e}(this,this.document); // Shuffle Doesn't require this shuffle/debounce plugin, but it works better with it. /* * jQuery throttle / debounce - v1.1 - 3/7/2010 * http://benalman.com/projects/jquery-throttle-debounce-plugin/ * * Copyright (c) 2010 "Cowboy" Ben Alman * Dual licensed under the MIT and GPL licenses. * http://benalman.com/about/license/ */ (function(b,c){var $=b.jQuery||b.Cowboy||(b.Cowboy={}),a;$.throttle=a=function(e,f,j,i){var h,d=0;if(typeof f!=="boolean"){i=j;j=f;f=c}function g(){var o=this,m=+new Date()-d,n=arguments;function l(){d=+new Date();j.apply(o,n)}function k(){h=c}if(i&&!h){l()}h&&clearTimeout(h);if(i===c&&m>e){l()}else{if(f!==true){h=setTimeout(i?k:l,i===c?e-m:e)}}}if($.guid){g.guid=j.guid=j.guid||$.guid++}return g};$.debounce=function(d,e,f){return f===c?a(d,e,false):a(d,f,e!==false)}})(this); /** * jQuery Shuffle Plugin * Uses CSS Transforms to filter down a grid of items. * Dependencies: jQuery 1.9+, Modernizr 2.6.2. Optionally throttle/debounce by Ben Alman * Inspired by Isotope http://isotope.metafizzy.co/ * Modified 2013-08-19 * @license MIT license * @author Glen Cheney * @version 2.0.1 */ (function($, Modernizr, undefined) { 'use strict'; // You can return `undefined` from the `by` function to revert to DOM order // This plugin does NOT return a jQuery object. It returns a plain array because // jQuery sorts everything in DOM order. $.fn.sorted = function(options) { var opts = $.extend({}, $.fn.sorted.defaults, options), arr = this.get(), revert = false; if ( !arr.length ) { return []; } if ( opts.randomize ) { return $.fn.sorted.randomize( arr ); } // Sort the elements by the opts.by function. // If we don't have opts.by, default to DOM order if (opts.by !== $.noop && opts.by !== null && opts.by !== undefined) { arr.sort(function(a, b) { // Exit early if we already know we want to revert if ( revert ) { return 0; } var valA = opts.by($(a)), valB = opts.by($(b)); // If both values are undefined, use the DOM order if ( valA === undefined && valB === undefined ) { revert = true; return 0; } if ( valA === 'sortFirst' || valB === 'sortLast' ) { return -1; } if ( valA === 'sortLast' || valB === 'sortFirst' ) { return 1; } return (valA < valB) ? -1 : (valA > valB) ? 1 : 0; }); } // Revert to the original array if necessary if ( revert ) { return this.get(); } if ( opts.reverse ) { arr.reverse(); } return arr; }; $.fn.sorted.defaults = { reverse: false, // Use array.reverse() to reverse the results by: null, // Sorting function randomize: false // If true, this will skip the sorting and return a randomized order in the array }; // http://stackoverflow.com/a/962890/373422 $.fn.sorted.randomize = function( array ) { var top = array.length, tmp, current; if ( !top ) { return array; } while ( --top ) { current = Math.floor( Math.random() * (top + 1) ); tmp = array[ current ]; array[ current ] = array[ top ]; array[ top ] = tmp; } return array; }; // Used for unique instance variables var id = 0; var Shuffle = function( $container, options ) { var self = this; $.extend( self, Shuffle.options, options, Shuffle.settings ); self.$container = $container; self.$window = $(window); self.unique = 'shuffle_' + id++; self._fire('loading'); self._init(); self._fire('done'); }; Shuffle.prototype = { _init : function() { var self = this, containerCSS, resizeFunction = $.proxy( self._onResize, self ), debouncedResize = self.throttle ? self.throttle( self.throttleTime, resizeFunction ) : resizeFunction, sort = self.initialSort ? self.initialSort : null; // Save variables needed later then add some classes self._setVars(); // Zero out all columns self._resetCols(); // Add classes and invalidate styles self._addClasses(); // Set initial css for each item self._initItems(); // Bind resize events (http://stackoverflow.com/questions/1852751/window-resize-event-firing-in-internet-explorer) self.$window.on('resize.shuffle.' + self.unique, debouncedResize); // Get container css all in one request. Causes reflow containerCSS = self.$container.css(['paddingLeft', 'paddingRight', 'position', 'width']); // Position cannot be static. // This will cause an extra style layout if it has to be set and the sizer element is used. if ( containerCSS.position === 'static' ) { self.$container.css('position', 'relative'); } // Get offset from container self.offset = { left: parseInt( containerCSS.paddingLeft, 10 ) || 0, top: parseInt( containerCSS.paddingTop, 10 ) || 0 }; // We already got the container's width above, no need to cause another reflow getting it again... // Calculate the number of columns there will be self._setColumns( parseInt( containerCSS.width, 10 ) ); // Kick off! self.shuffle( self.group, sort ); // The shuffle items haven't had transitions set on them yet // so the user doesn't see the first layout. Set them now that the first layout is done. if ( self.supported ) { setTimeout(function() { self._setTransitions(); self.$container[0].style[ self.transitionName ] = 'height ' + self.speed + 'ms ' + self.easing; }, 0); } }, // Will invalidate styles _addClasses : function() { var self = this; self.$container.addClass('shuffle'); self.$items.addClass('shuffle-item filtered'); return self; }, _setVars : function() { var self = this; self.$items = self._getItems(); self.transitionName = self.prefixed('transition'), self.transitionDelayName = self.prefixed('transitionDelay'); self.transitionDuration = self.prefixed('transitionDuration'); self.transform = self.getPrefixed('transform'); // Get transitionend event name self.transitionend = { 'WebkitTransition' : 'webkitTransitionEnd', 'MozTransition' : 'transitionend', 'OTransition' : 'oTransitionEnd', 'msTransition' : 'MSTransitionEnd', 'transition' : 'transitionend' }[ self.transitionName ]; // If the columnWidth property is a function, then the grid is fluid self.isFluid = self.columnWidth && typeof self.columnWidth === 'function'; // Column width is the default setting and sizer is not (meaning passed in) // Assume they meant column width to be the sizer if ( self.columnWidth === 0 && self.sizer !== null ) { self.columnWidth = self.sizer; } // If column width is a string, treat is as a selector and search for the // sizer element within the outermost container if ( typeof self.columnWidth === 'string' ) { self.$sizer = self.$container.find( self.columnWidth ); // Check for an element } else if ( self.columnWidth && self.columnWidth.nodeType && self.columnWidth.nodeType === 1 ) { // Wrap it in jQuery self.$sizer = $( self.columnWidth ); // Check for jQuery object } else if ( self.columnWidth && self.columnWidth.jquery ) { self.$sizer = self.columnWidth; } if ( self.$sizer && self.$sizer.length ) { self.useSizer = true; self.sizer = self.$sizer[0]; } return self; }, _filter : function( category, $collection ) { var self = this, isPartialSet = $collection !== undefined, $items = isPartialSet ? $collection : self.$items, $filtered = $(); category = category || self.lastFilter; self._fire('filter'); // Loop through each item and use provided function to determine // whether to hide it or not. if ( $.isFunction(category) ) { $items.each(function() { var $item = $(this), passes = category.call($item[0], $item, self); if ( passes ) { $filtered = $filtered.add( $item ); } }); } // Otherwise we've been passed a category to filter by else { self.group = category; if (category !== 'all') { $items.each(function() { var $this = $(this), groups = $this.data('groups'), keys = self.delimeter && !$.isArray( groups ) ? groups.split( self.delimeter ) : groups, passes = $.inArray(category, keys) > -1; if ( passes ) { $filtered = $filtered.add( $this ); } }); } // category === 'all', add filtered class to everything else { $filtered = $items; } } // Individually add/remove concealed/filtered classes self._toggleFilterClasses( $items, $filtered ); $items = null; $collection = null; return $filtered; }, _toggleFilterClasses : function( $items, $filtered ) { var concealed = 'concealed', filtered = 'filtered'; $items.filter( $filtered ).each(function() { var $filteredItem = $(this); // Remove concealed if it's there if ( $filteredItem.hasClass( concealed ) ) { $filteredItem.removeClass( concealed ); } // Add filtered class if it's not there if ( !$filteredItem.hasClass( filtered ) ) { $filteredItem.addClass( filtered ); } }); $items.not( $filtered ).each(function() { var $filteredItem = $(this); // Add concealed if it's not there if ( !$filteredItem.hasClass( concealed ) ) { $filteredItem.addClass( concealed ); } // Remove filtered class if it's there if ( $filteredItem.hasClass( filtered ) ) { $filteredItem.removeClass( filtered ); } }); }, /** * Set the initial css for each item * @param {jQuery} $items optionally specifiy at set to initialize * @return {jQuery} the items which were just set */ _initItems : function( $items ) { $items = $items || this.$items; return $items.css( this.itemCss ); }, _updateItemCount : function() { this.visibleItems = this.$items.filter('.filtered').length; return this; }, _setTransition : function( element ) { var self = this; element.style[ self.transitionName ] = self.transform + ' ' + self.speed + 'ms ' + self.easing + ', opacity ' + self.speed + 'ms ' + self.easing; return element; }, _setTransitions : function( $items ) { var self = this; $items = $items || self.$items; $items.each(function() { self._setTransition( this ); }); return self; }, _setSequentialDelay : function( $collection ) { var self = this; if ( !self.supported ) { return; } // $collection can be an array of dom elements or jquery object $.each( $collection, function(i) { // This works because the transition-property: transform, opacity; this.style[ self.transitionDelayName ] = '0ms,' + ((i + 1) * self.sequentialFadeDelay) + 'ms'; // Set the delay back to zero after one transition $(this).one(self.transitionend, function() { this.style[ self.transitionDelayName ] = '0ms'; }); }); }, _getItems : function() { return this.$container.children( this.itemSelector ); }, _getPreciseDimension : function( element, style ) { var dimension; if ( window.getComputedStyle ) { dimension = window.getComputedStyle( element, null )[ style ]; } else { dimension = $( element ).css( style ); } return parseFloat( dimension ); }, // Calculate number of columns // Gets css if using sizer element _setColumns : function( theContainerWidth ) { var self = this, containerWidth = theContainerWidth || self.$container.width(), gutter = typeof self.gutterWidth === 'function' ? self.gutterWidth( containerWidth ) : self.useSizer ? self._getPreciseDimension( self.sizer, 'marginLeft' ) : self.gutterWidth, calculatedColumns; // use fluid columnWidth function if there self.colWidth = self.isFluid ? self.columnWidth( containerWidth ) : // columnWidth option isn't a function, are they using a sizing element? self.useSizer ? self._getPreciseDimension( self.sizer, 'width' ) : // if not, how about the explicitly set option? self.columnWidth || // or use the size of the first item self.$items.outerWidth(true) || // if there's no items, use size of container containerWidth; // Don't let them set a column width of zero. self.colWidth = self.colWidth || containerWidth; self.colWidth += gutter; calculatedColumns = (containerWidth + gutter) / self.colWidth; // Widths given from getComputedStyle are not precise enough... if ( Math.ceil(calculatedColumns) - calculatedColumns < 0.01 ) { // e.g. calculatedColumns = 11.998876 calculatedColumns = Math.ceil( calculatedColumns ); } self.cols = Math.floor( calculatedColumns ); self.cols = Math.max( self.cols, 1 ); self.containerWidth = containerWidth; }, /** * Adjust the height of the grid */ _setContainerSize : function() { var self = this, gridHeight = Math.max.apply( Math, self.colYs ); self.$container.css( 'height', gridHeight + 'px' ); }, /** * Fire events with .shuffle namespace */ _fire : function( name, args ) { this.$container.trigger( name + '.shuffle', args && args.length ? args : [ this ] ); }, /** * Loops through each item that should be shown * Calculates the x and y position and then transitions it * @param {array} items - array of items that will be shown/layed out in order in their array. * Because jQuery collection are always ordered in DOM order, we can't pass a jq collection * @param {function} complete callback function * @param {boolean} isOnlyPosition set this to true to only trigger positioning of the items */ _layout: function( items, fn, isOnlyPosition, isHide ) { var self = this; fn = fn || self.filterEnd; self.layoutTransitionEnded = false; $.each(items, function(index) { var $this = $(items[index]), //how many columns does this brick span colSpan = Math.ceil( $this.outerWidth(true) / self.colWidth ); colSpan = Math.min( colSpan, self.cols ); if ( colSpan === 1 ) { // if brick spans only one column, just like singleMode self._placeItem( $this, self.colYs, fn, isOnlyPosition, isHide ); } else { // brick spans more than one column // how many different places could this brick fit horizontally var groupCount = self.cols + 1 - colSpan, groupY = [], groupColY, i; // for each group potential horizontal position for ( i = 0; i < groupCount; i++ ) { // make an array of colY values for that one group groupColY = self.colYs.slice( i, i + colSpan ); // and get the max value of the array groupY[i] = Math.max.apply( Math, groupColY ); } self._placeItem( $this, groupY, fn, isOnlyPosition, isHide ); } }); // `_layout` always happens after `_shrink`, so it's safe to process the style // queue here with styles from the shrink method self._processStyleQueue(); // Adjust the height of the container self._setContainerSize(); }, _resetCols : function() { // reset columns var i = this.cols; this.colYs = []; while (i--) { this.colYs.push( 0 ); } }, _reLayout : function( callback, isOnlyPosition ) { var self = this; callback = callback || self.filterEnd; self._resetCols(); // If we've already sorted the elements, keep them sorted if ( self.keepSorted && self.lastSort ) { self.sort( self.lastSort, true, isOnlyPosition ); } else { self._layout( self.$items.filter('.filtered').get(), self.filterEnd, isOnlyPosition ); } }, // worker method that places brick in the columnSet with the the minY _placeItem : function( $item, setY, callback, isOnlyPosition, isHide ) { // get the minimum Y value from the columns var self = this, minimumY = Math.min.apply( Math, setY ), shortCol = 0; // Find index of short column, the first from the left where this item will go // if ( setY[i] === minimumY ) requires items' height to be exact every time. // The buffer value is very useful when the height is a percentage of the width for (var i = 0, len = setY.length; i < len; i++) { if ( setY[i] >= minimumY - self.buffer && setY[i] <= minimumY + self.buffer ) { shortCol = i; break; } } // Position the item var x = self.colWidth * shortCol, y = minimumY; x = Math.round( x + self.offset.left ); y = Math.round( y + self.offset.top ); // Save data for shrink $item.data( {x: x, y: y} ); // Apply setHeight to necessary columns var setHeight = minimumY + $item.outerHeight( true ), setSpan = self.cols + 1 - len; for ( i = 0; i < setSpan; i++ ) { self.colYs[ shortCol + i ] = setHeight; } var transitionObj = { from: 'layout', $this: $item, x: x, y: y, scale: 1 }; if ( isOnlyPosition ) { transitionObj.skipTransition = true; } else { transitionObj.opacity = 1; transitionObj.callback = callback; } if ( isHide ) { transitionObj.opacity = 0; } self.styleQueue.push( transitionObj ); }, /** * Hides the elements that don't match our filter */ _shrink : function( $collection, fn ) { var self = this, $concealed = $collection || self.$items.filter('.concealed'), transitionObj = {}, callback = fn || self.shrinkEnd; // Abort if no items if ( !$concealed.length ) { return; } self._fire('shrink'); self.shrinkTransitionEnded = false; $concealed.each(function() { var $this = $(this), data = $this.data(); transitionObj = { from: 'shrink', $this: $this, x: data.x, y: data.y, scale : 0.001, opacity: 0, callback: callback }; self.styleQueue.push( transitionObj ); }); }, _onResize : function() { var self = this, containerWidth; // If shuffle is disabled, destroyed, don't do anything if ( !self.enabled || self.destroyed ) { return; } // Will need to check height in the future if it's layed out horizontaly containerWidth = self.$container.width(); // containerWidth hasn't changed, don't do anything if ( containerWidth === self.containerWidth ) { return; } self.resized(); }, /** * Uses Modernizr's prefixed() to get the correct vendor property name and sets it using jQuery .css() * * @param {jq} $el the jquery object to set the css on * @param {string} prop the property to set (e.g. 'transition') * @param {string} value the value of the prop */ setPrefixedCss : function( $el, prop, value ) { $el.css( this.prefixed( prop ), value ); }, /** * Returns things like `-webkit-transition` or `box-sizing` from `transition` or `boxSizing`, respectively * * @param {string} property to be prefixed. * @return {string} the prefixed css property */ getPrefixed : function( prop ) { var styleName = this.prefixed( prop ); return styleName ? styleName.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-') : styleName; }, /** * Transitions an item in the grid * * @param {object} opts options * @param {jQuery} opts.$this jQuery object representing the current item * @param {int} opts.x translate's x * @param {int} opts.y translate's y * @param {String} opts.left left position (used when no transforms available) * @param {String} opts.top top position (used when no transforms available) * @param {float} opts.scale amount to scale the item * @param {float} opts.opacity opacity of the item * @param {String} opts.height the height of the item (used when no transforms available) * @param {String} opts.width the width of the item (used when no transforms available) * @param {function} opts.callback complete function for the animation */ transition: function(opts) { var self = this, transform, // Only fire callback once per collection's transition complete = function() { if ( !self.layoutTransitionEnded && opts.from === 'layout' ) { self._fire('layout'); opts.callback.call( self ); self.layoutTransitionEnded = true; } else if ( !self.shrinkTransitionEnded && opts.from === 'shrink' ) { opts.callback.call( self ); self.shrinkTransitionEnded = true; } }; opts.callback = opts.callback || $.noop; // Use CSS Transforms if we have them if ( self.supported ) { // Make scale one if it's not preset if ( opts.scale === undefined ) { opts.scale = 1; } if (self.threeD) { transform = 'translate3d(' + opts.x + 'px, ' + opts.y + 'px, 0) scale3d(' + opts.scale + ', ' + opts.scale + ', 1)'; } else { transform = 'translate(' + opts.x + 'px, ' + opts.y + 'px) scale(' + opts.scale + ', ' + opts.scale + ')'; } if ( opts.x !== undefined ) { self.setPrefixedCss(opts.$this, 'transform', transform); } if ( opts.opacity !== undefined ) { // Update css to trigger CSS Animation opts.$this.css('opacity' , opts.opacity); } opts.$this.one(self.transitionend, complete); } else { var cssObj = { left: opts.x, top: opts.y, opacity: opts.opacity }; // Use jQuery to animate left/top opts.$this.stop( true ).animate( cssObj, self.speed, 'swing', complete); } }, _processStyleQueue : function() { var self = this, queue = self.styleQueue; $.each( queue, function(i, transitionObj) { if ( transitionObj.skipTransition ) { self._skipTransition( transitionObj.$this[0], function() { self.transition( transitionObj ); }); } else { self.transition( transitionObj ); } }); // Remove everything in the style queue self.styleQueue.length = 0; }, shrinkEnd: function() { this._fire('shrunk'); }, filterEnd: function() { this._fire('filtered'); }, sortEnd: function() { this._fire('sorted'); }, /** * Change a property or execute a function which will not have a transition * @param {Element} element DOM element that won't be transitioned * @param {string|function} property the new style property which will be set or a function which will be called * @param {string} [value] the value that `property` should be. */ _skipTransition : function( element, property, value ) { var self = this, reflow, durationName = self.transitionDuration, duration = element.style[ durationName ]; // Set the duration to zero so it happens immediately element.style[ durationName ] = '0ms'; // ms needed for firefox! if ( $.isFunction( property ) ) { property(); } else { element.style[ property ] = value; } // Force reflow reflow = element.offsetWidth; // Put the duration back element.style[ durationName ] = duration; }, _addItems : function( $newItems, animateIn, isSequential ) { var self = this, $passed, passed; if ( !self.supported ) { animateIn = false; } $newItems.addClass('shuffle-item'); self._initItems( $newItems ); self._setTransitions( $newItems ); self.$items = self._getItems(); // Hide all items $newItems.css('opacity', 0); // Get ones that passed the current filter $passed = self._filter( undefined, $newItems ); passed = $passed.get(); // How many filtered elements? self._updateItemCount(); if ( animateIn ) { self._layout( passed, null, true, true ); if ( isSequential ) { self._setSequentialDelay( $passed ); } self._revealAppended( $passed ); } else { self._layout( passed ); } }, _revealAppended : function( $newFilteredItems ) { var self = this; setTimeout(function() { $newFilteredItems.each(function(i, el) { self.transition({ from: 'reveal', $this: $(el), opacity: 1 }); }); }, self.revealAppendedDelay); }, /** * Public Methods */ /** * The magic. This is what makes the plugin 'shuffle' * @param {String|Function} category category to filter by. Can be a function * @param {Object} [sortObj] A sort object which can sort the filtered set */ shuffle : function( category, sortObj ) { var self = this; if ( !self.enabled ) { return; } if ( !category ) { category = 'all'; } self._filter( category ); // Save the last filter in case elements are appended. self.lastFilter = category; // How many filtered elements? self._updateItemCount(); self._resetCols(); // Shrink each concealed item self._shrink(); // If given a valid sort object, save it so that _reLayout() will sort the items if ( sortObj ) { self.lastSort = sortObj; } // Update transforms on .filtered elements so they will animate to their new positions self._reLayout(); }, /** * Gets the .filtered elements, sorts them, and passes them to layout * * @param {object} opts the options object for the sorted plugin * @param {Boolean} [fromFilter] was called from Shuffle.filter method. */ sort: function( opts, fromFilter, isOnlyPosition ) { var self = this, items = self.$items.filter('.filtered').sorted(opts); if ( !fromFilter ) { self._resetCols(); } self._layout(items, function() { if (fromFilter) { self.filterEnd(); } self.sortEnd(); }, isOnlyPosition); self.lastSort = opts; }, /** * Relayout everything */ resized: function( isOnlyLayout ) { if ( this.enabled ) { if ( !isOnlyLayout ) { // Get updated colCount this._setColumns(); } // Layout items this._reLayout(); } }, /** * Use this instead of `update()` if you don't need the columns and gutters updated * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations * could be off. */ layout : function() { this.update( true ); }, update : function( isOnlyLayout ) { this.resized( isOnlyLayout ); }, /** * New items have been appended to shuffle. Fade them in sequentially * @param {jQuery} $newItems jQuery collection of new items * @param {Boolean} [animateIn] If false, the new items won't animate in * @param {Boolean} [isSequential] If false, new items won't sequentially fade in */ appended : function( $newItems, animateIn, isSequential ) { // True if undefined animateIn = animateIn === false ? false : true; isSequential = isSequential === false ? false : true; this._addItems( $newItems, animateIn, isSequential ); }, /** * Disables shuffle from updating dimensions and layout on resize */ disable : function() { this.enabled = false; }, /** * Enables shuffle again * @param {Boolean} isUpdateLayout if undefined, shuffle will update columns and gutters */ enable : function( isUpdateLayout ) { this.enabled = true; if ( isUpdateLayout !== false ) { this.update(); } }, /** * Remove 1 or more shuffle items * @param {jQuery} $collection a jQuery object containing one or more element in shuffle * @return {Shuffle} the shuffle object */ remove : function( $collection ) { // If this isn't a jquery object, exit if ( !$collection.length || !$collection.jquery ) { return; } var self = this; // Hide collection first self._shrink( $collection, function() { var shuffle = this; // Remove the collection in the callback $collection.remove(); // Update the items, layout, count and fire off `removed` event setTimeout(function() { shuffle.$items = shuffle._getItems(); shuffle.layout(); shuffle._updateItemCount(); shuffle._fire( 'removed', [ $collection, shuffle ] ); // Let it get garbage collected $collection = null; }, 0); }); // Process changes self._processStyleQueue(); return self; }, /** * Destroys shuffle, removes events, styles, and classes */ destroy: function() { var self = this; // If there is more than one shuffle instance on the page, // removing the resize handler from the window would remove them // all. This is why a unique value is needed. self.$window.off('.' + self.unique); // Reset container styles self.$container .removeClass('shuffle') .removeAttr('style') .removeData('shuffle'); // Reset individual item styles self.$items .removeAttr('style') .removeClass('concealed filtered shuffle-item'); // Set a flag so if a debounced resize has been triggered, // it can first check if it is actually destroyed and not doing anything self.destroyed = true; } }; // Overrideable options Shuffle.options = { group: 'all', // Filter group speed: 250, // Transition/animation speed (milliseconds) easing: 'ease-out', // css easing function to use itemSelector: '', // e.g. '.picture-item' sizer: null, // sizer element. Can be anything columnWidth is gutterWidth: 0, // a static number or function that tells the plugin how wide the gutters between columns are (in pixels) columnWidth: 0, // a static number or function that returns a number which tells the plugin how wide the columns are (in pixels) delimeter: null, // if your group is not json, and is comma delimeted, you could set delimeter to ',' buffer: 0, // useful for percentage based heights when they might not always be exactly the same (in pixels) initialSort: null, // Shuffle can be initialized with a sort object. It is the same object given to the sort method throttle: $.throttle || null, // By default, shuffle will try to throttle the resize event. This option will change the method it uses throttleTime: 300, // How often shuffle can be called on resize (in milliseconds) sequentialFadeDelay: 150, // Delay between each item that fades in when adding items supported: Modernizr.csstransforms && Modernizr.csstransitions // supports transitions and transforms }; // Not overrideable Shuffle.settings = { $sizer: null, useSizer: false, itemCss : { // default CSS for each item position: 'absolute', top: 0, left: 0 }, offset: { top: 0, left: 0 }, revealAppendedDelay: 300, keepSorted : true, // Keep sorted when shuffling/layout enabled: true, destroyed: false, styleQueue: [], prefixed: Modernizr.prefixed, threeD: Modernizr.csstransforms3d // supports 3d transforms }; // Plugin definition $.fn.shuffle = function( opts ) { var args = Array.prototype.slice.call( arguments, 1 ); return this.each(function() { var $this = $( this ), shuffle = $this.data( 'shuffle' ); // If we don't have a stored shuffle, make a new one and save it if ( !shuffle ) { shuffle = new Shuffle( $this, opts ); $this.data( 'shuffle', shuffle ); } if ( typeof opts === 'string' && shuffle[ opts ] ) { shuffle[ opts ].apply( shuffle, args ); } }); }; })(jQuery, Modernizr); /* ugallery */ /*global ugalleries, Modernizr */ jQuery(function($){ var throttle = function(a,b,c){var d,e,f,g=null,h=0;c||(c={});var i=function(){h=c.leading===!1?0:new Date().getTime(),g=null,f=a.apply(d,e),g||(d=e=null)};return function(){var j=new Date().getTime();h||c.leading!==!1||(h=j);var k=b-(j-h);return d=this,e=arguments,0>=k||k>b?(clearTimeout(g),g=null,h=j,f=a.apply(d,e),g||(d=e=null)):g||c.trailing===!1||(g=setTimeout(i,k)),f}}; var resizedInDesktop = false; var initialized = false; var updateHorizonalPadding = function(gallery, absolute) { var container = gallery.find('.ugallery_items').width(), items = gallery.find('.ugallery_labels').length ? gallery.find('.ugallery_item.filtered') : gallery.find('.ugallery_item'), itemWidth = items.outerWidth(), row = 0, columns, thumbPaddingData, thumbPadding, thumbSidePadding, thumbBottomPadding, lockPadding, itemsTotalWidth; thumbSidePadding = gallery.data('thumb-side-padding') ? gallery.data('thumb-side-padding') : 0; thumbBottomPadding = gallery.data('thumb-bottom-padding') ? gallery.data('thumb-bottom-padding') : 0; thumbPaddingData = gallery.data('thumb-padding'); lockPadding = gallery.data('thumb-lock-padding'); if(typeof lockPadding === 'undefined' || lockPadding === "") { sidePadding = thumbSidePadding; bottomPadding = thumbBottomPadding; } else { sidePadding = typeof thumbPaddingData === 'undefined' ? 15 : thumbPaddingData; bottomPadding = sidePadding; } columns = Math.floor(container / (itemWidth + sidePadding)); columns++;// Increase for 1 besause upper calculation will always give one less itemsTotalWidth = columns * itemWidth + (columns - 1) * sidePadding; if (itemsTotalWidth > container) {// But check if got too much columns--; } items.each(function(item_index) { var $this = $(this); if (absolute) { // Set top margin for all thumbs that are not in first row if (item_index + 1 > columns && bottomPadding) { $this.css('top', parseInt($this.css('top'), 10) + bottomPadding * row); } if (item_index > 0 && (item_index + 1) % columns === 0) { row++; if (bottomPadding && !gallery.data('height-adjusted')) { gallery.css('height', parseInt(gallery.css('height'), 10) + bottomPadding); } } } else { // Set top margin for all thumbs that are not in first row if (item_index + 1 > columns && bottomPadding) { $this.css('margin-top', bottomPadding); } } }); if (absolute && !gallery.data('height-adjusted')) { gallery.css('height', parseInt(gallery.css('height'), 10) - parseInt(items.css('margin-bottom'), 10)); } gallery.data('height-adjusted', true); }; var bindShuffle = function($ugallery_grid, force) { if (Modernizr.mq('only all and (max-width: 1079px)')) { return; } if (!force) { if (resizedInDesktop) { return; } } resizedInDesktop = true; var $grids = $ugallery_grid || $('.ugallery_grid'); $grids.each(function(){ var grid = $(this); var sidePadding; var thumbSidePadding = grid.parent().data('thumb-side-padding') ? grid.parent().data('thumb-side-padding') : 0; var thumbPaddingData = grid.parent().data('thumb-padding'); var lockPadding = grid.parent().data('thumb-lock-padding'); if(typeof lockPadding === 'undefined' || lockPadding === "") { sidePadding = thumbSidePadding; } else { sidePadding = typeof thumbPaddingData === 'undefined' ? 15 : thumbPaddingData; } grid.parent().data('height-adjusted', false); grid.on('layout.shuffle', function(){ setTimeout(function(){ updateHorizonalPadding(grid.parent(), true); }, 20); }); grid.shuffle({ itemSelector: '#' + $(this).attr('rel') + ' .ugallery_item', gutterWidth: sidePadding, supported: false }); grid.siblings('.ugallery_labels').on('click', '.ugallery_label_filter', function(e) { var filter; e.preventDefault(); $(e.delegateTarget).find('a.filter_selected').removeClass('filter_selected'); filter = $(e.target).addClass('filter_selected').attr('rel'); grid.shuffle('shuffle', filter); }); }); }; $(document).on('upfront-load', function() { Upfront.frontFunctions = Upfront.frontFunctions || {}; Upfront.frontFunctions.galleryBindShuffle = bindShuffle; }); /** The following is being done so that the gallery items inside a lightbox can shuffle after the lightbox shows up, in order to expand around in the available space **/ $(document).on('upfront-lightbox-open', function() { setTimeout(function(){ $(window).trigger('resize'); }, 300); }); if (typeof ugalleries !== 'undefined') { var titleSrc = function(item) { var itemId = item.el.closest('.ugallery_item').attr('rel'), text = gallery.find('.ugallery_lb_text[rel=' + itemId + ']') ; if (text.length) { return text.html(); } return ''; }; var resizeWithText = function() { var caption = this.content.find('figcaption'), maxHeight = this.wH - 120 - caption.outerHeight(), maxWidth = $(window).width() - 200 ; this.content.find('img').css({ 'max-width': maxWidth, 'max-height': maxHeight }); }; /** * re-Resize Magnific Popup 100ms after MFP open (iPhone issue) */ var resizeMFP = function() { if(/i(Pad|Phone|Pod)/g.test(navigator.userAgent)) setTimeout(function(){ $.magnificPopup.instance.updateSize(); }, 500); }; var setupLightbox = function(galleryId) { var data = $('#' + galleryId).find('.ugallery').data(); var containerClass ='gallery-' + galleryId + '-lightbox'; if (data.lightboxShowClose === true) { $('.mfp-close').show(); } else { $('.mfp-close').hide(); } if (data.lightboxShowImageCount === true) { $('.mfp-counter').show(); } else { $('.mfp-counter').hide(); } $('.mfp-content').css('background', data.lightboxActiveAreaBg); $('.mfp-bg').css('background', data.lightboxOverlayBg); $('.mfp-wrap, .mfp-bg').addClass(containerClass); if ($('style#' + containerClass).length === 0) { $('body').append(''); } $('style#' + containerClass).html(data.styles); }; var markup, gallery, magOptions; markup = '
×
'; var cleanUpMfpBg = function() { $('.mfp-ready.mfp-bg').removeAttr('style'); }; for (var galleryId in ugalleries) { var data = $('#' + galleryId).find('.ugallery').data(), gallery = false, magOptions = ugalleries[galleryId].magnific ; if (magOptions){ gallery = $('#' + galleryId).find('.ugallery_item_image'); $.each(gallery, function() { // Remove added linking to larger image - it breaks links in image description $(this).find('.ugallery_lb_text .ugallery_lightbox_link').removeAttr('href'); }); if (ugalleries[galleryId].useLightbox) { magOptions.image = { titleSrc: titleSrc, markup: markup }; } magOptions.callbacks = { resize: resizeWithText, afterChange: resizeWithText, open: function(item) { // Retrieve ID from current item var newGalleryId = this.currItem.el.closest('.upfront-gallery').attr("id"); // If newGalleryId is undefined refer to galleryId if(typeof newGalleryId === "undefined") { newGalleryId = galleryId } // Open magnificPopup setupLightbox(newGalleryId); resizeMFP(); }, close: cleanUpMfpBg }; magOptions.closeOnBgClick = data.lightboxClickOutClose; gallery.magnificPopup(magOptions); } else { gallery = $('#' + galleryId).find('.ugallery_lightbox_link'), magOptions = { closeOnBgClick: data.lightboxClickOutClose, type: 'image', gallery: { enabled: 'true', tCounter: '%curr% / %total%' }, titleSrc: 'title', verticalFit: true, image: { markup: ugalleries[galleryId].template.markup, titleSrc: 'title', verticalFit: true }, callbacks: { resize: resizeWithText, afterChange: resizeWithText, open: function() { setupLightbox(galleryId); resizeMFP(); } } }; gallery.magnificPopup(magOptions); } } setTimeout(function(){ $(window).trigger('resize'); }, 300); } var lazyBindShuffle = throttle(function(){ if (initialized === false) { initialized = true; bindShuffle(); return; } if (Modernizr.mq('only all and (max-width: 1079px)')) { return; } bindShuffle(); }, 100); $(window).on('resize', lazyBindShuffle); // Properly bind caption hover events, as they don't even work otherwise $(document) .on("mouseenter", ".ugallery_item a", function (e) { var $title = $(this).find(".ugallery-thumb-title.ugallery-caption-over"); if ($title.length && $title.is(".ugallery-caption-on-hover-1")) $title.show(); }) .on("mouseleave", ".ugallery_item a", function (e) { var $title = $(this).find(".ugallery-thumb-title.ugallery-caption-over"); if ($title.length && $title.is(".ugallery-caption-on-hover-1") && $title.closest('.redactor-box').length === 0) $title.hide(); }) ; }); /* uslider-front */ jQuery(function($){ var setHeight = function(texts){ var max = 0; texts.find('.uslide-text').each(function(){ max = Math.max(max, $(this).height()); }); texts.height(max); }; setTimeout(function(){ $('.uslider-below').each(function(){ setHeight($(this).find('.uslider-texts')); }); $('.uslider-above').each(function(){ setHeight($(this).find('.uslider-texts')); }); }, 300); var magOptions = { type: 'image', gallery: { enabled: 'true', tCounter: '%curr% / %total%' }, titleSrc: 'title', verticalFit: true, image: { titleSrc: 'title', verticalFit: true } }; $('.uslider').each( function() { $(this).find('.uslider_lightbox_link').magnificPopup(magOptions); }); }); jQuery(function($){ $('.upfront-output-uslider').each( function() { var slider = $(this), options = slider.find('.uslider').data(); /* if it is enclosed inside a lightbox, * then set it up on first instance of * the lightbox showing up. Also store a flag * issetup in order to avoid repeating this process */ if(slider.closest('div.upfront-region-lightbox').length ) { // slider should stay hidden before the lightbox opens up, // or it kills the lightbox alignment because of its extra height slider.hide(); var lightbox = slider.closest('div.upfront-region-lightbox'); $(document).on("upfront-lightbox-open", function(e, which) { // no need to set it up again and again if(slider.data('issetup')) return; // identify that the event is triggered for the same lightbox if($(which).attr('id') !== lightbox.attr('id')) return; // do the thing slider.show(); setupSlider(slider); slider.data('issetup', true); }); return; } $(document).on("upfront-breakpoint-change", function (e, breakpoint) { onBreakpointChange(slider, breakpoint); updateSlider(slider); }); setupSlider(slider); function setupSlider(slider) { slider.find('.uslides').upfront_default_slider(options); onBreakpointChange(slider, upfront_get_breakpoint()); updateSlider(slider); } function updateSlider(slider) { var uslides = slider.find('.uslides'), caption_height = 0 ; slider.find('.uslide-above').each(function(){ var slide = $(this); slide.find('.uslide-caption').remove().prependTo(slide); caption_height = 1; }); slider.find('.uslide-below').each(function(){ var slide = $(this); slide.find('.uslide-caption').remove().appendTo(slide); caption_height = 1; }); slider.find('.uslide-left').each(function(){ var slide = $(this); slide.find('.uslide-caption').remove().prependTo(slide); }); slider.find('.uslide-right').each(function(){ var slide = $(this); slide.find('.uslide-caption').remove().appendTo(slide); }); slider.find('.uslide-bottomOver, .uslide-middleCover, .uslide-bottomCover, .uslide-topCover').each(function() { var slide = $(this); slide.find('.uslide-caption').remove().prependTo(slide.find('.uslide-image')); }); uslides.attr('data-caption_height', caption_height).trigger('refresh'); } function onBreakpointChange(slider, breakpoint) { breakpoint = !breakpoint ? 'desktop' : breakpoint; slider.find('.uslide').each(function(){ var slide = $(this), breakpoint_data = slide.attr('data-breakpoint'), map = breakpoint_data ? JSON.parse(breakpoint_data) : {}, default_style = slide.attr('data-style'), all_styles = ['uslide-' + default_style] ; for ( var bp in map ) { if ( !map[bp]['style'] ) continue; all_styles.push('uslide-' + map[bp]['style']); } if ( 'desktop' == breakpoint ) { slide.removeClass(all_styles.join(' ')).addClass('uslide-' + default_style); } else if ( breakpoint in map && map[breakpoint]['style'] ) { slide.removeClass(all_styles.join(' ')).addClass('uslide-' + map[breakpoint]['style']); } }); } }); /** * Fix DOM children responsive preset classes * * Legacy preset elements double up their preset classes in DOM children, * which doesn't get pick up by the responsive preset processing in `layout.js`. * * This is where we handle those cases, for the current element * * @param {Object} e Event - ignore * @param {String} breakpoint The current breakpoint to inherit */ $(document).on("upfront-responsive_presets-changed", function (e, breakpoint) { $(".upfront-uslider").each(function () { var $root = $(this), rmap = $root.attr("data-preset_map"), map = rmap ? JSON.parse(rmap) : {}, $items ; // we have to provide proper fallback here, mobile -> tablet -> desktop if ( breakpoint == 'mobile' ) { map[breakpoint] = map[breakpoint] || map['tablet'] || map['desktop']; } else if ( breakpoint == 'tablet' ) { map[breakpoint] = map[breakpoint] || map['desktop']; } else { map[breakpoint] = map[breakpoint]; } $items = $root.find(".uslider-caption-background"); $.each(map, function (bp, preset) { $items.removeClass('slider-preset-' + preset); if (bp === breakpoint && typeof preset !== "undefined") $items.addClass('slider-preset-' + preset); }); }); }); }); /* utext */ jQuery(function($){ // Update "preload" attribute to make videos show up and autoplay videos that are // set to autoplay. $('.uinsert-video-insert video').attr('preload', 'auto').each( function() { if ($(this).attr('data-autoplay-video') === "true") { $(this).attr('autoplay', 'true'); } }); }); /* ubutton_script */ ;(function($){ /** * Fix DOM children responsive preset classes * * Legacy preset elements double up their preset classes in DOM children, * which doesn't get pick up by the responsive preset processing in `layout.js`. * * This is where we handle those cases, for the current element * * @param {Object} e Event - ignore * @param {String} breakpoint The current breakpoint to inherit */ $(document).on("upfront-responsive_presets-changed", function (e, breakpoint) { $(".upfront-button").each(function () { var $root = $(this), rmap = $root.attr("data-preset_map"), map = rmap ? JSON.parse(rmap) : {}, $items ; // we have to provide proper fallback here, mobile -> tablet -> desktop if ( breakpoint == 'mobile' ) { map[breakpoint] = map[breakpoint] || map['tablet'] || map['desktop']; } else if ( breakpoint == 'tablet' ) { map[breakpoint] = map[breakpoint] || map['desktop']; } else { map[breakpoint] = map[breakpoint]; } $items = $root.find(".upfront_cta"); $.each(map, function (bp, preset) { $items.removeClass('button-preset-' + preset); if (bp === breakpoint && typeof preset !== "undefined") $items.addClass('button-preset-' + preset); }); }); }); })(jQuery); /* upfront_youtube */ ;(function($){ /* * Replace main video placeholder image+button with actual main video. */ function replace_ph_with_video(ph) { if (ph.size() === 0) return; var video_id = ph.data('video-id') || 'none'; var loop = ph.data('loop'); var width = ph.data('width') || parseInt(ph.width(), 10); var height = ph.data('height') || parseInt(ph.height(), 10); if (loop) loop = '&' + loop; ph.after(''); ph.remove(); } /** * Take data from list item and load video in player. * @param {Object} - jQuery object of selected list item */ function load_video_from_list(list_item) { var el = list_item.parents('.upfront-youtube-container'); var video_id = list_item.data('video-id') || 'none'; // Make sure iframe is present and initialized properly if (el.find('iframe').size() === 0) { replace_ph_with_video(el.find('.ufyt_main-video-placeholder')); } // Setup ifram and title for selected video var videoUrl = 'https://www.youtube.com/embed/' + video_id + '?modestbranding=1'; el.find('iframe').attr('src', videoUrl); el.find('.ufyt_main-video-title').html(list_item.find('h4').html()); // Handle hidding active video thumbnail if(el.data('first-hidden')) { list_item.siblings().css('display', 'inline-block'); list_item.hide(); } } $('.uyoutube-gallery-item, .uyoutube-list-item').on('click', function(event) { load_video_from_list($(this)); }); $('.ufyt_main-video-placeholder').on('click', function(event) { replace_ph_with_video($(this)); }); })(jQuery);