1/* ====================================================================================== 2 Place any jQuery helper/plugins here 3 ====================================================================================== */ 4 5/* --HELPERS-- */ 6 7/* 8 * Avoid `console` errors in browsers that lack a console 9 * @credit http://html5boilerplate.com/ 10 */ 11(function () { 12 var method; 13 var noop = function () { }; 14 var methods = [ 15 'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', 16 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 17 'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd', 18 'timeStamp', 'trace', 'warn' 19 ]; 20 var length = methods.length; 21 var console = (window.console = window.console || {}); 22 23 while (length--) { 24 method = methods[length]; 25 26 // Only stub undefined methods. 27 if (!console[method]) { 28 console[method] = noop; 29 } 30 } 31}()); 32 33/* 34 * Generic toggle function via click event 35 * @desc used to have toggle functions on click event as the toggle() function is deprecated in 1.9+ 36 * @initialise $('selector').toggleClick( function1, function2, ... ); 37 * @credit/ref http://stackoverflow.com/questions/14382857/what-to-use-instead-of-toggle-in-jquery-1-8 38 */ 39$.fn.toggleClick = function () { 40 var methods = arguments, // Store the passed arguments for future reference 41 count = methods.length; // Cache the number of methods 42 43 // Use return this to maintain jQuery chainability 44 return this.each(function (i, item) { 45 // For each element you bind to 46 var index = 0; // Create a local counter for that element 47 $(item).click(function () { // Bind a click handler to that element 48 return methods[index++ % count].apply(this, arguments); // That when called will apply the 'index' th method to that element 49 // The index % count means that we constrain our iterator between 0 and (count-1) 50 }); 51 }); 52}; 53 54/* --POLYFILLS-- */ 55 56/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ 57window.matchMedia = window.matchMedia || (function (doc, undefined) { 58 "use strict"; 59 60 var bool, 61 docElem = doc.documentElement, 62 refNode = docElem.firstElementChild || docElem.firstChild, 63 // fakeBody required for <FF4 when executed in <head> 64 fakeBody = doc.createElement("body"), 65 div = doc.createElement("div"); 66 67 div.id = "mq-test-1"; 68 div.style.cssText = "position:absolute;top:-100em"; 69 fakeBody.style.background = "none"; 70 fakeBody.appendChild(div); 71 72 return function (q) { 73 div.innerHTML = "­<style media=\"" + q + "\"> #mq-test-1 { width: 42px; }</style>"; 74 75 docElem.insertBefore(fakeBody, refNode); 76 bool = div.offsetWidth === 42; 77 docElem.removeChild(fakeBody); 78 79 return { 80 matches: bool, 81 media: q 82 }; 83 }; 84}(document)); 85 86/* --MY PLUGINS-- */ 87 88/* 89 * Toggle menu for palm sized viewports plugin 90 * @desc used to toggle the main navigation menu for palm sized viewports 91 * @initialise $('.js-menu-toggle').toggleMenu(); 92 */ 93$.fn.toggleMenu = function () { 94 // Set variables 95 var toogleBtn = $('.btn-menu-toggle'), 96 toggleBtnTxt = $('.btn-menu-toggle-txt'), 97 menu = $(this); 98 99 // Add some ARIA at palm size viewports 100 if (matchMedia(BPpalm).matches) { 101 $(this).attr('aria-hidden', 'true'); 102 } 103 104 // Toggle on click event 105 $(toogleBtn).toggleClick( 106 // Expanded state 107 function () { 108 menu.toggleClass('is-expanded').attr('aria-hidden', 'false'); 109 $(this).toggleClass('is-expanded'); 110 toggleBtnTxt.html('Close'); 111 }, 112 // Collapsed state 113 function () { 114 menu.toggleClass('is-expanded').attr('aria-hidden', 'true'); 115 $(this).toggleClass('is-expanded'); 116 toggleBtnTxt.html('Open'); 117 }) 118} 119 120/* --3rd PARTY PLUGINS-- */ 121 122// enquire.js v1.5.6 - Awesome Media Queries in JavaScript 123// Copyright (c) 2013 Nick Williams - http://wicky.nillia.ms/enquire.js 124// License: MIT (http://www.opensource.org/licenses/mit-license.php) 125window.enquire = (function (matchMedia) { 126 "use strict"; 127 128 /** 129 * Helper function for iterating over a collection 130 * 131 * @param collection 132 * @param fn 133 */ 134 function each(collection, fn) { 135 var i = 0, 136 length = collection.length, 137 cont; 138 139 for (i; i < length; i++) { 140 cont = fn(collection[i], i); 141 if (cont === false) { 142 break; //allow early exit 143 } 144 } 145 } 146 147 /** 148 * Helper function for determining whether target object is an array 149 * 150 * @param target the object under test 151 * @return {Boolean} true if array, false otherwise 152 */ 153 function isArray(target) { 154 return Object.prototype.toString.apply(target) === "[object Array]"; 155 } 156 157 /** 158 * Helper function for determining whether target object is a function 159 * 160 * @param target the object under test 161 * @return {Boolean} true if function, false otherwise 162 */ 163 function isFunction(target) { 164 return typeof target === "function"; 165 } 166 167 /** 168 * Delegate to handle a media query being matched and unmatched. 169 * 170 * @param {object} options 171 * @param {function} options.match callback for when the media query is matched 172 * @param {function} [options.unmatch] callback for when the media query is unmatched 173 * @param {function} [options.setup] one-time callback triggered the first time a query is matched 174 * @param {boolean} [options.deferSetup=false] should the setup callback be run immediately, rather than first time query is matched? 175 * @constructor 176 */ 177 function QueryHandler(options) {
178 this.initialised = false; 179 this.options = options; 180 181 if (!options.deferSetup) { 182 this.setup(); 183 } 184 } 185 QueryHandler.prototype = { 186 /** 187 * coordinates setup of the handler 188 * 189 * @function 190 */ 191 setup: function (e) { 192 if (this.options.setup) { 193 this.options.setup(e); 194 } 195 this.initialised = true; 196 }, 197 198 /** 199 * coordinates setup and triggering of the handler 200 * 201 * @function 202 * @param [e] the browser event which triggered a match 203 */ 204 on: function (e) { 205 if (!this.initialised) { 206 this.setup(e); 207 } 208 this.options.match(e); 209 }, 210 211 /** 212 * coordinates the unmatch event for the handler 213 * 214 * @function 215 * @param [e] the browser event which triggered a match 216 */ 217 off: function (e) { 218 if (this.options.unmatch) { 219 this.options.unmatch(e); 220 } 221 }, 222 223 /** 224 * called when a handler is to be destroyed. 225 * delegates to the destroy or unmatch callbacks, depending on availability. 226 * 227 * @function 228 */ 229 destroy: function () { 230 if (this.options.destroy) { 231 this.options.destroy(); 232 } 233 else { 234 this.off(); 235 } 236 }, 237 238 /** 239 * determines equality by reference. 240 * if object is supplied compare options, if function, compare match callback 241 * 242 * @function 243 * @param {object || function} [target] the target for comparison 244 */ 245 equals: function (target) { 246 return this.options === target || this.options.match === target; 247 } 248 }; 249 /** 250 * Represents a single media query, manages it's state and registered handlers for this query 251 * 252 * @constructor 253 * @param {string} query the media query string 254 * @param {boolean} [isUnconditional=false] whether the media query should run regardless of whether the conditions are met. Primarily for helping older browsers deal with mobile-first design 255 */ 256 function MediaQuery(query, isUnconditional) { 257 this.query = query; 258 this.isUnconditional = isUnconditional; 259 260 this.handlers = []; 261 this.matched = false; 262 } 263 MediaQuery.prototype = { 264 /** 265 * tests whether this media query is currently matching 266 * 267 * @function 268 * @returns {boolean} true if match, false otherwise 269 */ 270 matchMedia: function () { 271 return matchMedia(this.query).matches; 272 }, 273 274 /** 275 * add a handler for this query, triggering if already active 276 * 277 * @function 278 * @param {object} handler 279 * @param {function} handler.match callback for when query is activated 280 * @param {function} [handler.unmatch] callback for when query is deactivated 281 * @param {function} [handler.setup] callback for immediate execution when a query handler is registered 282 * @param {boolean} [handler.deferSetup=false] should the setup callback be deferred until the first time the handler is matched? 283 * @param {boolean} [turnOn=false] should the handler be turned on if the query is matching? 284 */ 285 addHandler: function (handler, turnOn) { 286 var qh = new QueryHandler(handler); 287 this.handlers.push(qh); 288 289 turnOn && this.matched && qh.on(); 290 }, 291 292 /** 293 * removes the given handler from the collection, and calls it's destroy methods 294 * 295 * @function 296 * @param {object || function} handler the handler to remove 297 */ 298 removeHandler: function (handler) { 299 var handlers = this.handlers; 300 each(handlers, function (h, i) { 301 if (h.equals(handler)) { 302 h.destroy(); 303 return !handlers.splice(i, 1); //remove from array and exit each early 304 } 305 }); 306 }, 307 308 /*
309 * assesses the query, turning on all handlers if it matches, turning them off if it doesn't match 310 * 311 * @function 312 */ 313 assess: function (e) { 314 if (this.matchMedia() || this.isUnconditional) { 315 this.match(e); 316 } 317 else { 318 this.unmatch(e); 319 } 320 }, 321 322 /** 323 * activates a query. 324 * callbacks are fired only if the query is currently unmatched 325 * 326 * @function 327 * @param {Event} [e] browser event if triggered as the result of a browser event 328 */ 329 match: function (e) { 330 if (this.matched) { 331 return; //already on 332 } 333 334 each(this.handlers, function (handler) { 335 handler.on(e); 336 }); 337 this.matched = true; 338 }, 339 340 /** 341 * deactivates a query. 342 * callbacks are fired only if the query is currently matched 343 * 344 * @function 345 * @param {Event} [e] browser event if triggered as the result of a browser event 346 */ 347 unmatch: function (e) { 348 if (!this.matched) { 349 return; //already off 350 } 351 352 each(this.handlers, function (handler) { 353 handler.off(e); 354 }); 355 this.matched = false; 356 } 357 }; 358 /** 359 * Allows for reigstration of query handlers. 360 * Manages the query handler's state and is responsible for wiring up browser events 361 * 362 * @constructor 363 */ 364 function MediaQueryDispatch() { 365 if (!matchMedia) { 366 throw new Error('matchMedia is required'); 367 } 368 369 var capabilityTest = new MediaQuery('only all'); 370 this.queries = {}; 371 this.listening = false; 372 this.browserIsIncapable = !capabilityTest.matchMedia(); 373 } 374 375 MediaQueryDispatch.prototype = { 376 /** 377 * Registers a handler for the given media query 378 * 379 * @function 380 * @param {string} q the media query 381 * @param {object || Array || Function} options either a single query handler object, a function, or an array of query handlers 382 * @param {function} options.match fired when query matched 383 * @param {function} [options.unmatch] fired when a query is no longer matched 384 * @param {function} [options.setup] fired when handler first triggered 385 * @param {boolean} [options.deferSetup=false] whether setup should be run immediately or deferred until query is first matched 386 * @param {boolean} [shouldDegrade=false] whether this particular media query should always run on incapable browsers 387 */ 388 register: function (q, options, shouldDegrade) { 389 var queries = this.queries, 390 isUnconditional = shouldDegrade && this.browserIsIncapable, 391 listening = this.listening; 392 393 if (!queries.hasOwnProperty(q)) { 394 queries[q] = new MediaQuery(q, isUnconditional); 395 396 this.listening && queries[q].assess(); 397 } 398 399 //normalise to object 400 if (isFunction(options)) { 401 options = { 402 match: options 403 }; 404 } 405 //normalise to array 406 if (!isArray(options)) { 407 options = [options]; 408 } 409 each(options, function (handler) { 410 queries[q].addHandler(handler, listening); 411 }); 412 413 return this; 414 }, 415 416 /** 417 * unregisters a query and all it's handlers, or a specific handler for a query 418 * 419 * @function 420 * @param {string} q the media query to target 421 * @param {object || function} [handler] specific handler to unregister 422 */ 423 unregister: function (q, handler) { 424 var queries = this.queries; 425 426 if (!queries.hasOwnProperty(q)) { 427 return this; 428 } 429 430 if (!handler) { 431 each(this.queries[q].handlers, function (handler) { 432 handler.destroy(); 433 }); 434 delete queries[q]; 435 } 436 else { 437 queries[q].removeHandler(handler); 438 } 439 440 return this; 441 }, 442 443 /** 444 * Tests all media queries and calls relevant methods depending whether 445 * transitioning from unmatched->matched or matched->unmatched 446 * 447 * @function 448 * @param {Event} [e] if fired as a result of a browser event, 449 * an event can be supplied to propagate to the various media query handlers 450 */ 451 fire: function (e) { 452 var queries = this.queries, 453 mediaQuery; 454 455 for (mediaQuery in queries) { 456 if (queries.hasOwnProperty(mediaQuery)) { 457 queries[mediaQuery].assess(e); 458 } 459 } 460 return this; 461 }, 462 463 /** 464 * sets up listeners for resize and orientation events 465 * 466 * @function 467 * @param {int}
467 [timeout=500] the time (in milliseconds) after which the queries should be handled 468 */ 469 listen: function (timeout) { 470 var self = this; 471 472 timeout = timeout || 500; 473 474 //creates closure for separate timed events 475 function wireFire(event) { 476 var timer; 477 478 window.addEventListener(event, function (e) { 479 timer && clearTimeout(timer); 480 481 timer = setTimeout(function () { 482 self.fire(e); 483 }, timeout); 484 }, false); 485 } 486 487 //prevent multiple event handlers 488 if (this.listening) { 489 return this; 490 } 491 492 // any browser that doesn't implement this 493 // will not have media query support 494 if (window.addEventListener) { 495 wireFire('resize'); 496 wireFire('orientationChange'); 497 } 498 499 self.fire(); 500 this.listening = true; 501 502 return this; 503 } 504 }; 505 506 return new MediaQueryDispatch(); 507}(window.matchMedia)); 508 509/* ============================================================ 510 * bootstrap-dropdown.js v2.1.1 511 * http://twitter.github.com/bootstrap/javascript.html#dropdowns 512 * ============================================================ 513 * Copyright 2012 Twitter, Inc. 514 * 515 * Licensed under the Apache License, Version 2.0 (the "License"); 516 * you may not use this file except in compliance with the License. 517 * You may obtain a copy of the License at 518 * 519 * http://www.apache.org/licenses/LICENSE-2.0 520 * 521 * Unless required by applicable law or agreed to in writing, software 522 * distributed under the License is distributed on an "AS IS" BASIS, 523 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 524 * See the License for the specific language governing permissions and 525 * limitations under the License. 526 * ============================================================ */ 527!function ($) { 528 'use strict'; // jshint ;_; 529 530 /* DROPDOWN CLASS DEFINITION 531 * ========================= */ 532 533 var toggle = '.js-drop-down-trigger' 534 , Dropdown = function (element) { 535 var $el = $(element).on('click.dropdown.data-api', this.toggle) 536 $('html').on('click.dropdown.data-api', function () { 537 $el.parent().removeClass('is-active') 538 }) 539 } 540 541 // EDIT: add the `aria-haspopup="true"` attr to parent of drop down trigger 542 var toggleParent = $('.js-drop-down-trigger').parent(); 543 toggleParent.attr('aria-haspopup', 'true') 544 545 // EDIT: add the `aria-hidden="true"` attr to drop down menu container 546 $('.js-drop-down').attr('aria-hidden', 'true'); 547 548 // EDIT: add the `tabindex="-1"` attr to links in drop down menu 549 $('.js-drop-down a').attr('tabindex', '-1'); 550 551 Dropdown.prototype = { 552 constructor: Dropdown 553 554 , toggle: function (e) { 555 var $this = $(this) 556 , $parent 557 , $dropDown 558 , isActive 559 560 // EDIT: changed the class selector to `.is-disabled` 561 if ($this.is('.is-disabled, :disabled')) return 562 563 $parent = getParent($this) 564 565 $dropDown = $this.next(); 566 567 isActive = $parent.hasClass('is-active') 568 569 clearMenus() 570 571 if (!isActive) { 572 $parent.toggleClass('is-active') 573 $this.focus() 574 // EDIT: toggle the `aria-hidden` attr for drop down menu container 575 $dropDown.attr('aria-hidden', 'false') 576 } 577 578 return false 579 } 580 581 , keydown: function (e) { 582 var $this 583 , $items 584 , $active 585 , $parent 586 , isActive 587 , index 588 589 if (!/(38|40|27)/.test(e.keyCode)) return 590 591 $this = $(this) 592 593 e.preventDefault() 594 e.stopPropagation() 595 596 // EDIT: changed the class selector to `.is-disabled` 597 if ($this.is('.is-disabled, :disabled')) return 598 599 $parent = getParent($this) 600 601 isActive = $parent.hasClass('is-active') 602 603 if (!isActive || (isActive && e.keyCode == 27)) return $this.click() 604 605 $items = $('.js-drop-down a', $parent) 606 607 if (!$items.length) return 608 609 index = $items.index($items.filter(':focus')) 610 611 if (e.keyCode == 38 && index > 0) index-- // up 612 if (e.keyCode == 40 && index < $items.length - 1) index++ // down 613 if (!~index) index = 0 614 615 $items 616 .eq(index) 617 .focus() 618 } 619 } 620 621 function clearMenus() { 622 $(toggle).each(function () { 623 getParent($(this)).removeClass('is-active') 624 // EDIT: update the `aria-hidden` attr value to 'true' for drop down menu container 625 $('.js-drop-down').attr('aria-hidden', 'true') 626 }) 627 } 628 629 function getParent($this) { 630 var selector = $this.attr('data-target') 631 , $parent 632 633 if (!selector) { 634 selector = $this.attr('href') 635 selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 636 } 637 638 $parent = $(selector) 639 $parent.length || ($parent = $this.parent()) 640 641 return $parent 642 } 643 644 /* DROPDOWN PLUGIN DEFINITION 645 * ========================== */ 646 647 $.fn.dropdown = function (option) { 648 return this.each(function () { 649 var $this = $(this) 650 , data = $this.data('dropdown') 651 if (!data) $this.data('dropdown', (data = new Dropdown(this))) 652 if (typeof option == 'string') data[option].call($this) 653 }) 654 } 655 656 $.fn.dropdown.Constructor = Dropdown 657 658 /* APPLY TO STANDARD DROPDOWN ELEMENTS 659 * =================================== */ 660 661 $(function () { 662 $('html').on('click.dropdown.data-api touchstart.dropdown.data-api', clearMenus) 663 $('body') 664 .on('click.dropdown touchstart.dropdown.data-api', '.js-drop-down form', function (e) { e.stopPropagation() }) 665 .on('click.dropdown.data-api touchstart.dropdown.data-api', toggle, Dropdown.prototype.toggle) 666 .on('keydown.dropdown.data-api touchstart.dropdown.data-api', toggle + ', .js-drop-down', Dropdown.prototype.keydown) 667 }) 668}(window.jQuery);
669// Fix for touch devices to stop closing the drop down when selecting a link: https://github.com/twitter/bootstrap/issues/4550 / http://alittlecode.com/fix-twitter-bootstraps-dropdown-menus-in-touch-screens/ 670$('body').on('touchstart.dropdown', '.js-drop-down', function (e) { e.stopPropagation(); });
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.