Ubuntu

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ /* globals jQuery, sowb */ var sowb = window.sowb || {}; jQuery( function ( $ ) { sowb.setupAccordion = function() { $( '.sow-accordion' ).each( function ( index, element ) { var $widget = $( this ).closest( '.so-widget-sow-accordion' ); if ( $widget.data( 'initialized' ) ) { return $( this ); } var $accordionPanels = $( element ).find( '> .sow-accordion-panel' ); $accordionPanels.not( '.sow-accordion-panel-open' ).children( '.sow-accordion-panel-content' ).hide(); var openPanels = $accordionPanels.filter( '.sow-accordion-panel-open' ).toArray(); var updateHash = function () { // noop }; var scrollToPanel = function ( $panel, smooth ) { var navOffset = 90;// Add some magic number offset to make space for possible nav menus etc. var scrollTop = $panel.offset().top - navOffset; if ( smooth ) { $( 'body,html' ).animate( { scrollTop: scrollTop, }, 200 ); } else { window.scrollTo( 0, scrollTop ); } }; var openPanel = function ( panel, preventHashChange, keepVisible ) { var $panel = $( panel ); if ( ! $panel.is( '.sow-accordion-panel-open' ) ) { $panel.find( '> .sow-accordion-panel-content' ).slideDown( { start: function () { // Sometimes the content of the panel relies on a window resize to setup correctly. // Trigger it here so it's hopefully done before the animation. $( window ).trigger( 'resize' ); $( sowb ).trigger( 'setup_widgets' ); }, complete: function() { if ( keepVisible && sowAccordion.scrollto_after_change && ( $panel.offset().top < window.scrollY || $panel.offset().top + $panel.height() > window.scrollY ) ) { scrollToPanel( $panel, true ); } $( this ).trigger( 'show' ); } }); $panel.find( '> .sow-accordion-panel-header-container > .sow-accordion-panel-header' ).attr( 'aria-expanded', true ); $panel.addClass( 'sow-accordion-panel-open' ); openPanels.push( panel ); // Check if accordion is within an accordion and if it is, ensure parent is visible var $parentPanel = $( panel ).parents( '.sow-accordion-panel' ); if ( $parentPanel.length && ! $parentPanel.hasClass( 'sow-accordion-panel-open' ) ) { openPanel( $parentPanel.get( 0 ), true ); } if ( ! preventHashChange ) { updateHash(); } } }; var closePanel = function ( panel, preventHashChange ) { var $panel = $( panel ); if ( $panel.is( '.sow-accordion-panel-open' ) ) { $panel.find( '> .sow-accordion-panel-content' ).slideUp( function() { $( this ).trigger( 'hide' ); } ); $panel.find( '> .sow-accordion-panel-header-container > .sow-accordion-panel-header' ).attr( 'aria-expanded', false ); $panel.removeClass( 'sow-accordion-panel-open' ); openPanels.splice( openPanels.indexOf( panel ), 1 ); if ( ! preventHashChange ) { updateHash(); } } }; $accordionPanels.find( '> .sow-accordion-panel-header-container > .sow-accordion-panel-header' ).on( 'click keydown', function( e ) { if ( e.type == 'keydown' ) { if ( e.keyCode !== 13 && e.keyCode !== 32 ){ return; } e.preventDefault(); } var $this = $( this ); var maxOpenPanels = $widget.data( 'maxOpenPanels' ); var $panel = $this.closest( '.sow-accordion-panel' ); if ( $panel.is( '.sow-accordion-panel-open' ) ) { closePanel( $panel.get( 0 ) ); } else { openPanel( $panel.get( 0 ), false, true ); } if ( ! isNaN( maxOpenPanels ) && maxOpenPanels > 0 && openPanels.length > maxOpenPanels ) { var skippedPanels = 0; $.each( openPanels.reverse(), function( index, el ) { if ( skippedPanels !== maxOpenPanels ) { skippedPanels++; } else { closePanel( openPanels[ index ] ); } } ); } } ); if ( $widget.data( 'useAnchorTags' ) ) { var timeoutId; updateHash = function () { if ( timeoutId ) { clearTimeout( timeoutId ); } timeoutId = setTimeout( function () { var anchors = []; var allOpenPanels = $( '.sow-accordion-panel-open' ).toArray(); for ( var i = 0; i < allOpenPanels.length; i++ ) { var anchor = $( allOpenPanels[ i ] ).data( 'anchor' ); if ( anchor ) { var $parentPanel = $( allOpenPanels[ i ] ).parents( '.sow-accordion-panel' ); if ( ! $parentPanel.length || ( $parentPanel.length && $parentPanel.hasClass( 'sow-accordion-panel-open' ) ) ) { anchors[ i ] = anchor; } } } if ( anchors && anchors.length ) { window.location.hash = anchors.join( ',' ); } else if ( window.location.hash ) { // This prevents adding a history event if no was present on load window.history.pushState( '', document.title, window.location.pathname + window.location.search ); } }, 100 ); }; var updatePanelStates = function () { var panels = $accordionPanels.toArray(); for ( var i = 0; i < panels.length; i++ ) { var panel = panels[ i ]; var panelAnchor = $( panel ).data( 'anchor' ); var anchors = window.location.hash.substring(1).split( ',' ); var panelOpen = anchors.some(function (anchor) { return decodeURI( panelAnchor ) === decodeURI( anchor ); }); if ( panelOpen ) { openPanel( panel, true ); } else { closePanel( panel, true ); } } }; $( window ).on( 'hashchange', updatePanelStates ); if ( window.location.hash ) { updatePanelStates(); } else { updateHash(); } var initialScrollPanel = $widget.data( 'initialScrollPanel' ); if ( window.location.hash && openPanels.length ) { setTimeout( function() { scrollToPanel( $( openPanels[0] ) ); }, 500 ); } else if ( initialScrollPanel > 0 ) { var $initialScrollPanel = initialScrollPanel > $accordionPanels.length ? $accordionPanels.last() : $accordionPanels.eq( initialScrollPanel - 1 ); setTimeout( function () { scrollToPanel( $initialScrollPanel ); }, 500 ); } } $widget.data( 'initialized', true ); } ); }; sowb.setupAccordion(); $( sowb ).on( 'setup_widgets', sowb.setupAccordion ); } ); window.sowb = sowb;