]> scripts.mit.edu Git - autoinstalls/wordpress.git/blob - wp-content/themes/twentyseventeen/assets/js/global.js
WordPress 4.7
[autoinstalls/wordpress.git] / wp-content / themes / twentyseventeen / assets / js / global.js
1 /* global twentyseventeenScreenReaderText */
2 (function( $ ) {
3
4         // Variables and DOM Caching.
5         var $body = $( 'body' ),
6                 $customHeader = $body.find( '.custom-header' ),
7                 $branding = $customHeader.find( '.site-branding' ),
8                 $navigation = $body.find( '.navigation-top' ),
9                 $navWrap = $navigation.find( '.wrap' ),
10                 $navMenuItem = $navigation.find( '.menu-item' ),
11                 $menuToggle = $navigation.find( '.menu-toggle' ),
12                 $menuScrollDown = $body.find( '.menu-scroll-down' ),
13                 $sidebar = $body.find( '#secondary' ),
14                 $entryContent = $body.find( '.entry-content' ),
15                 $formatQuote = $body.find( '.format-quote blockquote' ),
16                 isFrontPage = $body.hasClass( 'twentyseventeen-front-page' ) || $body.hasClass( 'home blog' ),
17                 navigationFixedClass = 'site-navigation-fixed',
18                 navigationHeight,
19                 navigationOuterHeight,
20                 navPadding,
21                 navMenuItemHeight,
22                 idealNavHeight,
23                 navIsNotTooTall,
24                 headerOffset,
25                 menuTop = 0,
26                 resizeTimer;
27
28         // Ensure the sticky navigation doesn't cover current focused links.
29         $( 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex], [contenteditable]', '.site-content-contain' ).filter( ':visible' ).focus( function() {
30                 if ( $navigation.hasClass( 'site-navigation-fixed' ) ) {
31                         var windowScrollTop = $( window ).scrollTop(),
32                                 fixedNavHeight = $navigation.height(),
33                                 itemScrollTop = $( this ).offset().top,
34                                 offsetDiff = itemScrollTop - windowScrollTop;
35
36                         // Account for Admin bar.
37                         if ( $( '#wpadminbar' ).length ) {
38                                 offsetDiff -= $( '#wpadminbar' ).height();
39                         }
40
41                         if ( offsetDiff < fixedNavHeight ) {
42                                 $( window ).scrollTo( itemScrollTop - ( fixedNavHeight + 50 ), 0 );
43                         }
44                 }
45         });
46
47         // Set properties of navigation.
48         function setNavProps() {
49                 navigationHeight      = $navigation.height();
50                 navigationOuterHeight = $navigation.outerHeight();
51                 navPadding            = parseFloat( $navWrap.css( 'padding-top' ) ) * 2;
52                 navMenuItemHeight     = $navMenuItem.outerHeight() * 2;
53                 idealNavHeight        = navPadding + navMenuItemHeight;
54                 navIsNotTooTall       = navigationHeight <= idealNavHeight;
55         }
56
57         // Make navigation 'stick'.
58         function adjustScrollClass() {
59
60                 // Make sure we're not on a mobile screen.
61                 if ( 'none' === $menuToggle.css( 'display' ) ) {
62
63                         // Make sure the nav isn't taller than two rows.
64                         if ( navIsNotTooTall ) {
65
66                                 // When there's a custom header image or video, the header offset includes the height of the navigation.
67                                 if ( isFrontPage && ( $body.hasClass( 'has-header-image' ) || $body.hasClass( 'has-header-video' ) ) ) {
68                                         headerOffset = $customHeader.innerHeight() - navigationOuterHeight;
69                                 } else {
70                                         headerOffset = $customHeader.innerHeight();
71                                 }
72
73                                 // If the scroll is more than the custom header, set the fixed class.
74                                 if ( $( window ).scrollTop() >= headerOffset ) {
75                                         $navigation.addClass( navigationFixedClass );
76                                 } else {
77                                         $navigation.removeClass( navigationFixedClass );
78                                 }
79
80                         } else {
81
82                                 // Remove 'fixed' class if nav is taller than two rows.
83                                 $navigation.removeClass( navigationFixedClass );
84                         }
85                 }
86         }
87
88         // Set margins of branding in header.
89         function adjustHeaderHeight() {
90                 if ( 'none' === $menuToggle.css( 'display' ) ) {
91
92                         // The margin should be applied to different elements on front-page or home vs interior pages.
93                         if ( isFrontPage ) {
94                                 $branding.css( 'margin-bottom', navigationOuterHeight );
95                         } else {
96                                 $customHeader.css( 'margin-bottom', navigationOuterHeight );
97                         }
98
99                 } else {
100                         $customHeader.css( 'margin-bottom', '0' );
101                         $branding.css( 'margin-bottom', '0' );
102                 }
103         }
104
105         // Set icon for quotes.
106         function setQuotesIcon() {
107                 $( twentyseventeenScreenReaderText.quote ).prependTo( $formatQuote );
108         }
109
110         // Add 'below-entry-meta' class to elements.
111         function belowEntryMetaClass( param ) {
112                 var sidebarPos, sidebarPosBottom;
113
114                 if ( ! $body.hasClass( 'has-sidebar' ) || (
115                         $body.hasClass( 'search' ) ||
116                         $body.hasClass( 'single-attachment' ) ||
117                         $body.hasClass( 'error404' ) ||
118                         $body.hasClass( 'twentyseventeen-front-page' )
119                 ) ) {
120                         return;
121                 }
122
123                 sidebarPos       = $sidebar.offset();
124                 sidebarPosBottom = sidebarPos.top + ( $sidebar.height() + 28 );
125
126                 $entryContent.find( param ).each( function() {
127                         var $element = $( this ),
128                                 elementPos = $element.offset(),
129                                 elementPosTop = elementPos.top;
130
131                         // Add 'below-entry-meta' to elements below the entry meta.
132                         if ( elementPosTop > sidebarPosBottom ) {
133                                 $element.addClass( 'below-entry-meta' );
134                         } else {
135                                 $element.removeClass( 'below-entry-meta' );
136                         }
137                 });
138         }
139
140         /*
141          * Test if inline SVGs are supported.
142          * @link https://github.com/Modernizr/Modernizr/
143          */
144         function supportsInlineSVG() {
145                 var div = document.createElement( 'div' );
146                 div.innerHTML = '<svg/>';
147                 return 'http://www.w3.org/2000/svg' === ( 'undefined' !== typeof SVGRect && div.firstChild && div.firstChild.namespaceURI );
148         }
149
150         /**
151          * Test if an iOS device.
152         */
153         function checkiOS() {
154                 return /iPad|iPhone|iPod/.test(navigator.userAgent) && ! window.MSStream;
155         }
156
157         /*
158          * Test if background-attachment: fixed is supported.
159          * @link http://stackoverflow.com/questions/14115080/detect-support-for-background-attachment-fixed
160          */
161         function supportsFixedBackground() {
162                 var el = document.createElement('div'),
163                         isSupported;
164
165                 try {
166                         if ( ! ( 'backgroundAttachment' in el.style ) || checkiOS() ) {
167                                 return false;
168                         }
169                         el.style.backgroundAttachment = 'fixed';
170                         isSupported = ( 'fixed' === el.style.backgroundAttachment );
171                         return isSupported;
172                 }
173                 catch (e) {
174                         return false;
175                 }
176         }
177
178         // Fire on document ready.
179         $( document ).ready( function() {
180
181                 // If navigation menu is present on page, setNavProps and adjustScrollClass.
182                 if ( $navigation.length ) {
183                         setNavProps();
184                         adjustScrollClass();
185                 }
186
187                 // If 'Scroll Down' arrow in present on page, calculate scroll offset and bind an event handler to the click event.
188                 if ( $menuScrollDown.length ) {
189
190                         if ( $( 'body' ).hasClass( 'admin-bar' ) ) {
191                                 menuTop -= 32;
192                         }
193                         if ( $( 'body' ).hasClass( 'blog' ) ) {
194                                 menuTop -= 30; // The div for latest posts has no space above content, add some to account for this.
195                         }
196                         if ( ! $navigation.length ) {
197                                 navigationOuterHeight = 0;
198                         }
199
200                         $menuScrollDown.click( function( e ) {
201                                 e.preventDefault();
202                                 $( window ).scrollTo( '#primary', {
203                                         duration: 600,
204                                         offset: { top: menuTop - navigationOuterHeight }
205                                 });
206                         });
207                 }
208
209                 adjustHeaderHeight();
210                 setQuotesIcon();
211                 if ( true === supportsInlineSVG() ) {
212                         document.documentElement.className = document.documentElement.className.replace( /(\s*)no-svg(\s*)/, '$1svg$2' );
213                 }
214
215                 if ( true === supportsFixedBackground() ) {
216                         document.documentElement.className += ' background-fixed';
217                 }
218         });
219
220         // If navigation menu is present on page, adjust it on scroll and screen resize.
221         if ( $navigation.length ) {
222
223                 // On scroll, we want to stick/unstick the navigation.
224                 $( window ).on( 'scroll', function() {
225                         adjustScrollClass();
226                         adjustHeaderHeight();
227                 });
228
229                 // Also want to make sure the navigation is where it should be on resize.
230                 $( window ).resize( function() {
231                         setNavProps();
232                         setTimeout( adjustScrollClass, 500 );
233                 });
234         }
235
236         $( window ).resize( function() {
237                 clearTimeout( resizeTimer );
238                 resizeTimer = setTimeout( function() {
239                         belowEntryMetaClass( 'blockquote.alignleft, blockquote.alignright' );
240                 }, 300 );
241                 setTimeout( adjustHeaderHeight, 1000 );
242         });
243
244         // Add header video class after the video is loaded.
245         $( document ).on( 'wp-custom-header-video-loaded', function() {
246                 $body.addClass( 'has-header-video' );
247         });
248
249 })( jQuery );