1!function(e){var o={};function n(t){if(o[t])return o[t].exports;var r=o[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=o,n.d=function(e,o,t){n.o(e,o)||Object.defineProperty(e,o,{enumerable:!0,get:t})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,o){if(1&o&&(e=n(e)),8&o)return e;if(4&o&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(n.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&o&&"string"!=typeof e)for(var r in e)n.d(t,r,function(o){return e[o]}.bind(null,r));return t},n.n=function(e){var o=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(o,"a",o),o},n.o=function(e,o){return Object.prototype.hasOwnProperty.call(e,o)},n.p="",n(n.s=273)}({273:function(e,o){!function(){"use strict";let e,o;function n(e){return new Promise((o,n)=>{const t=document.createElement("script");t.onload=()=>o(),t.onerror=e=>n(e),t.src=e,document.body.appendChild(t)})}function t(){if(e)return e;const o=window.wpcom_coblocks_js;return e=n(o.coblocks_lightbox_js),e}function r(){if(o)return o;window.wpcomJQueryUsageLoggerDisabled=!0;const e=window.wpcom_coblocks_js,t=window.jQuery?Promise.resolve():n(e.jquery_core_js).then(()=>n(e.jquery_migrate_js)),r=t.then(()=>window.imagesLoaded?Promise.resolve():n(e.imagesloaded_js)),c=t.then(()=>window.Masonry?Promise.resolve():n(e.masonry_js)),u=Promise.all([t,r,c]).then(()=>n(e.coblocks_masonry_js));return o=u,o}function c(){document.querySelector(".wp-block-coblocks-gallery-masonry")&&r(),document.querySelector(".has-lightbox")&&t(),document.body.classList.contains("block-editor-page")&&(r(),t())}"loading"!==document.readyState?c():document.addEventListener("DOMContentLoaded",c)}()}});; 2/** 3 * wp-nav-menus.js 4 * https://github.com/cedaro/wp-nav-menus 5 * 6 * @copyright Copyright (c) 2016 Cedaro, LLC 7 * @license MIT 8 * @version 1.0.0 9 */ 10(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.cedaroNavMenu = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ 11(function (global){ 12"use strict"; 13var jQuery = (typeof window !== "undefined" ? window['jQuery'] : typeof global !== "undefined" ? global['jQuery'] : null),
14 wpNavMenu = require( './src/entry' ); 15 16if ( jQuery ) { 17 /** 18 * jQuery method to initialize menus. 19 * 20 * @memberOf jQuery.fn 21 * 22 * @param {Object} options Menu options. 23 * @return {jQuery} Chainable jQuery collection. 24 */ 25 jQuery.fn.cedaroNavMenu = function( options ) { 26 return this.each(function() { 27 var menu = wpNavMenu( this, options ); 28 menu.initialize(); 29 }); 30 }; 31} 32 33/** 34 * Export the method for instantiating a new menu. 35 */ 36module.exports = wpNavMenu; 37 38}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 39},{"./src/entry":2}],2:[function(require,module,exports){ 40(function (global){ 41"use strict"; 42var l10n, 43 $ = require( './query' ), 44 customizerPartials = {}, 45 NavMenu = require( './nav-menu.js' ), 46 wp = (typeof window !== "undefined" ? window['wp'] : typeof global !== "undefined" ? global['wp'] : null); 47 48// Merge global localized strings. 49l10n = $.extend({ 50 collapseSubmenu: 'Collapse submenu', 51 expandSubmenu: 'Expand submenu' 52}, global._cedaroNavMenuL10n ); 53 54/** 55 * Initialize a partial placement in the customizer. 56 * 57 * Managing menus in the customizer causes the placement to be replaced for 58 * each change, so it needs to be reinitialized each time to ensure submenus 59 * are accessible. 60 * 61 * @param {wp.customize.selectiveRefresh.Placement} placement Partial placement. 62 */ 63function initializeCustomizePlacement( placement ) { 64 var addedMenu, removedMenu; 65 66 if ( ! ( placement.partial.id in customizerPartials ) ) { 67 return; 68 } 69 70 removedMenu = customizerPartials[ placement.partial.id ]; 71 removedMenu.destroy(); 72 73 // Initialize the new placement. 74 addedMenu = new NavMenu( placement.container[0], removedMenu.options ); 75 addedMenu.initialize(); 76 77 // Synchronize expanded states from the removed menu. 78 placement.removedNodes.find( '.' + removedMenu.options.expandedMenuItemClass ).each(function() { 79 placement.container 80 .find( '#' + this.id ) 81 .find( '> .{class}, > a .{class}'.replace( /{class}/g, removedMenu.options.submenuToggleClass ) ) 82 .trigger( 'click' ); 83 }); 84} 85 86/** 87 * Selective refresh support in the customizer. 88 */ 89if ( wp && 'customize' in wp ) { 90 wp.customize.bind( 'preview-ready', function() { 91 wp.customize.selectiveRefresh.bind( 'partial-content-rendered', initializeCustomizePlacement ); 92 }); 93} 94 95/** 96 * Create a new menu object. 97 * 98 * @param {string|Element} el Selector or HTML element. 99 * @param {object} options Menu options. 100 * @return {NavMenu} Nav menu instance. 101 */ 102module.exports = function( el, options ) { 103 var menu, 104 partialId; 105 106 // Fail gracefully in unsupported browsers. 107 if ( ! ( 'addEventListener' in global ) ) { 108 return; 109 } 110 111 options = options || {}; 112 options.l10n = options.l10n || {}; 113 114 // Merge global localized strings. 115 $.extend( options.l10n, l10n ); 116 117 menu = new NavMenu( el, options ); 118 119 // Attempt to detect the partial id in the customizer and store a 120 // reference so it can be cleaned up during a selective refresh. 121 partialId = menu.el.getAttribute( 'data-customize-partial-id' ); 122 if ( partialId ) { 123 customizerPartials[ partialId ] = menu; 124 } 125 126 return menu; 127}; 128 129}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 130},{"./nav-menu.js":3,"./query":4}],3:[function(require,module,exports){ 131"use strict"; 132var $ = require ( './query' ), 133 document = window.document; 134 135/** 136 * Create a menu instance. 137 * 138 * @class NavMenu 139 * 140 * @param {Element|string} el HTML element or selector. 141 * @param {object} options Menu options. 142 * @param {string} options.activeMenuItemClass HTML class for active menu items. 143 * @param {number} options.breakpoint Breakpoint to switch between mobile and full site mode. 144 * @param {boolean} options.expandCurrentItem Whether to expand the current menu item on initial load. 145 * @param {string} options.expandedMenuItemClass HTML class applied to the menu item that contains an expanded submenu. 146 * @param {string} options.expandedSubmenuClass HTML class applied to expanded submenus. 147 * @param {string} options.expandedSubmenuToggleClass HTML class applied to submenu toggle buttons when the submenu is expanded. 148 * @param {number} options.hoverTimeout Delay in milliseconds before hiding submenus. 149 * @param {object} options.l10n Localized strings specific to this instance. 150 * @param {string} options.submenuToggleClass HTML class for submenu toggle buttons. 151 * @param {string} options.submenuToggleInsert Where to insert submenu toggle buttons. Defaults to before the submenu. 152 * @param {string} options.submenuToggleMode Mode for displaying submenus. 153 */ 154function NavMenu( el, options ) { 155 var menu = this; 156 157 this.el = $( el )[0]; 158 this.options = $.extend( {}, NavMenu.defaults, options ); 159 this.el.setAttribute( 'data-nav-menu-options', JSON.stringify( this.options ) ); 160 161 // Automatically bind all event handlers. 162 Object.keys( Object.getPrototypeOf( this ) ).filter(function( key ) { 163 return 'function' === typeof menu[ key ] && 0 === key.indexOf( 'on' ); 164 }
164).forEach(function( key ) { 165 menu[ key ] = menu[ key ].bind( menu ); 166 }); 167} 168 169NavMenu.defaults = { 170 breakpoint: 768, // disable 171 expandCurrentItem: false, 172 hoverTimeout: 50, 173 l10n: {}, 174 submenuToggleInsert: '', // default|append|false 175 submenuToggleMode: 'hover', // hover|click; @todo hover-tap? 176 177 // Configurable HTML classes. 178 activeMenuItemClass: 'is-active', 179 expandedMenuItemClass: 'is-sub-menu-open', 180 expandedSubmenuClass: 'is-open', 181 expandedSubmenuToggleClass: 'is-open', 182 submenuToggleClass: 'sub-menu-toggle' 183}; 184 185NavMenu.prototype = { 186 _initialized: false, 187 _hasExpandedSubmenu: false, 188 _hoverTimeouts: [], 189 _touchStarted: false, 190 _viewportWidth: null, 191 192 /** 193 * Initialize the menu. 194 * 195 * @return {this} 196 */ 197 initialize: function() { 198 var menu = this; 199 200 if ( this._initialized ) { 201 return; 202 } 203 204 this._initialized = true; 205 206 // Ensure every menu item has an id to manage the hover state timeouts. 207 this.$items = $( 'li', this.el ).each(function( el ) { 208 el.id = $.getUid( el, 'menu-item' ); 209 }); 210 211 this.$submenus = $( 'li ul', this.el ).each(function( el ) { 212 el.setAttribute( 'aria-expanded', 'false' ); 213 }); 214 215 if ( false !== this.options.submenuToggleInsert ) { 216 this.insertSubmenuToggleButtons(); 217 } 218 219 document.addEventListener( 'click', this.onDocumentClick, true ); 220 this.el.addEventListener( 'click', this.onSubmenuToggleClick, false ); 221 222 if ( 'hover' === this.options.submenuToggleMode /*&& 'disable' !== this.options.breakpoint*/ ) { 223 this.el.addEventListener( 'touchstart', this.onMenuLinkTouchStart, false ); 224 this.el.addEventListener( 'mouseover', this.onMenuItemMouseEnter, false ); 225 this.el.addEventListener( 'mouseout', this.onMenuItemMouseLeave, false ); 226 } 227 228 // Use capturing mode to support event delegation. 229 // @link https://developer.mozilla.org/en-US/docs/Web/Events/blur#Event_delegation 230 this.el.addEventListener( 'focus', this.onMenuLinkFocus, true ); 231 this.el.addEventListener( 'blur', this.onMenuLinkBlur, true ); 232 233 // Expand current submenus on initialization. 234 if ( 235 menu.options.expandCurrentItem && 236 ( 'click' === menu.options.submenuToggleMode || menu.isMobile() ) 237 ) { 238 this.$items.filter(function( el ) { 239 return el.classList.contains( 'current-menu-item' ) || el.classList.contains( 'current-menu-ancestor' ); 240 }).each(function( el ) { 241 menu.expandSubmenu( el ); 242 }); 243 } 244 245 return this; 246 }, 247 248 /** 249 * Destroy the menu. 250 * 251 * Cleans up delegated event listeners. 252 * 253 * @todo Consider removing toggle buttons. 254 */ 255 destroy: function() { 256 document.removeEventListener( 'click', this.onDocumentClick, true ); 257 this.el.removeEventListener( 'click', this.onSubmenuToggleClick, false ); 258 this.el.removeEventListener( 'mouseover', this.onMenuItemMouseEnter, false ); 259 this.el.removeEventListener( 'mouseout', this.onMenuItemMouseLeave, false ); 260 this.el.removeEventListener( 'focus', this.onMenuLinkFocus, true ); 261 this.el.removeEventListener( 'blur', this.onMenuLinkBlur, true ); 262 }, 263 264 /** 265 * Whether the menu is in mobile mode. 266 * 267 * @return {boolean} 268 */ 269 isMobile: function() { 270 if ( 'disable' === this.options.breakpoint ) { 271 return true; 272 } 273 274 return this.getViewportWidth() < this.options.breakpoint; 275 }, 276 277 /** 278 * Collapse the submenu in a menu item. 279 * 280 * @param {Element} menuItem Menu item element. 281 */ 282 collapseSubmenu: function( menuItem ) { 283 var button = this.getSubmenuToggle( menuItem ), 284 $submenu = $( '.sub-menu', menuItem ); 285 286 menuItem.classList.remove( this.options.expandedMenuItemClass ); 287 288 if ( button ) { 289 button.classList.remove( this.options.expandedSubmenuToggleClass ); 290 button.setAttribute( 'aria-expanded', 'false' ); 291 $( '.screen-reader-text', button )[0].innerHTML = this.options.l10n.expandSubmenu || 'Expand submenu'; 292 } 293 294 if ( $submenu.length ) { 295 $submenu[0].classList.remove( this.options.expandedSubmenuClass ); 296 $submenu[0].setAttribute( 'aria-expanded', 'false' ); 297 } 298 }, 299 300 /** 301 * Collapse all submenus. 302 */ 303 collapseAllSubmenus: function() { 304 var menu = this; 305 306 this.$items.each(function( el ) { 307 el.classList.remove( menu.options.activeMenuItemClass ); 308 menu.collapseSubmenu( el ); 309 }); 310 }, 311 312 /** 313 * Collapse submenus in branches that don't contain the focused element. 314 * 315 * @param {Element} focusedEl Element that has focus. 316 */ 317 collapseUnrelatedSubmenus: function( focusedEl ) { 318 var menu = this; 319 320 this.$items.each(function( el ) { 321 if ( ! el.contains( focusedEl ) ) { 322 el.classList.remove( menu.options.activeMenuItemClass ); 323 menu.collapseSubmenu( el ); 324 } 325 }); 326 }, 327 328 /** 329 * Expand the submenu in a menu item. 330 * 331 * @param {Element} menuItem Menu item element. 332 */ 333 expandSubmenu: function( menuItem ) {
334 var button = this.getSubmenuToggle( menuItem ), 335 $submenu = $( '.sub-menu', menuItem ); 336 337 menuItem.classList.add( this.options.activeMenuItemClass ); 338 339 if ( ! this.hasSubmenu( menuItem ) ) { 340 return; 341 } 342 343 menuItem.classList.add( this.options.expandedMenuItemClass ); 344 345 if ( button ) { 346 button.classList.add( this.options.expandedSubmenuToggleClass ); 347 button.setAttribute( 'aria-expanded', 'true' ); 348 $( '.screen-reader-text', button )[0].innerHTML = this.options.l10n.collapseSubmenu || 'Collapse submenu'; 349 } 350 351 if ( $submenu.length ) { 352 $submenu[0].classList.add( this.options.expandedSubmenuClass ); 353 $submenu[0].setAttribute( 'aria-expanded', 'true' ); 354 } 355 }, 356 357 /** 358 * Retrieve the viewport width. 359 * 360 * @return {number} 361 */ 362 getViewportWidth: function() { 363 return this._viewportWidth || Math.max( document.documentElement.clientWidth, window.innerWidth || 0 ); 364 }, 365 366 /** 367 * Set the viewport width. 368 * 369 * @param {number} width Width of the viewport. 370 * @return {this} 371 */ 372 setViewportWidth: function( width ) { 373 this._viewportWidth = parseInt( width, 10 ); 374 return this; 375 }, 376 377 /** 378 * Retrieve the submenu toggle button from a menu item. 379 * 380 * @param {Element} menuItem Menu item element. 381 * @return {Element} 382 */ 383 getSubmenuToggle: function( menuItem ) { 384 return $( '.' + this.options.submenuToggleClass, menuItem )[0]; 385 }, 386 387 /** 388 * Whether a menu item has a submenu. 389 * 390 * WordPress adds the 'menu-item-has-children' class to menu items even when 391 * the children are hidden with a depth restriction, so we have to query for 392 * the submenu to see if it exists. 393 * 394 * @param {Element} menuItem Menu item element. 395 * @return {Boolean} 396 */ 397 hasSubmenu: function ( menuItem ) { 398 return $( '.sub-menu', menuItem ).length > 0; //classList.contains( 'menu-item-has-children' ); 399 }, 400 401 /** 402 * Insert toggle buttons in menu items that contain a submenu. 403 */ 404 insertSubmenuToggleButtons: function() { 405 var button, span, 406 menu = this; 407 408 button = document.createElement( 'button' ); 409 button.setAttribute( 'class', menu.options.submenuToggleClass ); 410 button.setAttribute( 'aria-expanded', 'false' ); 411 412 span = document.createElement( 'span' ); 413 span.setAttribute( 'class', 'screen-reader-text' ); 414 span.innerHTML = this.options.l10n.expandSubmenu || 'Expand submenu'; 415 416 button.appendChild( span ); 417 418 this.$submenus.each(function( submenu ) { 419 var buttonInstance = button.cloneNode( true ); 420 421 // Assign an id to each submenu to use in ARIA attributes. 422 if ( ! submenu.id ) { 423 submenu.id = $.getUid( submenu, 'sub-menu' ); 424 } 425 426 buttonInstance.setAttribute( 'aria-controls', submenu.id ); 427 428 if ( 'append' !== menu.options.submenuToggleInsert ) { 429 // Insert the toggle button before the submenu element. 430 submenu.parentElement.insertBefore( buttonInstance, submenu ); 431 return; 432 } 433 434 // Append the toggle button to the parent item anchor element. 435 // This should primarily be used for backward compatibility. 436 $( submenu.parentElement.children ).each(function( el ) { 437 if ( 'A' === el.nodeName ) { 438 el.appendChild( buttonInstance ); 439 return false; 440 } 441 }); 442 }); 443 }, 444 445 isSubmenuExpanded: function( menuItem ) { 446 return menuItem.classList.contains( this.options.expandedMenuItemClass ); 447 }, 448 449 /** 450 * Toggle the submenu in a menu item. 451 * 452 * @param {Element} menuItem Menu item element. 453 */ 454 toggleSubmenu: function( menuItem ) { 455 if ( this.isSubmenuExpanded( menuItem ) ) { 456 this.collapseSubmenu( menuItem ); 457 } else { 458 this.expandSubmenu( menuItem ); 459 } 460 }, 461 462 /** 463 * Collapse all submenus when clicking outside the menu. 464 * 465 * On touch devices without toggle buttons, tapping a link will expand 466 * the submenu. It's not possible to close it without clicking another link 467 * with a submenu, which leads back to the initial problem. 468 * 469 * Submenus also won't be collapsed when the keyboard is used to focus 470 * an element and a click occurs outside the menu. 471 */ 472 onDocumentClick: function( e ) { 473 // Don't do this in click mode or on mobile. 474 if ( 'click' === this.options.submenuToggleMode || this.isMobile() ) { 475 return; 476 } 477 478 if ( this.el === e.target || ! this.el.contains( e.target ) ) { 479 this.collapseAllSubmenus(); 480 } 481 }, 482 483 /** 484 * Handle clicks on submenu toggle buttons. 485 * 486 * Delegated to the menu element, so need to ensure the click is on a 487 * toggle button before handling it. 488 * 489 * @param {MouseEvent} e Mouse event object. 490 */ 491 onSubmenuToggleClick: function( e ) { 492 var menuItem, 493 button = $( e.target ).closest( '.' + this.options.submenuToggleClass, this.el ); 494 495 // Bail if this isn't a click on a toggle button. 496 if ( ! button ) { 497 return; 498 } 499 500 e.preventDefault(); 501 502 menuItem = $( e.target ).closest( 'li', this.el ); 503 this.toggleSubmenu( menuItem ); 504 }, 505 506 /** 507 * Handle touchstart events on menu links. 508 * 509 * On touch devices, make the first click open a submenu if there isn't a 510 * clickable toggle button available. Otherwise, the submenus w
510ouldn't be 511 * accessible on touch devices. 512 * 513 * @param {TouchEvent} e Touch event object. 514 */ 515 onMenuLinkTouchStart: function( e ) { 516 var button, target; 517 518 // Bail if this isn't a touchstart on the anchor element. 519 if ( ! $.isElementOrDescendant( e.target, 'A', this.el ) ) { 520 return; 521 } 522 523 target = $( e.target ).closest( 'li', this.el ); 524 525 // Bail if a target couldn't be found. 526 if ( ! target ) { 527 return; 528 } 529 530 // Bail if there isn't a submenu in this item or it's already expanded. 531 if ( ! this.hasSubmenu( target ) || this.isSubmenuExpanded( target ) ) { 532 return; 533 } 534 535 button = this.getSubmenuToggle( target ); 536 537 // Expand the submenu and disable the click event if a clickable toggle 538 // button isn't available. 539 if ( ! $.isClickable( button ) ) { 540 e.stopImmediatePropagation(); 541 e.preventDefault(); 542 this.expandSubmenu( target ); 543 this.collapseUnrelatedSubmenus( e.target ); 544 } else { 545 this._touchStarted = true; 546 } 547 }, 548 549 /** 550 * Handle mouseenter events on menu items. 551 * 552 * When the mouse enters a menu item: 553 * - Add an 'is-active' class to the menu item to aid in styling. Using 554 * the class should prevent needing to use :hover, which can cause 555 * double tap issues on touch devices. 556 * - Expand the submenu if not on mobile. The toggle button should be 557 * used to control submenus on mobile. 558 * 559 * Mimics mouseenter, but is delegated to the menu element instead of 560 * being bound to each item. The actual mouseenter event cannot be 561 * delegated. 562 * 563 * @link https://developer.mozilla.org/en-US/docs/Web/Events/mouseenter 564 * @link http://stackoverflow.com/a/22444819 565 * @link https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html#//apple_ref/doc/uid/TP40006511-SW7 566 * @link https://patrickhlauke.github.io/touch/tests/results/ 567 * 568 * @param {MouseEvent} e Mouse event object. 569 */ 570 onMenuItemMouseEnter: function( e ) { 571 var related, target, 572 isTouchEvent = this._touchStarted, 573 menu = this; 574 575 // Reset the touch started flag. 576 this._isTouchStarted = false; 577 578 target = $( e.target ).closest( 'li', this.el ); 579 related = $( e.relatedTarget ).closest( 'li', this.el ); 580 581 /* 582 * Bail if a target couldn't be found, or if the cursor is already in 583 * the target element. Handling mouseover events like this mimics 584 * mousenter behavior. 585 */ 586 if ( ! target || related === target ) { 587 return; 588 } 589 590 // Clear the timeout to hide a submenu when re-entering an item. 591 $( e.target ).up( 'li', this.el ).each(function( el ) { 592 clearTimeout( menu._hoverTimeouts[ el.id ] ); 593 el.classList.add( menu.options.activeMenuItemClass ); 594 }); 595 596 // Bail if there isn't a submenu in this item or it's already expanded. 597 if ( ! this.hasSubmenu( target ) || this.isSubmenuExpanded( target ) ) { 598 return; 599 } 600 601 /* 602 * If a submenu has been expanded by a focus event, hovering over 603 * unrelated menu items won't collapse the submenu. This should only 604 * happen when the keyboard is used to focus a link, then the mouse is 605 * used to interact with the menu. It's an edge case an may not be worth 606 * the performance impact of looping through every item on mouseenter to 607 * collapse unrelated submenus. 608 */ 609 // if ( ! this.isMobile() ) { 610 // this.collapseUnrelatedSubmenus( target ); 611 // } 612 613 /* 614 * If this event was triggered by a touchstart event and the target is 615 * an anchor element, don't open the submenu to prevent it from flashing 616 * before the link is followed. Also prevents a double tap from being 617 * required on iOS. 618 */ 619 if ( ! isTouchEvent || ! $.isElementOrDescendant( e.target, 'A', this.el ) ) { 620 // Don't expand on mobile to prevent the menu from jumping. 621 if ( ! this.isMobile() ) { 622 this.expandSubmenu( target ); 623 } 624 } 625 }, 626 627 /** 628 * Handle mouseleave events on menu items. 629 * 630 * When the mouse leaves a menu item, collapse submenus and remove the 631 * 'is-active' class for any menu items that no longer have the cursor 632 * hovering over them. 633 * 634 * Mimics mouseleave, but is delegated to the menu element instead of 635 * being bound to each item. 636 * 637 * @link https://developer.mozilla.org/en-US/docs/Web/Events/mouseleave 638 * 639 * @param {MouseEvent} e Moust event object. 640 */ 641 onMenuItemMouseLeave: function( e ) { 642 var menu = this, 643 isMobile = menu.isMobile(); 644 645 $( e.target ).up( 'li', this.el ).filter(function( el ) { 646 return el !== e.relatedTarget && ! el.contains( e.relatedTarget ); 647 }).each(function( el ) { 648 el.classList.remove( menu.options.activeMenuItemClass ); 649 650 // Bail in mobile mode to prevent the menu from jumping. 651 if ( isMobile ) { 652 return; 653 } 654 655 menu._hoverTimeouts[ el.id ] = setTimeout(function() { 656 menu.collapseSubmenu( el ); 657 }, menu.options.hoverTimeout ); 658 }); 659 }, 660 661 /** 662 * Handle the focus event on elements within the menu. 663 * 664 * Aids keyboard navigation by: 665 * - Collapsing submenus in unrelated items to prevent submenus from 666 * overlapping in full screen mode. This is not done in mobile mode to 667 * prevent the menu from jumping when tabbing through items. 668 * - Adding an 'is-active' class to ancestor menu items when any 669 * descendant is focused. 670 * - Expanding a submenu when an element (link or toggle button) in the 671 * parent menu item receives focus. 672 * 673 * @param {FocusEvent} e Focus event object. 674 */ 675 onMenuLinkFocus: function( e ) { 676 var button, $parents, 677 menu = this; 678 679 // Collapse unrelated submenus except in mobile mode. 680 if ( 'click' !== menu.options.submenuToggleMode && ! menu.isMobile() ) { 681 menu.collapseUnrelatedSubmenus( e.target ); 682 } 683 684 $parents = $( e.target ).parents( 'li', menu.el ).each(function( el ) { 685 el.classList.add( menu.options.activeMenuItemClass ); 686 }); 687 688 // Bail if the target menu item doesn't have a submenu. 689 if ( ! menu.hasSubmenu( $parents[ 0 ] ) ) { 690 return; 691 } 692
693 button = this.getSubmenuToggle( $parents[0] ); 694 695 /* 696 * Expand the submenu if a toggle button isn't visible. 697 * 698 * Also expands parents since keyboards can access elements positioned 699 * off-screen, so reverse tabbing through a menu needs to make sure 700 * parents are visible. 701 */ 702 if ( ! button || ! $.isVisible( button ) ) { 703 $parents.each(function( el ) { 704 menu.expandSubmenu( el ); 705 }); 706 } 707 }, 708 709 /** 710 * Close submenus when focus leaves the containing item. 711 * 712 * Aids keyboard navigation in full screen mode by preventing multiple 713 * expanded submenus from overlapping when tabbing through items. 714 * 715 * The relatedTarget property isn't available in some browsers for focus 716 * events, so it's not possible to grab the focused element in a blur 717 * event handler. For that reason, unrelated submenus are also collapsed in 718 * onMenuLinkFocus. 719 * 720 * @link https://developer.mozilla.org/en-US/docs/Web/API/FocusEvent/relatedTarget 721 * 722 * @todo Blur events sent when clicking outside the element the event is 723 * bound to also send null for the relatedTarget. This prevents 724 * clicking anywhere else in the document from collapsing the submenu. 725 * 726 * @param {FocusEvent} e Focus event object. 727 */ 728 onMenuLinkBlur: function( e ) { 729 var menu = this; 730 731 // Remove the activeMenuItemClass from the parent menu items. 732 $( e.target ).parents( 'li', menu.el ).each(function( el ) { 733 el.classList.remove( menu.options.activeMenuItemClass ); 734 }); 735 736 // Bail if the relatedTarget event is null. 737 if ( ! e.relatedTarget ) { 738 return; 739 } 740 741 // Disable on mobile to prevent the menu from jumping while tabbing 742 // through menu items and toggle buttons. 743 if ( 'click' === menu.options.submenuToggleMode || menu.isMobile() ) { 744 return; 745 } 746 747 menu.collapseUnrelatedSubmenus( e.relatedTarget ); 748 } 749}; 750 751module.exports = NavMenu; 752 753},{"./query":4}],4:[function(require,module,exports){ 754"use strict"; 755var _ = require( './utils' ); 756 757function Query( selector, context ) { 758 var i, length; 759 760 if ( selector instanceof Query ) { 761 return selector; 762 } 763 764 if ( ! selector ) { 765 return this; 766 } 767 768 context = context || document; 769 if ( context.length ) { 770 context = context[0]; 771 } 772 773 if ( 'string' === typeof selector ) { 774 selector = context.querySelectorAll( selector ); 775 } 776 777 if ( selector && selector.nodeType ) { 778 this.length = 1; 779 this[0] = selector; 780 } else { 781 selector = Array.prototype.slice.call( selector ); 782 length = this.length = selector.length; 783 784 for ( i = 0; i < length; i++ ) { 785 this[ i ] = selector[ i ]; 786 } 787 } 788} 789 790_.extend( Query.prototype, { 791 length: 0, 792 793 closest: function( selector, context ) { 794 var el = this[0]; 795 context = context || document.body; 796 797 while ( el && el !== context ) { 798 if ( _.matches( el, selector ) ) { 799 return el; 800 } 801 802 el = el.parentElement; 803 } 804 805 return null; 806 }, 807 808 each: function( callback ) { 809 _.each( this, callback ); 810 return this; 811 }, 812 813 filter: function( callback ) { 814 return query( Array.prototype.filter.call( this, callback ) ); 815 }, 816 817 /** 818 * @todo Improve performance: http://ryanmorr.com/abstract-away-the-performance-faults-of-queryselectorall/ 819 */ 820 find: function( selector ) { 821 return query( this[0].querySelectorAll( selector ) ); 822 }, 823 824 parents: function( selector, context ) { 825 var el = this[0], 826 parents = []; 827 828 context = context || document.body; 829 830 while ( el && el.parentElement && el.parentElement !== context ) { 831 if ( _.matches( el.parentElement, selector ) ) { 832 parents.push( el.parentElement ); 833 } 834 el = el.parentElement; 835 } 836 837 return query( parents ); 838 }, 839 840 up: function( selector, context ) { 841 var items = Array.prototype.slice.call( this.parents( selector, context ) ); 842 843 if ( _.matches( this[0], selector ) ) { 844 items.unshift( this[0] ); 845 } 846 847 return query( items ); 848 } 849}); 850 851function query( selector, context ) { 852 return new Query( selector, context ); 853} 854 855module.exports = _.extend( query, _, { 856 isClickable: function( el ) { 857 var styles; 858 859 if ( ! el ) { 860 return false; 861 } 862 863 styles = window.getComputedStyle( el ); 864 return 'none' !== styles.display && 'none' !== styles.pointerEvents; 865 }, 866 867 isElementOrDescendant: function( el, tagName, container ) { 868 return tagName === el.nodeName || null !== query( el ).closest( tagName, container ); 869 }, 870 871 isVisible: function( el ) { 872 return el && 'none' !== window.getComputedStyle( el ).display; 873 } 874}); 875 876},{"./utils":5}],5:[function(require,module,exports){ 877"use strict";
878function each( items, callback ) { 879 var i, 880 length = items.length; 881 882 for ( i = 0; i < length; i++ ) { 883 if ( false === callback.call( items[i], items[i], i ) ) { 884 break; 885 } 886 } 887} 888 889function extend( target ) { 890 var i = 0, 891 length = arguments.length; 892 893 target = target || {}; 894 895 while ( ++i < length ) { 896 if ( ! arguments[ i ] ) { 897 continue; 898 } 899 900 for ( var key in arguments[ i ] ) { 901 if ( arguments[ i ].hasOwnProperty( key ) ) { 902 target[ key ] = arguments[ i ][ key ]; 903 } 904 } 905 } 906 907 return target; 908} 909 910function generateUniqueId( prefix ) { 911 prefix = prefix || ''; 912 if ( '' !== prefix ) { 913 prefix += '-'; 914 } 915 return prefix + Math.random().toString( 36 ).slice( 2, 15 ); 916} 917 918function getUniqueId( el, prefix ) { 919 if ( el.id ) { 920 return el.id; 921 } 922 923 return generateUniqueId( prefix ); 924} 925 926/** 927 * @link https://developer.mozilla.org/en-US/docs/Web/API/Element/matches 928 */ 929function matches( el, selector ) { 930 var fn = el && ( 931 el.matches || 932 el.webkitMatchesSelector || 933 el.mozMatchesSelector || 934 el.msMatchesSelector || 935 el.oMatchesSelector 936 ); 937 938 return !! fn && fn.call( el, selector ); 939} 940 941module.exports = { 942 each: each, 943 extend: extend, 944 getUid: getUniqueId, 945 matches: matches 946}; 947 948},{}]},{},[1])(1) 949});; 950/*global _obsidianSettings:false, AudiothemeTracks:false */ 951 952window.cue = window.cue || {}; 953window.obsidian = window.obsidian || {}; 954 955(function( window, $, undefined ) { 956 'use strict'; 957 958 var $window = $( window ), 959 $document = $( document ), 960 cue = window.cue, 961 obsidian = window.obsidian; 962 963 // Localize jquery.cue.js. 964 cue.l10n = $.extend( cue.l10n, _obsidianSettings.l10n ); 965 966 $.extend( obsidian, { 967 config: { 968 tracklist: { 969 classPrefix: 'mejs-', 970 cueSkin: 'obsidian-tracklist', 971 cueSelectors: { 972 playlist: '.tracklist-area', 973 track: '.track', 974 trackCurrentTime: '.track-current-time', 975 trackDuration: '.track-duration' 976 }, 977 enableAutosize: false, 978 features: [ 'cueplaylist' ], 979 pluginPath: _obsidianSettings.mejs.pluginPath, 980 setDimensions: false, 981 timeFormat: 'm:ss' 982 } 983 }, 984 985 init: function() { 986 $( 'body' ).addClass( 'ontouchstart' in window || 'onmsgesturechange' in window ? 'touch' : 'no-touch' ); 987 988 obsidian.setupExternalLinks(); 989 obsidian.setupBackground(); 990 obsidian.setupNavigation(); 991 obsidian.setupPopupLinks(); 992 obsidian.setupTracklist(); 993 obsidian.setupVideos(); 994 }, 995 996 /** 997 * Set up the background image. 998 * 999 * Prevents the background image from jumping/zooming on mobile devices 1000 * after scrolling. 1001 */ 1002 setupBackground: function() { 1003 var isThrottled = false, 1004 $overlay = $( '.obsidian-background-overlay' ); 1005 1006 if ( ! this.isMobile() ) { 1007 return; 1008 } 1009 1010 $overlay.css( 'bottom', 'auto' ).height( screen.height ); 1011 1012 $( window ).on( 'load orientationchange resize', function() { 1013 if ( isThrottled ) { 1014 return; 1015 } 1016 1017 isThrottled = true; 1018 setTimeout(function() { 1019 $overlay.height( screen.height ); 1020 isThrottled = false; 1021 }, 150 ); 1022 }); 1023 }, 1024 1025 /** 1026 * Setup external links to open in a new window. 1027 */ 1028 setupExternalLinks: function() { 1029 $( '.js-maybe-external' ).each(function() { 1030 if ( this.hostname && this.hostname !== window.location.hostname ) { 1031 $( this ).attr( 'target', '_blank' ); 1032 } 1033 }); 1034 }, 1035 1036 /** 1037 * Set up the main navigation. 1038 */ 1039 setupNavigation: function() { 1040 var $navigation = $( '.site-navigation' ); 1041 1042 // Toggle the main menu. 1043 $( '.site-navigation-toggle' ).on( 'click', function() { 1044 $navigation.toggleClass( 'is-open' ); 1045 }); 1046 1047 $navigation.find( '.menu' ).cedaroNavMenu({ 1048 breakpoint: 768, 1049 submenuToggleInsert: 'append' 1050 }); 1051 }, 1052 1053 /** 1054 * Open new windows for links with a class of '.js-popup'. 1055 */ 1056 setupPopupLinks: function() { 1057 $( '.js-popup' ).on( 'click', function( e ) { 1058 var $this = $( this ), 1059 popupId = $this.data( 'popup-id' ) || 'popup', 1060 popupUrl = $this.data( 'popup-url' ) || $this.attr( 'href' ), 1061 popupWidth = $this.data( 'popup-width' ) || 550, 1062 popupHeight = $this.data( 'popup-height' ) || 260; 1063 1064 e.preventDefault(); 1065 1066 window.open( popupUrl, popupId, [ 1067 'width=' + popupWidth, 1068 'height=' + popupHeight, 1069 'directories=no', 1070 'location=no', 1071 'menubar=no', 1072 'scrollbars=no', 1073 'status=no', 1074 'toolbar=no' 1075 ].join( ',' ) ); 1076 }); 1077 }, 1078 1079 /** 1080 * Setup tracklists. 1081 */ 1082 setupTracklist: function() { 1083 var $tracklist = $( '.tracklist-area' ); 1084 1085 if ( $tracklist.length && $.isFunction( $.fn.cuePlaylist ) ) { 1086 $tracklist.cuePlaylist( $.extend( this.config.tracklist, { 1087 cuePlaylistTracks: AudiothemeTracks.record 1088 })); 1089 } 1090 }, 1091 1092 /** 1093 * Set up videos. 1094 *
1095 * - Makes videos responsive. 1096 * - Moves videos embedded in page content to an '.entry-video' 1097 * container. Used primarily with the WPCOM single video templates. 1098 */ 1099 setupVideos: function() { 1100 if ( $.isFunction( $.fn.fitVids ) ) { 1101 $( '.hentry' ).fitVids(); 1102 } 1103 1104 $( 'body.page' ).find( '.single-video' ).find( '.jetpack-video-wrapper' ).first().appendTo( '.entry-video' ); 1105 }, 1106 1107 /** 1108 * Update the scrollbar width CSS variable. 1109 * 1110 * This doesn't modify the scrollbar at all, but sets a CSS variable 1111 * with the width of the scrollbar so it can be accounted for in 1112 * full-width layouts. 1113 */ 1114 updateScrollbarWidth: function() { 1115 var docEl = document.documentElement, 1116 prevWidth = window.getComputedStyle( docEl ).getPropertyValue( '--scrollbar-width' ), 1117 newWidth = window.innerWidth - document.body.clientWidth + 'px'; 1118 1119 if ( newWidth !== prevWidth ) { 1120 docEl.style.setProperty( '--scrollbar-width', newWidth ); 1121 } 1122 }, 1123 1124 /** 1125 * Whether the current device is mobile. 1126 * 1127 * @return {boolean} 1128 */ 1129 isMobile: function() { 1130 return ( /Android|iPhone|iPad|iPod|BlackBerry/i ).test( navigator.userAgent || navigator.vendor || window.opera ); 1131 } 1132 }); 1133 1134 $document.ready( obsidian.init ); 1135 $window.on( 'load orientationchange', obsidian.updateScrollbarWidth ); 1136 1137 obsidian.updateScrollbarWidth(); 1138 1139})( this, jQuery ); 1140;
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.