1/* global screenReaderText */ 2/** 3 * Theme functions file. 4 * 5 * Contains handlers for navigation and widget area. 6 */ 7 8( function( $ ) { 9 var $body, $window, $sidebar, adminbarOffset, top = false, 10 bottom = false, windowWidth, windowHeight, lastWindowPos = 0, 11 topOffset = 0, bodyHeight, sidebarHeight, resizeTimer, 12 secondary, button; 13 14 // Add dropdown toggle that display child menu items. 15 $( '.main-navigation .menu-item-has-children > a' ).after( '<button class="dropdown-toggle" aria-expanded="false">' + screenReaderText.expand + '</button>' ); 16 17 // Toggle buttons and submenu items with active children menu items. 18 $( '.main-navigation .current-menu-ancestor > button' ).addClass( 'toggle-on' ); 19 $( '.main-navigation .current-menu-ancestor > .sub-menu' ).addClass( 'toggled-on' ); 20 21 $( '.dropdown-toggle' ).click( function( e ) { 22 var _this = $( this ); 23 e.preventDefault(); 24 _this.toggleClass( 'toggle-on' ); 25 _this.next( '.children, .sub-menu' ).toggleClass( 'toggled-on' ); 26 _this.attr( 'aria-expanded', _this.attr( 'aria-expanded' ) === 'false' ? 'true' : 'false' ); 27 _this.html( _this.html() === screenReaderText.expand ? screenReaderText.collapse : screenReaderText.expand ); 28 } ); 29 30 secondary = $( '#secondary' ); 31 button = $( '.site-branding' ).find( '.secondary-toggle' ); 32 33 // Enable menu toggle for small screens. 34 ( function() { 35 var menu, widgets, social; 36 if ( ! secondary || ! button ) { 37 return; 38 } 39 40 // Hide button if there are no widgets and the menus are missing or empty. 41 menu = secondary.find( '.nav-menu' ); 42 widgets = secondary.find( '#widget-area' ); 43 social = secondary.find( '#social-navigation' ); 44 if ( ! widgets.length && ! social.length && ( ! menu || ! menu.children().length ) ) { 45 button.hide(); 46 return; 47 } 48 49 button.on( 'click.twentyfifteen', function() { 50 secondary.toggleClass( 'toggled-on' ); 51 secondary.trigger( 'resize' ); 52 $( this ).toggleClass( 'toggled-on' ); 53 if ( $( this, secondary ).hasClass( 'toggled-on' ) ) { 54 $( this ).attr( 'aria-expanded', 'true' ); 55 secondary.attr( 'aria-expanded', 'true' ); 56 } else { 57 $( this ).attr( 'aria-expanded', 'false' ); 58 secondary.attr( 'aria-expanded', 'false' ); 59 } 60 } ); 61 } )(); 62 63 /** 64 * @summary Add or remove ARIA attributes. 65 * Uses jQuery's width() function to determine the size of the window and add 66 * the default ARIA attributes for the menu toggle if it's visible. 67 * @since Twenty Fifteen 1.1 68 */ 69 function onResizeARIA() { 70 if ( 955 > $window.width() ) { 71 button.attr( 'aria-expanded', 'false' ); 72 secondary.attr( 'aria-expanded', 'false' ); 73 button.attr( 'aria-controls', 'secondary' ); 74 } else { 75 button.removeAttr( 'aria-expanded' ); 76 secondary.removeAttr( 'aria-expanded' ); 77 button.removeAttr( 'aria-controls' ); 78 } 79 } 80 81 // Sidebar scrolling. 82 function resize() { 83 windowWidth = $window.width(); 84 85 if ( 955 > windowWidth ) { 86 top = bottom = false; 87 $sidebar.removeAttr( 'style' ); 88 } 89 } 90 91 function scroll() { 92 var windowPos = $window.scrollTop(); 93 94 if ( 955 > windowWidth ) { 95 return; 96 } 97 98 sidebarHeight = $sidebar.height(); 99 windowHeight = $window.height(); 100 bodyHeight = $body.height(); 101 102 if ( sidebarHeight + adminbarOffset > windowHeight ) { 103 if ( windowPos > lastWindowPos ) { 104 if ( top ) { 105 top = false; 106 topOffset = ( $sidebar.offset().top > 0 ) ? $sidebar.offset().top - adminbarOffset : 0; 107 $sidebar.attr( 'style', 'top: ' + topOffset + 'px;' ); 108 } else if ( ! bottom && windowPos + windowHeight > sidebarHeight + $sidebar.offset().top && sidebarHeight + adminbarOffset < bodyHeight ) { 109 bottom = true; 110 $sidebar.attr( 'style', 'position: fixed; bottom: 0;' ); 111 } 112 } else if ( windowPos < lastWindowPos ) { 113 if ( bottom ) { 114 bottom = false; 115 topOffset = ( $sidebar.offset().top > 0 ) ? $sidebar.offset().top - adminbarOffset : 0; 116 $sidebar.attr( 'style', 'top: ' + topOffset + 'px;' ); 117 } else if ( ! top && windowPos + adminbarOffset < $sidebar.offset().top ) { 118 top = true; 119 $sidebar.attr( 'style', 'position: fixed;' ); 120 } 121 } else { 122 top = bottom = false;
123 topOffset = ( $sidebar.offset().top > 0 ) ? $sidebar.offset().top - adminbarOffset : 0; 124 $sidebar.attr( 'style', 'top: ' + topOffset + 'px;' ); 125 } 126 } else if ( ! top ) { 127 top = true; 128 $sidebar.attr( 'style', 'position: fixed;' ); 129 } 130 131 lastWindowPos = windowPos; 132 } 133 134 function resizeAndScroll() { 135 resize(); 136 scroll(); 137 } 138 139 $( document ).ready( function() { 140 $body = $( document.body ); 141 $window = $( window ); 142 $sidebar = $( '#sidebar' ).first(); 143 adminbarOffset = $body.is( '.admin-bar' ) ? $( '#wpadminbar' ).height() : 0; 144 145 $window 146 .on( 'scroll.twentyfifteen', scroll ) 147 .on( 'load.twentyfifteen', onResizeARIA ) 148 .on( 'resize.twentyfifteen', function() { 149 clearTimeout( resizeTimer ); 150 resizeTimer = setTimeout( resizeAndScroll, 500 ); 151 onResizeARIA(); 152 } ); 153 $sidebar.on( 'click.twentyfifteen keydown.twentyfifteen', 'button', resizeAndScroll ); 154 155 resizeAndScroll(); 156 157 for ( var i = 1; i < 6; i++ ) { 158 setTimeout( resizeAndScroll, 100 * i ); 159 } 160 } ); 161 162} )( jQuery );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.