// Custom page actions ;(function($){ 'use strict'; window.sandboxTheme = function(){ var $body = $('body'), eventNames = ['resize', 'scroll', 'ready', 'load', 'sticky'], readyStates = ['interactive', 'complete'], trigger_event = function(){ var feature, featureName, eventName = typeof arguments[0] !== 'undefined' ? arguments[0] : null; if ( eventName && $.inArray(eventName, eventNames) !== -1 ) { // Trigger all features for ( featureName in sandboxTheme.features ) { if ( sandboxTheme.features.hasOwnProperty(featureName) ) { if ( sandboxTheme.info['feature-' + featureName] ) { feature = sandboxTheme.features[featureName]; if ( feature.hasOwnProperty(eventName) ) { feature[eventName](); } } } } } }, ready_events_register = function(){ trigger_event('ready'); $(window).on('scroll', function(){ trigger_event('scroll'); }); $(window).on('debouncedresize', function(){ trigger_event('resize'); }); }, setup = function setup(){ var featureName, feature, featureOptions, dataName, dataValue, data = arguments[0]; sandboxTheme.info = {}; sandboxTheme.page = {}; if ( $.isPlainObject(data) ) { for ( dataName in data ) { if ( data.hasOwnProperty(dataName) ) { dataValue = dataName === 'id' ? parseInt(data[dataName]) : data[dataName]; if ( dataName !== 'info') { sandboxTheme.page[dataName] = dataValue; } } } if ( data.hasOwnProperty('info') ) { for ( dataName in data.info ) { if ( data.info.hasOwnProperty(dataName) ) { sandboxTheme.info[dataName] = data.info[dataName]; } } } } $.log(data); // Loop through all features to set all neccessary data for ( featureName in sandboxTheme.features ) { if ( sandboxTheme.features.hasOwnProperty(featureName) ) { feature = sandboxTheme.features[featureName]; // Make a copy of merged page feature options and feature options // jQuery.extend() will take care for a boolean value of options.page.features[featureName] featureOptions = $.extend(true, {}, feature.options || {}); // Merge the feature with common feature functions, options and info $.extend(true, feature, { options: featureOptions, info: { name: featureName, /** * Lookup for a hash fragment that starts with the features name * false if no match is found */ hash: window.location.hash.length > 0 && window.location.hash.match('^#' + featureName) ? window.location.hash.replace('#' + featureName + '-', '') : false, } }); sandboxTheme.info['feature-' + featureName] = Boolean(feature.setup()); } } // Execute events if ( $.inArray(document.readyState, readyStates) !== -1 ) { ready_events_register(); } else { $(document).on('DOMContentLoaded readyStates', function(){ ready_events_register(); }); } $(window).on('load', function(){ trigger_event('load'); }); }; return { init: function init(){ setup(arguments[0] || null); }, $body: $body, is_page: function is_page(){ var id = typeof arguments[0] !== 'undefined' ? parseInt(arguments[0]) : null; if ( id ) { return id === sandboxTheme.page.id; } else { return sandboxTheme.info.is_page; } }, get_page: function get_page(){ var property = typeof arguments[0] === 'string' ? arguments[0] : null; if ( property ) { if ( sandboxTheme.page.hasOwnProperty(property) ) { return sandboxTheme.page[property]; } else { return 'ERROR: no page property called "' + property + '"'; } } else { return sandboxTheme.page; } }, trigger: function trigger(eventName){ var eventName = typeof arguments[0] !== 'undefined' ? arguments[0] : null; if ( eventName && $.inArray(eventName, eventNames) !== -1 ) { trigger_event(eventName); } } }; }(); sandboxTheme.features = { /** * Scrolled * ======== * Controlls a className to be set, when the page has been scrolled * Any layout based on this behaviour is at style.css */ scrolled: { info: { isScrolled: false }, scroll: function scroll(){ if (this.$window.scrollTop() > 100){ if ( !this.info.isScrolled ) { this.info.isScrolled = true; sandboxTheme.$body.addClass(this.info.name); } } else { if ( this.info.isScrolled ) { this.info.isScrolled = false; sandboxTheme.$body.removeClass(this.info.name); } } }, ready: function ready(){ var scrollTop = 0; this.$window = $(window); this.$target = window.location.hash.length > 0 ? $(window.location.hash) : false; if ( this.$target && this.$target.length > 0 ) { scrollTop = this.$target.offset().top; } $('html, body').scrollTop(scrollTop); this.scroll(); }, setup: function setup(){ var isSetup = true; //sandboxTheme.info.is_front_page || sandboxTheme.info.is_home || sandboxTheme.info.is_archive; return isSetup; } }, /** * Forms support * ============= */ forms: { options: { selectors: { form: '.wpcf7-form', form_container: '.content, .textwidget', inputs: '.inputs, .textarea', input_container: 'p', label: 'label', input: 'input' }, classNames: { focus: 'focus', valued: 'valued', }, }, events: function events(){ var selectors = this.options.selectors, classNames = this.options.classNames; this.$forms.each(function(index){ var $form = $(this), $inputs = $form.find(selectors.input); $inputs.on('focusin', function(){ $(this).parents(selectors.input_container).addClass(classNames.focus); }); $inputs.on('focusout', function(){ var $input = $(this), $input_container = $input.parents(selectors.input_container).first(); $input_container.removeClass(classNames.focus); if ( $input.val() === '' ) { if ( $input_container.is('.' + classNames.valued) ) { $input_container.removeClass(classNames.valued); } } else if ( !$input_container.is('.' + classNames.valued) ) { $input_container.addClass(classNames.valued); } }); $form.on('submit', function(){ $inputs.each(function(index){ $(this).parents(selectors.input_container).first().removeClass(classNames.valued); }); }); }); }, ready: function ready(){ var selectors = this.options.selectors; this.$forms = $(selectors.form); this.events(); }, setup: function setup(){ return true; } }, /** * Back to top * =========== */ toTop: { options: { selectors: { toTop: '.to-top' } }, events: function events(){ $(this.options.selectors.toTop).on('click', function(event){ $.mPageScroll2id('scrollTo', this.hash); event.preventDefault(); }); }, ready: function ready(){ this.events(); }, setup: function setup(){ return true; } }, /** * Offpage side menu with toggle button * ==================================== * controls the behaviour of the mobile menu * Visible on: Viewport lower then 987px * Look at CSS for Layout */ sideMenu: { options: { outsideOff: true, selectors: { container:'#site-actions', site_menu: '#site-menu > .inner', source: '#site-menu .menu > li', blackout: 'body > .blackout', additional_content: '.header-bar', logo: '#site-logo', additional_items: '.add-to-sideMenu', has_sub_menu: '.menu-item-has-children', current_item: '.current-menu-item', current_item_parent: '.current-menu-parent', current_item_parents: '.current-menu-ancestor', main: '#main' }, classNames: { toggler: 'toggle', active: 'active', visible: 'visible', menu: 'menu', sub_menu: 'sub-menu', searcher: 'search', additional: 'additional', parentLink: 'sub-menu-parent-link' } }, templates:{ toggler: '', // Animated CSS Bars like svg rect elements icon: '
', }, info: {}, toggle_sub_menu: function toggle_sub_menu($item){ var active_class = this.options.classNames.toggler + '-' + this.options.classNames.active, $sub_menu_parent = $item.parent(), $active_sub_menu_parent = this.$has_sub_menu.filter('.' + active_class); if ( $active_sub_menu_parent.length > 0 ) { $active_sub_menu_parent.removeClass(active_class); $active_sub_menu_parent.children('ul').slideUp(250); } if ( !$sub_menu_parent.is($active_sub_menu_parent) ) { $sub_menu_parent.addClass(active_class); $sub_menu_parent.children('ul').slideDown(250) } }, events: function events(){ var info = this.info, classNames = this.options.classNames, selectors = this.options.selectors, $toggler = this.$toggler, $sideMenu = this.$sideMenu, sideMenu = this; // Toggle menu Off/On Page with toggler this.$toggler.on('click', function(event){ if ( info.isVisible ) { $toggler.removeClass(classNames.active); $sideMenu.removeClass(classNames.visible); sandboxTheme.$body.removeClass(info.name + '-' + classNames.visible); info.isVisible = false; } else { $toggler.addClass(classNames.active); $sideMenu.addClass(classNames.visible).find('a').eq(0).trigger('focus'); sandboxTheme.$body.addClass(info.name + '-' + classNames.visible); info.isVisible = true; } event.preventDefault(); }); // Toggle sub_menu Display this.$has_sub_menu.children('a').on('click', function click(event){ sideMenu.toggle_sub_menu($(this)); event.preventDefault(); }); // Toggle menu Off/On Page with Outside Click if ( this.options.outsideOff === true ) { this.$blackout.on('click', function(){ $toggler.trigger('click').trigger('focus'); }); } }, ready: function ready(){ var options = this.options, info = this.info, templates = this.templates, classNames = options.classNames, selectors = options.selectors, sideMenu = this; this.$container = $(selectors.container); this.$site_menu = $(selectors.site_menu); // Get sources this.$logo = $(selectors.logo).clone().removeAttr('id'); this.$additional_content = $(selectors.additional_content).clone().addClass(classNames.additional).removeAttr('id'); this.$source = $(selectors.source).clone(); // include sources to $sideMenu this.$source.appendTo(this.$container).wrapAll('