From 8e348325a785fe32764db5abd468bfaa33f8e63e Mon Sep 17 00:00:00 2001 From: ghazal-salehi Date: Thu, 30 Nov 2023 10:59:34 +1000 Subject: [PATCH 01/13] Resolving lint errors --- gulp/build-tasks/node-docs-flatten.js | 1 - gulp/release-tasks/files.js | 2 +- gulp/test-tasks/e2e.js | 2 +- .../accessibility/qg-accessibility.js | 7 +- .../components/accordion/qg-accordion.js | 22 +- .../components/carousel/qg-carousel.js | 14 +- .../forms/qg-address-autocomplete.js | 60 +- .../_blocks/components/forms/qg-recaptcha.js | 34 +- .../_blocks/components/misc/qg-license.js | 86 +- .../components/opengraph/qg-opengraph.js | 26 +- .../_blocks/components/print/qg-print.js | 10 +- .../components/quick-exit/qg-quick-exit.js | 4 +- .../site-search/qg-funnelback-v16-refs.js | 2 +- .../site-search/qg-search-minimize.js | 9 +- .../components/site-search/qg-site-search.js | 66 +- .../social-media/qg-social-media.js | 5 +- .../content-types/figure-credits-toggle.js | 2 +- .../_blocks/layout/footer/feedback-form.js | 12 +- .../_blocks/layout/location/qg-location.js | 179 +- .../layout/section-nav/qg-section-nav.js | 4 +- .../_blocks/layout/section-nav/qg-step-nav.js | 4 +- .../_blocks/legacy/bootstrap-accessibility.js | 535 +- .../_blocks/legacy/bootstrap-extensions.js | 22 +- .../_project/_blocks/legacy/forms/forms.js | 2282 ++++---- src/assets/_project/_blocks/qg-main.js | 2 +- .../_project/_blocks/utils/qg-datatables.js | 2 +- .../_blocks/utils/qg-load-google-api.js | 24 +- src/assets/_project/_blocks/utils/qg-misc.js | 6 +- .../_project/_blocks/utils/qg-quickexit.js | 6 +- .../lib/ext/butterfly/jquery.butterfly.js | 2531 +++++---- .../lib/ext/butterfly/jquery.history.js | 338 +- .../lib/ext/butterfly/jquery.pxToEm.js | 71 +- .../lib/ext/butterfly/jquery.resize-events.js | 261 +- .../lib/ext/fancybox/jquery.fancybox.min.js | 66 +- src/assets/_project/lib/ext/generate-id.js | 25 +- src/assets/_project/lib/ext/jquery.browser.js | 126 +- src/assets/_project/lib/ext/jquery.history.js | 4665 ++++++++--------- src/assets/_project/lib/ext/jquery.jsonp.js | 532 +- .../_project/lib/ext/jquery.resize-events.js | 330 +- src/assets/_project/lib/ext/markdown.js | 2 +- src/docs/assets/js/prism.js | 16 +- 41 files changed, 6073 insertions(+), 6320 deletions(-) diff --git a/gulp/build-tasks/node-docs-flatten.js b/gulp/build-tasks/node-docs-flatten.js index fd0adc89d..3e5f07df4 100644 --- a/gulp/build-tasks/node-docs-flatten.js +++ b/gulp/build-tasks/node-docs-flatten.js @@ -11,4 +11,3 @@ let dest = path.join('build', 'docs'); let exclude = []; ssiToStatic(includeSrc, src, dest, exclude); - diff --git a/gulp/release-tasks/files.js b/gulp/release-tasks/files.js index 5a0f3c911..1959b30bd 100644 --- a/gulp/release-tasks/files.js +++ b/gulp/release-tasks/files.js @@ -60,7 +60,7 @@ module.exports = function (gulp, plugins, config, es, path, banner) { //CSS task gulp.src(`${config.basepath.build}/assets/${config.versionName}/**/*.css`, { dot: true }) .pipe(plugins.postcss([cssnano({ - discardComments: {removeAll: true}, + discardComments: { removeAll: true }, })])) .on('error', console.log) .pipe(plugins.insert.prepend(banner)) diff --git a/gulp/test-tasks/e2e.js b/gulp/test-tasks/e2e.js index 5091dbbba..29db773c3 100644 --- a/gulp/test-tasks/e2e.js +++ b/gulp/test-tasks/e2e.js @@ -4,7 +4,7 @@ module.exports = function (gulp, plugins, argv) { console.log('\x1b[33m%s\x1b[0m: ', '1.) Browsers list missing. Example gulp test:browserstack --browsers ie,safari\n2.) Also make sure to run gulp serve to start a local server before performing e2e testing'); return; } - gulp.src('', {read: false}) + gulp.src('', { read: false }) .pipe(plugins.shell([ 'node tests/e2e/runner.js -c tests/e2e/conf.js -e ' + argv.browsers, ])); diff --git a/src/assets/_project/_blocks/components/accessibility/qg-accessibility.js b/src/assets/_project/_blocks/components/accessibility/qg-accessibility.js index 4be724fc8..6d01615d0 100644 --- a/src/assets/_project/_blocks/components/accessibility/qg-accessibility.js +++ b/src/assets/_project/_blocks/components/accessibility/qg-accessibility.js @@ -21,9 +21,9 @@ function opensInNewWindow () { } function addCorrectIncorrect () { - let ext = ':not(:has(.qg-blank-notice))'; - let $correct = $(`.qg-correct${ext}, table.qg-correct-incorrect td:nth-child(odd)${ext}`); - let $incorrect = $(`.qg-incorrect${ext}, table.qg-correct-incorrect td:nth-child(even)${ext}`); + const ext = ':not(:has(.qg-blank-notice))'; + const $correct = $(`.qg-correct${ext}, table.qg-correct-incorrect td:nth-child(odd)${ext}`); + const $incorrect = $(`.qg-incorrect${ext}, table.qg-correct-incorrect td:nth-child(even)${ext}`); $correct.prepend('Correct. '); $incorrect.prepend('Incorrect. '); @@ -37,4 +37,3 @@ function init () { } module.exports = { init: init }; - diff --git a/src/assets/_project/_blocks/components/accordion/qg-accordion.js b/src/assets/_project/_blocks/components/accordion/qg-accordion.js index 295333587..40a3aca1f 100644 --- a/src/assets/_project/_blocks/components/accordion/qg-accordion.js +++ b/src/assets/_project/_blocks/components/accordion/qg-accordion.js @@ -42,9 +42,9 @@ export class QgAccordion { * @return {undefined} **/ hashTrigger(){ - let self = this; - let hashValTrimmed = this.filterSpecialChar(self.urlHashVal); - let hashValueIdMatch = self.urlHashVal.replace('#', ''); + const self = this; + const hashValTrimmed = this.filterSpecialChar(self.urlHashVal); + const hashValueIdMatch = self.urlHashVal.replace('#', ''); if (hashValTrimmed.length > 0) { // supports ID match self.$accordion.find('.collapsing-section').each(function (index, titleEl){ @@ -85,8 +85,8 @@ export class QgAccordion { * @return {undefined} **/ accordionPanelClick(){ - let self = this; - let accHeading = self.$accordion_v2.find(self.$accHeading); + const self = this; + const accHeading = self.$accordion_v2.find(self.$accHeading); accHeading.on('click', function (event) { self.toggleOpenCloseClass($(this)); }); @@ -115,7 +115,7 @@ export class QgAccordion { * @return {undefined} **/ collapseAll(){ - let self = this; + const self = this; // collapse all click // label selector is to provide backward compatibility in case projects are using old markup $('.qg-acc-controls .collapse, label[for=\'collapse\']').on('click keypress', function (event) { @@ -133,7 +133,7 @@ export class QgAccordion { * @return {undefined} **/ expandAll(){ - let self = this; + const self = this; //expand all click // label selector is to provide backward compatibility in case projects are using old markup $('.qg-acc-controls .expand, label[for=\'expand\']').on('click keypress', function (event) { @@ -152,7 +152,7 @@ export class QgAccordion { **/ gaTracking(){ this.$accordion.find('.qg-accordion--ga').each(function(){ - let title = 'accordion title - ' + $(this).find($('.title')).text(); + const title = 'accordion title - ' + $(this).find($('.title')).text(); $(this).attr('data-analytics-link-group', title); }); } @@ -162,13 +162,13 @@ export class QgAccordion { * @return {undefined} **/ legacyAccordion(){ - let self = this; - let accItem = $('.qg-accordion:not(.qg-accordion-v2)').find('article'); + const self = this; + const accItem = $('.qg-accordion:not(.qg-accordion-v2)').find('article'); accItem.find('.acc-heading').on('keypress', function (event) { if (event.target === event.currentTarget) { event.preventDefault(); if (self.keyboardAccessibility(event) === true) { - let parent = $(this).parent(); + const parent = $(this).parent(); if (parent.find('input[name="tabs"]:checked').length > 0) { parent.find('input[name="tabs"]').prop('checked', false); } else { diff --git a/src/assets/_project/_blocks/components/carousel/qg-carousel.js b/src/assets/_project/_blocks/components/carousel/qg-carousel.js index b373c6057..8ba366fd9 100644 --- a/src/assets/_project/_blocks/components/carousel/qg-carousel.js +++ b/src/assets/_project/_blocks/components/carousel/qg-carousel.js @@ -2,16 +2,16 @@ 'use strict'; (function ($) { - let carousels = []; + const carousels = []; - let eqHeight = (carousels) => { + const eqHeight = (carousels) => { //For each carousel on the page... carousels.forEach(function (carousel) { //Get the height of each carousel slide in the carousel... - let slides = $('#' + carousel).find('.carousel-item'); + const slides = $('#' + carousel).find('.carousel-item'); //Each slides height into an array... - let slideHeights = slides.map(function(e, slide) { + const slideHeights = slides.map(function(e, slide) { return $(slide).height(); }); @@ -23,7 +23,7 @@ }; $('.qg-featured .carousel.slide').each(function (int, element) { - let carouselID = $(element).attr('id'); + const carouselID = $(element).attr('id'); carousels.push(carouselID); //Start all slides to cycle by default @@ -32,8 +32,8 @@ //Bind click/tap event $('#' + carouselID).find('.toggleCarousel').on('click', function (e) { e.preventDefault(); - let parentCarousel = $(this).parents('div.carousel.slide'); - let currentState = parentCarousel.attr('data-state'); + const parentCarousel = $(this).parents('div.carousel.slide'); + const currentState = parentCarousel.attr('data-state'); switch (currentState) { //If paused, switch to cycling state case 'pause': diff --git a/src/assets/_project/_blocks/components/forms/qg-address-autocomplete.js b/src/assets/_project/_blocks/components/forms/qg-address-autocomplete.js index b589e4348..3f5761d50 100644 --- a/src/assets/_project/_blocks/components/forms/qg-address-autocomplete.js +++ b/src/assets/_project/_blocks/components/forms/qg-address-autocomplete.js @@ -36,12 +36,12 @@ export class QgAddressAutocomplete { **/ _setValFromUrlParameters () { this.$form.find(':input:not(:checkbox):not(:radio), select, textarea').each(function () { - let name = $(this).attr('name'); - let getParameterVal = qg.swe.getParameterByName($(this).attr('name')); + const name = $(this).attr('name'); + const getParameterVal = qg.swe.getParameterByName($(this).attr('name')); getParameterVal !== false ? $('[name="' + name + '"]').val(getParameterVal) : ''; }).end().find('input[type=checkbox], input[type=radio]').each(function () { - let name = $(this).attr('name'); - let getParameterVal = qg.swe.getParameterByName(name); + const name = $(this).attr('name'); + const getParameterVal = qg.swe.getParameterByName(name); getParameterVal !== false ? $('[value="' + getParameterVal + '"]').prop('checked', true) : ''; }); } @@ -66,7 +66,7 @@ export class QgAddressAutocomplete { * @return {undefined} **/ _onBlue () { - let self = this; + const self = this; this.$inpuField.blur(function () { console.log('blur'); if ($(this).val().length === 0) { @@ -82,25 +82,25 @@ export class QgAddressAutocomplete { * @return {undefined} **/ _getCurrentLocation (){ - let self = this; + const self = this; if (this.$getCurrentLocIcon.length > 0) { $.each(this.$getCurrentLocIcon, (i, ele) => { $(ele).on('click', function (event) { event.preventDefault(); if (navigator.geolocation) { - let showLocation = (position) => { + const showLocation = (position) => { // get latitude and longitude - let latitude = position.coords.latitude; - let longitude = position.coords.longitude; - let latlng = {lat: parseFloat(latitude), lng: parseFloat(longitude)}; - let geocoder = new google.maps.Geocoder(); - let locationInput = $(this).parent().find(self.$inpuField); + const latitude = position.coords.latitude; + const longitude = position.coords.longitude; + const latlng = { lat: parseFloat(latitude), lng: parseFloat(longitude) }; + const geocoder = new google.maps.Geocoder(); + const locationInput = $(this).parent().find(self.$inpuField); // Insert latitude and longitude value to the hidden input fields self.$searchWidget.find(self.$latitude).val(latitude) .end() .find(self.$longitude).val(longitude); // get address using latitude and longitude from Google maps api - geocoder.geocode({'location': latlng}, (results, status) => { + geocoder.geocode({ location: latlng }, (results, status) => { if (status === 'OK') { if (results[1]) { locationInput.val(results[1].formatted_address); @@ -113,14 +113,14 @@ export class QgAddressAutocomplete { } }); }; - let errorHandler = (err) => { + const errorHandler = (err) => { if (err.code === 1) { alert('Error: Access is denied!'); } else if (err.code === 2) { alert('Error: Position is unavailable!'); } }; - let options = {timeout: 60000}; + const options = { timeout: 60000 }; navigator.geolocation.getCurrentPosition(showLocation, errorHandler, options); } else { // Browser doesn't support Geolocation @@ -136,25 +136,25 @@ export class QgAddressAutocomplete { * @return {undefined} **/ _addressAutocomplete () { - let self = this; - let googleAddressAutocomplete = function (){ - let qldBounds = new google.maps.LatLngBounds( + const self = this; + const googleAddressAutocomplete = function (){ + const qldBounds = new google.maps.LatLngBounds( new google.maps.LatLng(-29, 138.0578426), new google.maps.LatLng(-9.9339, 153.63831), ); // set events on all autocomplete fields (there can be more than one autocomplete on a same page) $.each(self.$inpuField, function () { - let dataStrictBounds = $(this).data('strictbounds') || true; - let options = { + const dataStrictBounds = $(this).data('strictbounds') || true; + const options = { bounds: qldBounds, strictBounds: dataStrictBounds, types: ['geocode'], }; - let autocomplete = new google.maps.places.Autocomplete(this, options); + const autocomplete = new google.maps.places.Autocomplete(this, options); // add lat and lng values after a option is selection from the autocomplete options autocomplete.addListener('place_changed', function(){ - let place = autocomplete.getPlace(); + const place = autocomplete.getPlace(); if (place.geometry) { self.$searchWidget.find(self.$latitude).val(place.geometry.location.lat()) .end() @@ -173,7 +173,7 @@ export class QgAddressAutocomplete { * @return {undefined} **/ _keypress () { - let self = this; + const self = this; // eslint-disable-next-line no-unused-vars let addressSelection = false; let reqReady = true; @@ -183,20 +183,20 @@ export class QgAddressAutocomplete { if (event.keyCode === 13 || event.keyCode === 9) { event.preventDefault(); // get the value from the autocomplete options - let itemFull = $('.pac-container .pac-item:first').text(); - let itemQuery = $('.pac-container .pac-item:first .pac-item-query').text(); - let firstResult = itemQuery + ' ' + itemFull.substring(itemQuery.length); + const itemFull = $('.pac-container .pac-item:first').text(); + const itemQuery = $('.pac-container .pac-item:first .pac-item-query').text(); + const firstResult = itemQuery + ' ' + itemFull.substring(itemQuery.length); // check if results are there if (firstResult.length > 1 && reqReady === true) { self.$inpuField.val(firstResult); - let geocoder = new google.maps.Geocoder(); - geocoder.geocode({ 'address': firstResult }, function (results, status) { + const geocoder = new google.maps.Geocoder(); + geocoder.geocode({ address: firstResult }, function (results, status) { if (status === 'OK') { reqReady = false; if (results) { $('.qg-location-autocomplete').val(results[0].formatted_address); - let latitude = results[0].geometry.location.lat(); - let longitude = results[0].geometry.location.lng(); + const latitude = results[0].geometry.location.lat(); + const longitude = results[0].geometry.location.lng(); addressSelection = true; self.$searchWidget.find(self.$latitude).val(latitude) .end() diff --git a/src/assets/_project/_blocks/components/forms/qg-recaptcha.js b/src/assets/_project/_blocks/components/forms/qg-recaptcha.js index 8c7925a61..681581a23 100644 --- a/src/assets/_project/_blocks/components/forms/qg-recaptcha.js +++ b/src/assets/_project/_blocks/components/forms/qg-recaptcha.js @@ -18,7 +18,7 @@ import keys from '../../data/qg-google-keys'; * @return {undefined} **/ init: function() { - let $feedbackForm = this.config.$feedbackForm; + const $feedbackForm = this.config.$feedbackForm; // let loadedRecaptcha = false; if ($feedbackForm.length > 0) { /** @@ -77,14 +77,14 @@ import keys from '../../data/qg-google-keys'; var self = this; grecaptcha.ready(() => { $('#qg-page-feedback-form').submit(function (event) { - let targetFormSubmit = $(this); + const targetFormSubmit = $(this); event.preventDefault(); if ($('#qg-page-feedback-form li.invalid').length <= 0) { - let $inputRecaptchaResponseElem = self.config.$feedbackForm.find('input[name="g-recaptcha-response"]'); - let postUrl = targetFormSubmit.attr('action'); - let requestMethod = targetFormSubmit.attr('method'); - let $successMsgContainer = $('.thankyou'); - grecaptcha.execute(self.feedbackGoogleRecaptchaApiKey(), {action: 'feedback'}) + const $inputRecaptchaResponseElem = self.config.$feedbackForm.find('input[name="g-recaptcha-response"]'); + const postUrl = targetFormSubmit.attr('action'); + const requestMethod = targetFormSubmit.attr('method'); + const $successMsgContainer = $('.thankyou'); + grecaptcha.execute(self.feedbackGoogleRecaptchaApiKey(), { action: 'feedback' }) .then(function (token) { if ($inputRecaptchaResponseElem.length > 0) { $inputRecaptchaResponseElem.val(token); @@ -169,7 +169,7 @@ import keys from '../../data/qg-google-keys'; v3Captcha: function (form, greptcha, key, action){ // console.log('v3 key: ' + key); try { - grecaptcha.execute(key, {action: action}) + grecaptcha.execute(key, { action: action }) .then(function (token) { if (greptcha.length > 0) { if ( @@ -193,7 +193,7 @@ import keys from '../../data/qg-google-keys'; * @return {undefined} **/ loadRecaptchaLib: function (){ - let self = this; + const self = this; /** * handles footer feedback recaptcha load **/ @@ -210,8 +210,8 @@ import keys from '../../data/qg-google-keys'; //enable recaptcha on form submits, load latest v3 version of recaptcha let v2Loaded = false; $('form[data-recaptcha="true"]').each(function () { - let manualSitekey = $(this).attr('data-sitekey'); - let manualAction = $(this).attr('data-action'); + const manualSitekey = $(this).attr('data-sitekey'); + const manualAction = $(this).attr('data-action'); if (manualSitekey !== undefined && manualAction !== undefined) { //v3 manual form $.getScript('https://www.google.com/recaptcha/api.js?render=' + manualSitekey, function (){ self.onloadRecaptcha(); @@ -237,7 +237,7 @@ import keys from '../../data/qg-google-keys'; * @return {undefined} **/ onloadRecaptcha: function(){ - let self = this; + const self = this; grecaptcha.ready(function () { //v2 Forms if (!self.config.loadedRecaptcha) { @@ -245,11 +245,11 @@ import keys from '../../data/qg-google-keys'; .find('input[type="submit"], button[type="submit"]') .on('click', e => { e.preventDefault(); - let subBtn = e.target; - let form = $(subBtn).parents('form'); - let $inputRecaptchaResponseElem = form.find('input[name="g-recaptcha-response"]'); - let manualSitekey = form.attr('data-sitekey'); - let manualAction = form.attr('data-action'); + const subBtn = e.target; + const form = $(subBtn).parents('form'); + const $inputRecaptchaResponseElem = form.find('input[name="g-recaptcha-response"]'); + const manualSitekey = form.attr('data-sitekey'); + const manualAction = form.attr('data-action'); if (manualSitekey !== undefined && manualAction !== undefined) { //v3 manual form self.v3Captcha(form, $inputRecaptchaResponseElem, manualSitekey, manualAction); } else if (manualAction !== undefined) { //v3 manual with feedback key but differnt action diff --git a/src/assets/_project/_blocks/components/misc/qg-license.js b/src/assets/_project/_blocks/components/misc/qg-license.js index 025892b96..760b94e62 100644 --- a/src/assets/_project/_blocks/components/misc/qg-license.js +++ b/src/assets/_project/_blocks/components/misc/qg-license.js @@ -12,87 +12,87 @@ A1 This function checks meta tag [name="DCTERMS.license] and then insert markup url: '//creativecommons.org/licenses/', imgSrc: '{{CDN}}/latest/images/licences/', types: { - 'by': { - 'name': 'Attribution', - 'imgName': 'by-80x15.png', - 'versions': { + by: { + name: 'Attribution', + imgName: 'by-80x15.png', + versions: { '3.0': { - 'title': '3.0 Australia (CC BY 3.0 AU)', - 'urlPath': 'by/3.0/au/', + title: '3.0 Australia (CC BY 3.0 AU)', + urlPath: 'by/3.0/au/', }, '4.0': { - 'title': '4.0 International (CC BY 4.0)', - 'urlPath': 'by/4.0/', + title: '4.0 International (CC BY 4.0)', + urlPath: 'by/4.0/', }, }, }, 'by-sa': { - 'name': 'Attribution-ShareAlike', - 'imgName': 'by-sa-80x15.png', - 'versions': { + name: 'Attribution-ShareAlike', + imgName: 'by-sa-80x15.png', + versions: { '3.0': { - 'title': '3.0 Australia (CC BY-SA 3.0 AU)', - 'urlPath': 'by-sa/3.0/au', + title: '3.0 Australia (CC BY-SA 3.0 AU)', + urlPath: 'by-sa/3.0/au', }, '4.0': { - 'title': '4.0 International (CC BY-SA 4.0)', - 'urlPath': 'by-sa/4.0/', + title: '4.0 International (CC BY-SA 4.0)', + urlPath: 'by-sa/4.0/', }, }, }, 'by-nd': { - 'name': 'Attribution-NoDerivatives', - 'imgName': 'by-nd-80x15.png', - 'versions': { + name: 'Attribution-NoDerivatives', + imgName: 'by-nd-80x15.png', + versions: { '3.0': { - 'title': '3.0 Australia (CC BY-ND 3.0 AU))', - 'urlPath': 'by-nd/3.0/au/', + title: '3.0 Australia (CC BY-ND 3.0 AU))', + urlPath: 'by-nd/3.0/au/', }, '4.0': { - 'title': '4.0 International (CC BY-ND 4.0)', - 'urlPath': 'by-nd/4.0/', + title: '4.0 International (CC BY-ND 4.0)', + urlPath: 'by-nd/4.0/', }, }, }, 'by-nc': { - 'name': 'Attribution-NonCommercial', - 'imgName': 'by-nc-80x15.png', - 'versions': { + name: 'Attribution-NonCommercial', + imgName: 'by-nc-80x15.png', + versions: { '3.0': { - 'title': '3.0 Australia (CC BY-NC 3.0 AU)', - 'urlPath': 'by-nc/3.0/au/', + title: '3.0 Australia (CC BY-NC 3.0 AU)', + urlPath: 'by-nc/3.0/au/', }, '4.0': { - 'title': '4.0 International (CC BY-NC 4.0)', - 'urlPath': 'by-nc/4.0/', + title: '4.0 International (CC BY-NC 4.0)', + urlPath: 'by-nc/4.0/', }, }, }, 'by-nc-sa': { - 'name': 'Attribution-NonCommercial-ShareAlike', - 'imgName': 'by-nc-sa-80x15.png', - 'versions': { + name: 'Attribution-NonCommercial-ShareAlike', + imgName: 'by-nc-sa-80x15.png', + versions: { '3.0': { - 'title': '3.0 Australia (CC BY-NC-SA 3.0 AU)', - 'urlPath': 'by-nc-sa/3.0/au/', + title: '3.0 Australia (CC BY-NC-SA 3.0 AU)', + urlPath: 'by-nc-sa/3.0/au/', }, '4.0': { - 'title': '4.0 International (CC BY-NC-SA 4.0)', - 'urlPath': 'by-nc-sa/4.0/', + title: '4.0 International (CC BY-NC-SA 4.0)', + urlPath: 'by-nc-sa/4.0/', }, }, }, 'by-nc-nd': { - 'name': 'Attribution-NonCommercial-NoDerivatives', - 'imgName': 'by-nc-nd-80x15.png', - 'versions': { + name: 'Attribution-NonCommercial-NoDerivatives', + imgName: 'by-nc-nd-80x15.png', + versions: { '3.0': { - 'title': '3.0 Australia (CC BY-NC-ND 3.0 AU)', - 'urlPath': 'by-nc-nd/3.0/au/', + title: '3.0 Australia (CC BY-NC-ND 3.0 AU)', + urlPath: 'by-nc-nd/3.0/au/', }, '4.0': { - 'title': '4.0 International (CC BY-NC-ND 4.0)', - 'urlPath': 'by-nc-nd/4.0/', + title: '4.0 International (CC BY-NC-ND 4.0)', + urlPath: 'by-nc-nd/4.0/', }, }, }, diff --git a/src/assets/_project/_blocks/components/opengraph/qg-opengraph.js b/src/assets/_project/_blocks/components/opengraph/qg-opengraph.js index 26bd78bf9..d2314ccb3 100644 --- a/src/assets/_project/_blocks/components/opengraph/qg-opengraph.js +++ b/src/assets/_project/_blocks/components/opengraph/qg-opengraph.js @@ -1,22 +1,22 @@ (function ($) { 'use strict'; const fields = [ - {property: 'meta[property="og:title"]'}, - {property: 'meta[property="og:description"]'}, - {property: 'meta[property="og:url"]'}, - {property: 'meta[property="og:type"]'}, - {property: 'meta[property="og:image"]'}, - {property: 'meta[name="twitter:card"]'}, - {property: 'meta[name="twitter:title"]'}, - {property: 'meta[name="twitter:description"]'}, - {property: 'meta[name="twitter:image"]'}, + { property: 'meta[property="og:title"]' }, + { property: 'meta[property="og:description"]' }, + { property: 'meta[property="og:url"]' }, + { property: 'meta[property="og:type"]' }, + { property: 'meta[property="og:image"]' }, + { property: 'meta[name="twitter:card"]' }, + { property: 'meta[name="twitter:title"]' }, + { property: 'meta[name="twitter:description"]' }, + { property: 'meta[name="twitter:image"]' }, ]; const openGraph = { init: function () { - let graphImg = '/assets/v4/latest/images/coat-of-arms/coa-thumbnail.png'; - let descriptionMeta = $('meta[name="DCTERMS.description"]').attr('content', ''); + const graphImg = '/assets/v4/latest/images/coat-of-arms/coa-thumbnail.png'; + const descriptionMeta = $('meta[name="DCTERMS.description"]').attr('content', ''); $.each(fields, function (key, val) { - let itemObj = $(val.property); + const itemObj = $(val.property); if (itemObj.length > 0) { //check if template not already populated by Matrix or authorer if (itemObj.attr('content') === '' || itemObj.attr('content') === undefined) { @@ -42,7 +42,7 @@ } } } else { - let head = $('head'); + const head = $('head'); head.append(itemObj); } }); diff --git a/src/assets/_project/_blocks/components/print/qg-print.js b/src/assets/_project/_blocks/components/print/qg-print.js index a3f99f471..04520e985 100644 --- a/src/assets/_project/_blocks/components/print/qg-print.js +++ b/src/assets/_project/_blocks/components/print/qg-print.js @@ -26,7 +26,7 @@ export class QgPrint { * @return {undefined} **/ onClickContentBtn() { - let self = this; + const self = this; if (self.$printContentLink.length > 0) { $(document).on('click', '.print-content-link', function(event) { event.preventDefault(); @@ -40,7 +40,7 @@ export class QgPrint { * @return {undefined} **/ onClickGuidePageBtn () { - let self = this; + const self = this; let numImagesLoaded = 0; // store content present inside the 'qg-primary-content' container @@ -62,7 +62,7 @@ export class QgPrint { self.$content.append(self.new_content); // check all images are there on the page or not (large images takes more time to load also depends on the network connection speed) const imageList = self.$content.find('img'); - let totalImages = imageList.length; + const totalImages = imageList.length; // filter out the content and make it ready for print self.$content.find('h1').not(':first').remove(); self.$content.find('.qg-print-guide p:contains("In this guide")').parent().remove(); @@ -73,7 +73,7 @@ export class QgPrint { self.$content.empty().append(self.current_content); } else { imageList.map(function() { - let tempSrc = this.src; + const tempSrc = this.src; this.onload = function () { numImagesLoaded++; if (numImagesLoaded >= totalImages) { @@ -93,7 +93,7 @@ export class QgPrint { * @return {undefined} **/ getRemotePages (pageContent) { - let self = this; + const self = this; $.ajax({ url: pageContent, data: {}, diff --git a/src/assets/_project/_blocks/components/quick-exit/qg-quick-exit.js b/src/assets/_project/_blocks/components/quick-exit/qg-quick-exit.js index d7fcccfb0..9113a4e64 100644 --- a/src/assets/_project/_blocks/components/quick-exit/qg-quick-exit.js +++ b/src/assets/_project/_blocks/components/quick-exit/qg-quick-exit.js @@ -53,7 +53,7 @@ export class QgQuickExit { * @return {undefined} **/ onbtnClick () { - let self = this; + const self = this; this.quickExitButton.onclick = function (e) { return self.quickExit(self.escapeSite); }; @@ -64,7 +64,7 @@ export class QgQuickExit { * @return {undefined} **/ onKeyDown (){ - let self = this; + const self = this; // add hotkey trigger document.addEventListener('keydown', function (e) { if (e.keyCode === self.hotkey) { diff --git a/src/assets/_project/_blocks/components/site-search/qg-funnelback-v16-refs.js b/src/assets/_project/_blocks/components/site-search/qg-funnelback-v16-refs.js index e746669ef..559d28df6 100644 --- a/src/assets/_project/_blocks/components/site-search/qg-funnelback-v16-refs.js +++ b/src/assets/_project/_blocks/components/site-search/qg-funnelback-v16-refs.js @@ -13,7 +13,7 @@ newValue = newValue.replace(new RegExp(pair[0], 'g'), pair[1]); if (originalValue.includes(pair[0])) { - let depReference = pair[1].includes('qgov~') ? `"${pair[0]}" collection,` : `"${pair[0]}"`; + const depReference = pair[1].includes('qgov~') ? `"${pair[0]}" collection,` : `"${pair[0]}"`; console.log( `SWE/Funnelback notice:\nThis application contains a reference to ${depReference} which is deprecated. It must be replaced with "${pair[1]}".\n`, ); diff --git a/src/assets/_project/_blocks/components/site-search/qg-search-minimize.js b/src/assets/_project/_blocks/components/site-search/qg-search-minimize.js index a23135ad8..9dc47e6ac 100644 --- a/src/assets/_project/_blocks/components/site-search/qg-search-minimize.js +++ b/src/assets/_project/_blocks/components/site-search/qg-search-minimize.js @@ -22,7 +22,7 @@ export class QgSearchMinimize { } addSearchToggleMarkup() { - let self = this; + const self = this; if ($('.' + self.searchStateContainer).length <= 0){ // 'Search all information & services' markup which on click show the global search form var searchStateContainerMarkup = `
@@ -35,7 +35,7 @@ export class QgSearchMinimize { } onServiceFinderSearchClick () { - let self = this; + const self = this; // toggle global search on interacting with the service finder search self.$multipleForms.find(self.$siteSearchInput).click(function() { if ($(window).width() >= self.smBreakPoint) { @@ -46,7 +46,7 @@ export class QgSearchMinimize { } onSearchStateContainerClick (){ - let self = this; + const self = this; // toggle global search form on click $('.' + self.searchStateContainer).on('click', function (){ $(this).hide(); @@ -55,7 +55,7 @@ export class QgSearchMinimize { } onResize() { - let self = this; + const self = this; let resizeTimer; $(window).resize(function(e) { clearTimeout(resizeTimer); @@ -76,4 +76,3 @@ export class QgSearchMinimize { }); } } - diff --git a/src/assets/_project/_blocks/components/site-search/qg-site-search.js b/src/assets/_project/_blocks/components/site-search/qg-site-search.js index f46c7e178..35199707c 100644 --- a/src/assets/_project/_blocks/components/site-search/qg-site-search.js +++ b/src/assets/_project/_blocks/components/site-search/qg-site-search.js @@ -6,8 +6,8 @@ $(function () { // var qgSiteSearch = { - 'fn': {}, - 'vars': {}, + fn: {}, + vars: {}, }; // @@ -66,9 +66,9 @@ $(function () { // Handle multiple events qgSiteSearch.fn.inputEventHandler = function (event) { - var eventType = event['type']; - var targetInput = $(event['target']); - var keyCode = event['keyCode']; + var eventType = event.type; + var targetInput = $(event.target); + var keyCode = event.keyCode; var inputValue = targetInput.val(); switch (eventType) { @@ -139,7 +139,7 @@ $(function () { qgSiteSearch.fn.keyboardNavigation = function (event) { var self = $(this); - var keyCode = event['keyCode']; + var keyCode = event.keyCode; var focusableList = self.parents('.qg-site-search__form').find($('.qg-search-concierge.show')).find('a, button'); var currentIndex = self.parents('.qg-site-search__form').attr('data-navindex'); @@ -160,7 +160,7 @@ $(function () { // Handle clearing the input field via button qgSiteSearch.fn.clearInputField = function (event) { - let inputTarget = event.target; + const inputTarget = event.target; var clearButton = $(this).parent().find($('.qg-search-close-concierge')); var searchInput = $(this).parent().find($('.qg-search-site__input')); searchInput.val(''); @@ -174,7 +174,7 @@ $(function () { // Handle selecting a suggestion qgSiteSearch.fn.searchSuggestionClick = function (event) { - var targetElement = $(event['currentTarget']); + var targetElement = $(event.currentTarget); var suggestionValue = targetElement.text(); var searchInput = $('.qg-search-site__input'); @@ -184,10 +184,10 @@ $(function () { // Handle background click to close concierge qgSiteSearch.fn.handleBodyClick = function (event, targetInput) { - let self = event.target; + const self = event.target; var targetSelector = '#qg-global-search-form'; - if ($(event['target']).closest(targetSelector).length === 0) { + if ($(event.target).closest(targetSelector).length === 0) { // Close the concierge panels qgSiteSearch.fn.closeConciergePanels(self); } @@ -209,10 +209,10 @@ $(function () { // Get example suggestions from Funnelback qgSiteSearch.fn.getExampleSuggestions = function (inputValue) { - var exampleResponse = [{'key': 'cancelled', 'disp': 'cancelled', 'disp_t': 'T', 'wt': '77.44', 'cat': '', 'cat_t': '', 'action': '', 'action_t': 'S'}, {'key': 'cancellation', 'disp': 'cancellation', 'disp_t': 'T', 'wt': '72.139', 'cat': '', 'cat_t': '', 'action': '', 'action_t': 'S'}, {'key': 'cancel', 'disp': 'cancel', 'disp_t': 'T', 'wt': '69.493', 'cat': '', 'cat_t': '', 'action': '', 'action_t': 'S'}, {'key': 'cancelling', 'disp': 'cancelling', 'disp_t': 'T', 'wt': '43.151', 'cat': '', 'cat_t': '', 'action': '', 'action_t': 'S'}, {'key': 'cancellations', 'disp': 'cancellations', 'disp_t': 'T', 'wt': '32.28', 'cat': '', 'cat_t': '', 'action': '', 'action_t': 'S'}, {'key': 'cancellation of membership', 'disp': 'cancellation of membership', 'disp_t': 'T', 'wt': '2.2', 'cat': '', 'cat_t': '', 'action': '', 'action_t': 'S'}, {'key': 'cancellation form', 'disp': 'fill out this cancellation form', 'disp_t': 'T', 'wt': '2', 'cat': '', 'cat_t': '', 'action': '', 'action_t': 'S'}, {'key': 'cancel a booking', 'disp': 'cancel a booking', 'disp_t': 'T', 'wt': '1.1', 'cat': '', 'cat_t': '', 'action': '', 'action_t': 'S'}, {'key': 'cancel a disability parking permit', 'disp': 'cancel a disability parking permit', 'disp_t': 'T', 'wt': '1', 'cat': '', 'cat_t': '', 'action': '', 'action_t': 'S'}, {'key': 'cancelling your registration', 'disp': 'cancelling your registration', 'disp_t': 'T', 'wt': '1', 'cat': '', 'cat_t': '', 'action': '', 'action_t': 'S'}]; + var exampleResponse = [{ key: 'cancelled', disp: 'cancelled', disp_t: 'T', wt: '77.44', cat: '', cat_t: '', action: '', action_t: 'S' }, { key: 'cancellation', disp: 'cancellation', disp_t: 'T', wt: '72.139', cat: '', cat_t: '', action: '', action_t: 'S' }, { key: 'cancel', disp: 'cancel', disp_t: 'T', wt: '69.493', cat: '', cat_t: '', action: '', action_t: 'S' }, { key: 'cancelling', disp: 'cancelling', disp_t: 'T', wt: '43.151', cat: '', cat_t: '', action: '', action_t: 'S' }, { key: 'cancellations', disp: 'cancellations', disp_t: 'T', wt: '32.28', cat: '', cat_t: '', action: '', action_t: 'S' }, { key: 'cancellation of membership', disp: 'cancellation of membership', disp_t: 'T', wt: '2.2', cat: '', cat_t: '', action: '', action_t: 'S' }, { key: 'cancellation form', disp: 'fill out this cancellation form', disp_t: 'T', wt: '2', cat: '', cat_t: '', action: '', action_t: 'S' }, { key: 'cancel a booking', disp: 'cancel a booking', disp_t: 'T', wt: '1.1', cat: '', cat_t: '', action: '', action_t: 'S' }, { key: 'cancel a disability parking permit', disp: 'cancel a disability parking permit', disp_t: 'T', wt: '1', cat: '', cat_t: '', action: '', action_t: 'S' }, { key: 'cancelling your registration', disp: 'cancelling your registration', disp_t: 'T', wt: '1', cat: '', cat_t: '', action: '', action_t: 'S' }]; var filteredResponse = exampleResponse.filter(function (suggestion) { - return suggestion['disp'].indexOf(inputValue.toLowerCase()) !== -1; + return suggestion.disp.indexOf(inputValue.toLowerCase()) !== -1; }); return filteredResponse; @@ -220,7 +220,7 @@ $(function () { // Get example service results from Funnelback qgSiteSearch.fn.getExampleServices = function () { - var exampleResponse = {'response': {'resultPacket': {'query': 'grants', 'results': [{'rank': 1, 'title': 'Grants and funding | Environment, land and water | Queensland Government', 'collection': 'qgov-web', 'metaData': {'license': 'https://creativecommons.org/licenses/by/4.0/', 'r': 'all', 'c': 'Grants and funding are available to support environmental programs in Queensland. This includes koala and marine life conservation, and nature refuges.', 'C': 'Grants and funding are available to support environmental programs in Queensland. This includes koala and marine life conservation, and nature refuges.', 's': 'Grant; funding; nature assist; koala; Everyones environment; Indigenous sea rangers; research; NatureAssist; Indigenous Sea Country Management Grants Program; Koala Rescue and Rehabilitation Grants Program; Koala Research Grant Program; koala', 'd': '2019-07-31', 't': 'Grants and funding | Environment, land and water | Queensland Government;Grants and funding | Environment and pollution management', 'e': 'Text', 'f': 'guidelines', 'j': 'https://www.qld.gov.au/environment/pollution/funding'}, 'liveUrl': 'https://www.qld.gov.au/environment/pollution/funding', 'clickTrackingUrl': '/s/redirect?collection=qld-gov&url=https%3A%2F%2Fwww.qld.gov.au%2Fenvironment%2Fpollution%2Ffunding&index_url=https%3A%2F%2Fwww.qld.gov.au%2Fenvironment%2Fpollution%2Ffunding&auth=qzUXw9sTwPwOdKvslCPbog&profile=qld_preview&rank=1&query=grants', 'explain': null, 'indexUrl': 'https://www.qld.gov.au/environment/pollution/funding'}, {'rank': 2, 'title': 'Funding and grants | Recreation, sport and arts | Queensland Government', 'collection': 'qgov-web', 'metaData': {'c': 'Find what funding and grants are available for young athletes and for clubs to upgrade sport and recreation facilities or equipment.', 'C': 'Find what funding and grants are available for young athletes and for clubs to upgrade sport and recreation facilities or equipment.', 'sprequired': 'yes', 'd': '2019-07-19', 'e': 'Collection', 'f': 'index', 'stype': 'apply-for-it', 'j': 'https://www.qld.gov.au/recreation/sports/funding', 'sid': 'P001085', 'sfinder': 'yes', 'license': 'https://creativecommons.org/licenses/by/4.0/', 'scategory': 'recreation-sports-and-arts', 'r': 'all', 's': 'Funding and grants; funding for young athletes; grants for young athletes; athlete scholarships; funding for kids and young people; funding for clubs and organisations; grants for clubs and organisations; funding to upgrade sport and recreation', 't': 'Funding and grants | Recreation, sport and arts | Queensland Government;Funding and grants | Sport', 'skioskonly': 'no'}, 'liveUrl': 'https://www.qld.gov.au/recreation/sports/funding', 'clickTrackingUrl': '/s/redirect?collection=qld-gov&url=https%3A%2F%2Fwww.qld.gov.au%2Frecreation%2Fsports%2Ffunding&index_url=https%3A%2F%2Fwww.qld.gov.au%2Frecreation%2Fsports%2Ffunding&auth=cM3gwHE6wlGI5UzFw2iszA&profile=qld_preview&rank=2&query=grants', 'explain': null, 'indexUrl': 'https://www.qld.gov.au/recreation/sports/funding'}, {'rank': 3, 'title': 'Everyones Environment grants program | Environment, land and water | Queensland Government', 'collection': 'qgov-web', 'metaData': {'c': 'This program provides funding for Queensland community groups with projects aimed at delivering practical actions for local environmental improvements.', 'C': 'This program provides funding for Queensland community groups with projects aimed at delivering practical actions for local environmental improvements.', 'sprequired': 'no', 'd': '2015-03-23', 'e': 'Text', 'f': 'guidelines', 'stype': 'find-it', 'j': 'https://www.qld.gov.au/environment/pollution/funding/everyones', 'sid': 'P000369', 'sfinder': 'yes', 'license': 'https://creativecommons.org/licenses/by/4.0/', 'scategory': 'environment-land-and-water', 'r': 'all', 's': 'Grants; everyone; environment; heritage; Queensland; funding', 't': 'Everyones Environment grants program | Environment, land and water | Queensland Government;Everyones Environment grants program | Grants and funding', 'skioskonly': 'no'}, 'liveUrl': 'https://www.qld.gov.au/environment/pollution/funding/everyones', 'clickTrackingUrl': '/s/redirect?collection=qld-gov&url=https%3A%2F%2Fwww.qld.gov.au%2Fenvironment%2Fpollution%2Ffunding%2Feveryones&index_url=https%3A%2F%2Fwww.qld.gov.au%2Fenvironment%2Fpollution%2Ffunding%2Feveryones&auth=QaZNQYwacyhU7xtVcs%2FPbg&profile=qld_preview&rank=3&query=grants', 'explain': null, 'indexUrl': 'https://www.qld.gov.au/environment/pollution/funding/everyones'}], 'error': null}, 'curator': {'exhibits': [{'titleHtml': 'Queensland Government Grants Finder', 'displayUrl': 'https://www.grants.services.qld.gov.au/#/', 'linkUrl': '/s/redirect?collection=qld-gov&url=https%3A%2F%2Fwww.grants.services.qld.gov.au%2F%23%2F&index_url=https%3A%2F%2Fwww.grants.services.qld.gov.au%2F%23%2F&auth=wEzza0HDD%2BGN4WIzBUq0%2Fg&profile=qld_preview&type=FP', 'descriptionHtml': 'The Queensland Government Grants Finder is a comprehensive list of our grants and funding programs.', 'additionalProperties': {'icon': 'fa-car fa-motorcycle fa-address-card', 'buttonText': 'Find out more', 'service': 'yes'}, 'category': ''}, {'titleHtml': 'North Queensland flood assistance', 'displayUrl': 'https://www.qld.gov.au/community/disasters-emergencies/queensland-disasters/fnq-monsoonal-trough', 'linkUrl': '/s/redirect?collection=qld-gov&url=https%3A%2F%2Fwww.qld.gov.au%2Fcommunity%2Fdisasters-emergencies%2Fqueensland-disasters%2Ffnq-monsoonal-trough&index_url=https%3A%2F%2Fwww.qld.gov.au%2Fcommunity%2Fdisasters-emergencies%2Fqueensland-disasters%2Ffnq-monsoonal-trough&auth=qbavFamsPcqvWK5M3INRmA&profile=qld_preview&type=FP', 'descriptionHtml': 'Personal hardship financial assistance has been activated for some communities at this time.', 'additionalProperties': {}, 'category': ''}, {'titleHtml': 'Change of address', 'displayUrl': 'https://www.change-of-address.services.qld.gov.au/', 'linkUrl': '/s/redirect?collection=qld-gov&url=https%3A%2F%2Fwww.change-of-address.services.qld.gov.au%2F&index_url=https%3A%2F%2Fwww.change-of-address.services.qld.gov.au%2F&auth=RrjhEMq01%2B%2BZwQhpwXAjPg&profile=qld_preview&type=FP', 'descriptionHtml': 'Use this online form to change your home and/or postal address online, rather than contacting multiple Queensland Government departments/services.', 'additionalProperties': {'icon': 'fa-car fa-motorcycle fa-address-card', 'service': 'yes'}, 'category': ''}]}}}; + var exampleResponse = { response: { resultPacket: { query: 'grants', results: [{ rank: 1, title: 'Grants and funding | Environment, land and water | Queensland Government', collection: 'qgov-web', metaData: { license: 'https://creativecommons.org/licenses/by/4.0/', r: 'all', c: 'Grants and funding are available to support environmental programs in Queensland. This includes koala and marine life conservation, and nature refuges.', C: 'Grants and funding are available to support environmental programs in Queensland. This includes koala and marine life conservation, and nature refuges.', s: 'Grant; funding; nature assist; koala; Everyones environment; Indigenous sea rangers; research; NatureAssist; Indigenous Sea Country Management Grants Program; Koala Rescue and Rehabilitation Grants Program; Koala Research Grant Program; koala', d: '2019-07-31', t: 'Grants and funding | Environment, land and water | Queensland Government;Grants and funding | Environment and pollution management', e: 'Text', f: 'guidelines', j: 'https://www.qld.gov.au/environment/pollution/funding' }, liveUrl: 'https://www.qld.gov.au/environment/pollution/funding', clickTrackingUrl: '/s/redirect?collection=qld-gov&url=https%3A%2F%2Fwww.qld.gov.au%2Fenvironment%2Fpollution%2Ffunding&index_url=https%3A%2F%2Fwww.qld.gov.au%2Fenvironment%2Fpollution%2Ffunding&auth=qzUXw9sTwPwOdKvslCPbog&profile=qld_preview&rank=1&query=grants', explain: null, indexUrl: 'https://www.qld.gov.au/environment/pollution/funding' }, { rank: 2, title: 'Funding and grants | Recreation, sport and arts | Queensland Government', collection: 'qgov-web', metaData: { c: 'Find what funding and grants are available for young athletes and for clubs to upgrade sport and recreation facilities or equipment.', C: 'Find what funding and grants are available for young athletes and for clubs to upgrade sport and recreation facilities or equipment.', sprequired: 'yes', d: '2019-07-19', e: 'Collection', f: 'index', stype: 'apply-for-it', j: 'https://www.qld.gov.au/recreation/sports/funding', sid: 'P001085', sfinder: 'yes', license: 'https://creativecommons.org/licenses/by/4.0/', scategory: 'recreation-sports-and-arts', r: 'all', s: 'Funding and grants; funding for young athletes; grants for young athletes; athlete scholarships; funding for kids and young people; funding for clubs and organisations; grants for clubs and organisations; funding to upgrade sport and recreation', t: 'Funding and grants | Recreation, sport and arts | Queensland Government;Funding and grants | Sport', skioskonly: 'no' }, liveUrl: 'https://www.qld.gov.au/recreation/sports/funding', clickTrackingUrl: '/s/redirect?collection=qld-gov&url=https%3A%2F%2Fwww.qld.gov.au%2Frecreation%2Fsports%2Ffunding&index_url=https%3A%2F%2Fwww.qld.gov.au%2Frecreation%2Fsports%2Ffunding&auth=cM3gwHE6wlGI5UzFw2iszA&profile=qld_preview&rank=2&query=grants', explain: null, indexUrl: 'https://www.qld.gov.au/recreation/sports/funding' }, { rank: 3, title: 'Everyones Environment grants program | Environment, land and water | Queensland Government', collection: 'qgov-web', metaData: { c: 'This program provides funding for Queensland community groups with projects aimed at delivering practical actions for local environmental improvements.', C: 'This program provides funding for Queensland community groups with projects aimed at delivering practical actions for local environmental improvements.', sprequired: 'no', d: '2015-03-23', e: 'Text', f: 'guidelines', stype: 'find-it', j: 'https://www.qld.gov.au/environment/pollution/funding/everyones', sid: 'P000369', sfinder: 'yes', license: 'https://creativecommons.org/licenses/by/4.0/', scategory: 'environment-land-and-water', r: 'all', s: 'Grants; everyone; environment; heritage; Queensland; funding', t: 'Everyones Environment grants program | Environment, land and water | Queensland Government;Everyones Environment grants program | Grants and funding', skioskonly: 'no' }, liveUrl: 'https://www.qld.gov.au/environment/pollution/funding/everyones', clickTrackingUrl: '/s/redirect?collection=qld-gov&url=https%3A%2F%2Fwww.qld.gov.au%2Fenvironment%2Fpollution%2Ffunding%2Feveryones&index_url=https%3A%2F%2Fwww.qld.gov.au%2Fenvironment%2Fpollution%2Ffunding%2Feveryones&auth=QaZNQYwacyhU7xtVcs%2FPbg&profile=qld_preview&rank=3&query=grants', explain: null, indexUrl: 'https://www.qld.gov.au/environment/pollution/funding/everyones' }], error: null }, curator: { exhibits: [{ titleHtml: 'Queensland Government Grants Finder', displayUrl: 'https://www.grants.services.qld.gov.au/#/', linkUrl: '/s/redirect?collection=qld-gov&url=https%3A%2F%2Fwww.grants.services.qld.gov.au%2F%23%2F&index_url=https%3A%2F%2Fwww.grants.services.qld.gov.au%2F%23%2F&auth=wEzza0HDD%2BGN4WIzBUq0%2Fg&profile=qld_preview&type=FP', descriptionHtml: 'The Queensland Government Grants Finder is a comprehensive list of our grants and funding programs.', additionalProperties: { icon: 'fa-car fa-motorcycle fa-address-card', buttonText: 'Find out more', service: 'yes' }, category: '' }, { titleHtml: 'North Queensland flood assistance', displayUrl: 'https://www.qld.gov.au/community/disasters-emergencies/queensland-disasters/fnq-monsoonal-trough', linkUrl: '/s/redirect?collection=qld-gov&url=https%3A%2F%2Fwww.qld.gov.au%2Fcommunity%2Fdisasters-emergencies%2Fqueensland-disasters%2Ffnq-monsoonal-trough&index_url=https%3A%2F%2Fwww.qld.gov.au%2Fcommunity%2Fdisasters-emergencies%2Fqueensland-disasters%2Ffnq-monsoonal-trough&auth=qbavFamsPcqvWK5M3INRmA&profile=qld_preview&type=FP', descriptionHtml: 'Personal hardship financial assistance has been activated for some communities at this time.', additionalProperties: {}, category: '' }, { titleHtml: 'Change of address', displayUrl: 'https://www.change-of-address.services.qld.gov.au/', linkUrl: '/s/redirect?collection=qld-gov&url=https%3A%2F%2Fwww.change-of-address.services.qld.gov.au%2F&index_url=https%3A%2F%2Fwww.change-of-address.services.qld.gov.au%2F&auth=RrjhEMq01%2B%2BZwQhpwXAjPg&profile=qld_preview&type=FP', descriptionHtml: 'Use this online form to change your home and/or postal address online, rather than contacting multiple Queensland Government departments/services.', additionalProperties: { icon: 'fa-car fa-motorcycle fa-address-card', service: 'yes' }, category: '' }] } } }; return exampleResponse; }; @@ -315,7 +315,7 @@ $(function () { suggestions.forEach(function (item) { suggestionsHTML += '
  • '; suggestionsHTML += ''; suggestionsHTML += '
  • '; }); @@ -352,14 +352,14 @@ $(function () { // Process suggested services and filter out bad results qgSiteSearch.fn.processServices = function (services) { - var allResults = services['response']['resultPacket']['results']; + var allResults = services.response.resultPacket.results; var serviceResults = []; var featuredService = null; - var curatorIndex = services['response']['curator']; + var curatorIndex = services.response.curator; // Look for curated results if (typeof (curatorIndex) !== 'undefined') { - var allCuratedResults = curatorIndex['exhibits']; + var allCuratedResults = curatorIndex.exhibits; if (typeof (allCuratedResults) !== 'undefined') { if (allCuratedResults.length > 0) { @@ -369,9 +369,9 @@ $(function () { // Process any additional exhibits for (var index = 1; index < allCuratedResults.length; index++) { var result = allCuratedResults[index]; - var additionalProperties = result['additionalProperties']; + var additionalProperties = result.additionalProperties; - if (additionalProperties['service'] === 'yes') { + if (additionalProperties.service === 'yes') { serviceResults.push(result); } } @@ -382,8 +382,8 @@ $(function () { // Look for services in standard results if (allResults.length > 0) { var filteredResults = allResults.filter(function (result) { - if (result['listMetadata'] != null && result['listMetadata']['sfinder'] != null) { - return result['listMetadata']['sfinder'][0] === 'yes'; + if (result.listMetadata != null && result.listMetadata.sfinder != null) { + return result.listMetadata.sfinder[0] === 'yes'; } else { return false; } @@ -409,18 +409,18 @@ $(function () { var serviceHTML = ''; if (featuredService) { - var title = featuredService['titleHtml']; - var linkURL = featuredService['displayUrl']; - var description = featuredService['descriptionHtml']; - var additionalProperties = featuredService['additionalProperties']; + var title = featuredService.titleHtml; + var linkURL = featuredService.displayUrl; + var description = featuredService.descriptionHtml; + var additionalProperties = featuredService.additionalProperties; serviceHTML = '
    '; serviceHTML += '
    '; serviceHTML += '

    ' + title + '

    '; // Check for icons - if (typeof (additionalProperties['icon']) !== 'undefined') { - var allIcons = additionalProperties['icon'].split(' '); + if (typeof (additionalProperties.icon) !== 'undefined') { + var allIcons = additionalProperties.icon.split(' '); var iconHTML = allIcons.map(function (icon) { return ''; @@ -432,8 +432,8 @@ $(function () { serviceHTML += '
    '; serviceHTML += '

    ' + description + '

    '; if (linkURL) { - if (additionalProperties['buttonText']) { - serviceHTML += '' + additionalProperties['buttonText'] + ''; + if (additionalProperties.buttonText) { + serviceHTML += '' + additionalProperties.buttonText + ''; } else { serviceHTML += 'Continue'; } @@ -456,17 +456,17 @@ $(function () { serviceHTML += '
      '; serviceResults.forEach(function (service) { - var serviceName = service['title']; - var serviceLink = service['liveUrl']; + var serviceName = service.title; + var serviceLink = service.liveUrl; if (typeof (serviceName) !== 'undefined') { serviceName = serviceName.split('|')[0].trim(); } else { - serviceName = service['titleHtml']; + serviceName = service.titleHtml; } if (typeof (serviceLink) === 'undefined') { - serviceLink = service['displayUrl']; + serviceLink = service.displayUrl; } serviceHTML += '
    • '; diff --git a/src/assets/_project/_blocks/components/social-media/qg-social-media.js b/src/assets/_project/_blocks/components/social-media/qg-social-media.js index 5f4fa7ca2..037c699be 100644 --- a/src/assets/_project/_blocks/components/social-media/qg-social-media.js +++ b/src/assets/_project/_blocks/components/social-media/qg-social-media.js @@ -8,8 +8,8 @@ }, init: function () { // twitter and facebook SDK scripts - let twitterSdkScript = 'platform.twitter.com/widgets.js'; - let facebookSdkScript = 'connect.facebook.net/en_GB/sdk.js#xfbml=1&version=v12.0'; + const twitterSdkScript = 'platform.twitter.com/widgets.js'; + const facebookSdkScript = 'connect.facebook.net/en_GB/sdk.js#xfbml=1&version=v12.0'; // check if twitter SDK script is not already on the page then load if (this.config.$twitterEl.length > 0 && $('script[src*="' + twitterSdkScript + '"]').length <= 0) { this.loadScript('script', 'twitter-wjs', twitterSdkScript); @@ -43,4 +43,3 @@ // initialize the social media qgSocialMedia.init(); }(jQuery)); - diff --git a/src/assets/_project/_blocks/layout/content/content-types/figure-credits-toggle.js b/src/assets/_project/_blocks/layout/content/content-types/figure-credits-toggle.js index c36ffcf4b..dcdf2bb43 100644 --- a/src/assets/_project/_blocks/layout/content/content-types/figure-credits-toggle.js +++ b/src/assets/_project/_blocks/layout/content/content-types/figure-credits-toggle.js @@ -19,6 +19,6 @@ $(() => { // decommission qg-cut-in warning if ($(figureElement).length) { - console.warn(`".qg-cut-in" and ".qg-cut-in-alt" is going to be deprecated in SWE library. Please replace ".qg-cut-in" or ".qg-cut-in-alt" with ".qg-fig". Please refer to https://qld-gov-au.github.io/web-template-release/components/images.html for more details.`); + console.warn('".qg-cut-in" and ".qg-cut-in-alt" is going to be deprecated in SWE library. Please replace ".qg-cut-in" or ".qg-cut-in-alt" with ".qg-fig". Please refer to https://qld-gov-au.github.io/web-template-release/components/images.html for more details.'); } }); diff --git a/src/assets/_project/_blocks/layout/footer/feedback-form.js b/src/assets/_project/_blocks/layout/footer/feedback-form.js index bf032467c..9d7b5ccf2 100644 --- a/src/assets/_project/_blocks/layout/footer/feedback-form.js +++ b/src/assets/_project/_blocks/layout/footer/feedback-form.js @@ -19,13 +19,13 @@ var feedbackForm = { * Add hidden inputs on a page **/ const hiddenInputs = { - 'franchise': franchise, + franchise: franchise, 'page-title': $(document).find('title').text(), 'page-url': window.location.href, 'page-referer': document.referrer, - 'rspUsrAgent': navigator.userAgent, - 'browserName': this.predictBrowserName().name + ' ' + this.predictBrowserName().version, - 'OS': navigator.platform, + rspUsrAgent: navigator.userAgent, + browserName: this.predictBrowserName().name + ' ' + this.predictBrowserName().version, + OS: navigator.platform, 'g-recaptcha-response': '', }; for (const prop in hiddenInputs) { @@ -76,11 +76,11 @@ var feedbackForm = { var matchBrowser = navigatorUserAgent.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []; if (/trident/i.test(matchBrowser[1])){ predictVersion = /\brv[ :]+(\d+)/g.exec(navigatorUserAgent) || []; - return {name: 'IE', version: (predictVersion[1] || '')}; + return { name: 'IE', version: (predictVersion[1] || '') }; } if (matchBrowser[1] === 'Chrome'){ predictVersion = navigatorUserAgent.match(/\bOPR|Edge\/(\d+)/); - if (predictVersion != null) { return {name: 'Edge', version: predictVersion[1]}; } + if (predictVersion != null) { return { name: 'Edge', version: predictVersion[1] }; } } matchBrowser = matchBrowser[2] ? [matchBrowser[1], matchBrowser[2]] : [navigator.appName, navigator.appVersion, '-?']; predictVersion = navigatorUserAgent.match(/version\/(\d+)/i); diff --git a/src/assets/_project/_blocks/layout/location/qg-location.js b/src/assets/_project/_blocks/layout/location/qg-location.js index 150b98c84..d643e5a83 100644 --- a/src/assets/_project/_blocks/layout/location/qg-location.js +++ b/src/assets/_project/_blocks/layout/location/qg-location.js @@ -9,15 +9,15 @@ $(function () { // var qgLocation = { - 'fn': {}, - 'vars': { - 'cookie_name': 'qg-location', - 'event_coordinates_set': 'qgLocationCoordsSet', - 'event_locality_set': 'qgLocationLocalitySet', - 'event_location_found': 'qgLocationFound', - 'event_location_cleared': 'qgLocationCleared', - 'error_message': '', - 'suburb_input': '', + fn: {}, + vars: { + cookie_name: 'qg-location', + event_coordinates_set: 'qgLocationCoordsSet', + event_locality_set: 'qgLocationLocalitySet', + event_location_found: 'qgLocationFound', + event_location_cleared: 'qgLocationCleared', + error_message: '', + suburb_input: '', }, }; @@ -85,17 +85,17 @@ $(function () { // Handle custom events function customEventHandler (event, eventName) { switch (eventName) { - case qgLocation['vars']['event_coordinates_set']: + case qgLocation.vars.event_coordinates_set: qgLocation.fn.getLocality(); break; - case qgLocation['vars']['event_locality_set']: + case qgLocation.vars.event_locality_set: qgLocation.fn.getCoordinates(); break; - case qgLocation['vars']['event_location_found']: + case qgLocation.vars.event_location_found: qgLocation.fn.setLocationName(); qgLocation.fn.initServiceCentre(); break; - case qgLocation['vars']['event_location_cleared']: + case qgLocation.vars.event_location_cleared: qgLocation.fn.resetLocationContainers(); break; } @@ -156,11 +156,11 @@ $(function () { // Keep location dropdown open the elements inside of the dropdown are clicked $('.header-location .dropdown-menu').click(function (e) { - var eventTarget = event['target']; - var targetElement = eventTarget['tagName'].toLowerCase(); + var eventTarget = event.target; + var targetElement = eventTarget.tagName.toLowerCase(); // Close suburb list if clicking outside - if (event['keyCode'] !== 40 && event['keyCode'] !== 38) { + if (event.keyCode !== 40 && event.keyCode !== 38) { qgLocation.fn.closeSuburbsIfOutside(e); } @@ -182,11 +182,11 @@ $(function () { qgLocation.fn.deletePositionData = function (event) { event.stopPropagation(); - var cookieName = qgLocation['vars']['cookie_name']; + var cookieName = qgLocation.vars.cookie_name; deleteCookie(cookieName); // Notify the rest of the page - $('body').trigger('custom', qgLocation['vars']['event_location_cleared']); + $('body').trigger('custom', qgLocation.vars.event_location_cleared); }; // Close the popup @@ -207,9 +207,9 @@ $(function () { // Manually search for location qgLocation.fn.initManualSearch = function (event) { - var inputField = event['target']; - var keyCode = event['keyCode']; - var inputValue = inputField['value'].toLowerCase(); + var inputField = event.target; + var keyCode = event.keyCode; + var inputValue = inputField.value.toLowerCase(); var numChars = inputValue.length; $('.qg-location-setter-form input[type=text]').removeClass('error'); @@ -221,7 +221,7 @@ $(function () { } } else if (numChars >= 3) { // Save the manual suburb input value - qgLocation['vars']['suburb_input'] = inputValue; + qgLocation.vars.suburb_input = inputValue; // Query the suburbs API qgLocation.fn.querySuburbsAPI(); @@ -232,10 +232,10 @@ $(function () { qgLocation.fn.keyboardNavigation = function (event) { var navIndex = parseInt($('.qg-location-setter-form input[type=text]').attr('data-navindex')); - if (event['keyCode'] === 40) { + if (event.keyCode === 40) { navIndex++; $('.qg-location-setter-autocomplete button')[navIndex].focus(); - } else if (event['keyCode'] === 38) { + } else if (event.keyCode === 38) { if (navIndex > 0) { navIndex--; $('.qg-location-setter-autocomplete button')[navIndex].focus(); @@ -250,7 +250,7 @@ $(function () { qgLocation.fn.getManualSuburbName = function (event) { event.stopPropagation(); - var suburbButton = event['target']; + var suburbButton = event.target; var suburbName = suburbButton.getAttribute('data-location'); var suburbFullArea = $(suburbButton).text(); @@ -315,7 +315,7 @@ $(function () { // Close suburb list if clicking outside qgLocation.fn.closeSuburbsIfOutside = function (event) { - if (!$(event['target']).closest('.qg-location-setter-form').length && event['view'] !== undefined) { + if (!$(event.target).closest('.qg-location-setter-form').length && event.view !== undefined) { $('.qg-location-setter-autocomplete').addClass('hide'); } }; @@ -326,14 +326,14 @@ $(function () { // Get local example of Google Maps API qgLocation.fn.getExampleLocation = function () { - var exampleResponse = [ { 'address_components': [ { 'long_name': 'Browning St near Boundary Rd, stop 5', 'short_name': 'Browning St near Boundary Rd, stop 5', 'types': [ 'establishment', 'point_of_interest', 'transit_station' ] }, { 'long_name': 'South Brisbane', 'short_name': 'South Brisbane', 'types': [ 'locality', 'political' ] }, { 'long_name': 'Brisbane City', 'short_name': 'Brisbane', 'types': [ 'administrative_area_level_2', 'political' ] }, { 'long_name': 'Queensland', 'short_name': 'QLD', 'types': [ 'administrative_area_level_1', 'political' ] }, { 'long_name': 'Australia', 'short_name': 'AU', 'types': [ 'country', 'political' ] }, { 'long_name': '4101', 'short_name': '4101', 'types': [ 'postal_code' ] } ], 'formatted_address': 'Browning St near Boundary Rd, stop 5, South Brisbane QLD 4101, Australia', 'geometry': { 'location': { 'lat': -27.477727, 'lng': 153.01314 }, 'location_type': 'GEOMETRIC_CENTER', 'viewport': { 'northeast': { 'lat': -27.4763780197085, 'lng': 153.0144889802915 }, 'southwest': { 'lat': -27.4790759802915, 'lng': 153.0117910197085 } } }, 'place_id': 'ChIJufdIyqBQkWsRlnW4qQxzN94', 'types': [ 'establishment', 'point_of_interest', 'transit_station' ] } ]; + var exampleResponse = [{ address_components: [{ long_name: 'Browning St near Boundary Rd, stop 5', short_name: 'Browning St near Boundary Rd, stop 5', types: ['establishment', 'point_of_interest', 'transit_station'] }, { long_name: 'South Brisbane', short_name: 'South Brisbane', types: ['locality', 'political'] }, { long_name: 'Brisbane City', short_name: 'Brisbane', types: ['administrative_area_level_2', 'political'] }, { long_name: 'Queensland', short_name: 'QLD', types: ['administrative_area_level_1', 'political'] }, { long_name: 'Australia', short_name: 'AU', types: ['country', 'political'] }, { long_name: '4101', short_name: '4101', types: ['postal_code'] }], formatted_address: 'Browning St near Boundary Rd, stop 5, South Brisbane QLD 4101, Australia', geometry: { location: { lat: -27.477727, lng: 153.01314 }, location_type: 'GEOMETRIC_CENTER', viewport: { northeast: { lat: -27.4763780197085, lng: 153.0144889802915 }, southwest: { lat: -27.4790759802915, lng: 153.0117910197085 } } }, place_id: 'ChIJufdIyqBQkWsRlnW4qQxzN94', types: ['establishment', 'point_of_interest', 'transit_station'] }]; return exampleResponse; }; // Get local example of service centres qgLocation.fn.getExampleServiceCentres = function () { - var exampleCentres = {'question': {'rawInputParameters': {'origin': ['-27.477413799999997;153.01329099999998']}}, 'response': {'resultPacket': {'results': [{'rank': 1, 'title': 'Asif AMin Justices of the Peace Branch', 'kmFromOrigin': 0.2, 'metaData': {'area': 'Brisbane City', 'hours': 'Monday to Friday, 10am-2pm|Mon,Mon,Tues,Tues,Wednes,Wednes,Thurs,Thurs,Fri,Fri,', 'agency': 'DJAG', 'address2': 'Level 6, 154 Melbourne Street', 'address1': 'See reception', 'viewpageassetid': '21806', 'postcode': '4101', 'type': 'Service', 's': 'Volunteer Justice of the Peace or Commissioner for Declarations', 't': 'Justices of the Peace Branch', 'phone': '1300 301 147', 'datasource': 'JP', 'suburb': 'SOUTH BRISBANE', 'location': '-27.4761712;153.0149019', 'id': '92'}}, {'rank': 2, 'title': 'Family Court Brisbane', 'kmFromOrigin': 1.2, 'metaData': {'area': 'Brisbane City', 'hours': 'Monday, Thursday and Friday 9am-2pm Note this service is for Family Court matters only. Hours of service may vary daily.|Mon,Mon,Thurs,Thurs,Fri,Fri,', 'agency': 'DJAG', 'address2': '(Entrance via Tank Street)', 'address1': 'Corner North Quay and Tank Streets', 'viewpageassetid': '21806', 'postcode': '4000', 'type': 'Service', 's': 'Hours of service vary daily, please phone before attending. Volunteer Justice of the Peace or Commissioner for Declarations', 't': 'Family Court Brisbane', 'datasource': 'JP', 'suburb': 'BRISBANE', 'location': '-27.468426;153.019921', 'id': '62'}}]}}}; + var exampleCentres = { question: { rawInputParameters: { origin: ['-27.477413799999997;153.01329099999998'] } }, response: { resultPacket: { results: [{ rank: 1, title: 'Asif AMin Justices of the Peace Branch', kmFromOrigin: 0.2, metaData: { area: 'Brisbane City', hours: 'Monday to Friday, 10am-2pm|Mon,Mon,Tues,Tues,Wednes,Wednes,Thurs,Thurs,Fri,Fri,', agency: 'DJAG', address2: 'Level 6, 154 Melbourne Street', address1: 'See reception', viewpageassetid: '21806', postcode: '4101', type: 'Service', s: 'Volunteer Justice of the Peace or Commissioner for Declarations', t: 'Justices of the Peace Branch', phone: '1300 301 147', datasource: 'JP', suburb: 'SOUTH BRISBANE', location: '-27.4761712;153.0149019', id: '92' } }, { rank: 2, title: 'Family Court Brisbane', kmFromOrigin: 1.2, metaData: { area: 'Brisbane City', hours: 'Monday, Thursday and Friday 9am-2pm Note this service is for Family Court matters only. Hours of service may vary daily.|Mon,Mon,Thurs,Thurs,Fri,Fri,', agency: 'DJAG', address2: '(Entrance via Tank Street)', address1: 'Corner North Quay and Tank Streets', viewpageassetid: '21806', postcode: '4000', type: 'Service', s: 'Hours of service vary daily, please phone before attending. Volunteer Justice of the Peace or Commissioner for Declarations', t: 'Family Court Brisbane', datasource: 'JP', suburb: 'BRISBANE', location: '-27.468426;153.019921', id: '62' } }] } } }; return exampleCentres; }; @@ -361,9 +361,9 @@ $(function () { // Get location coordinates from storage var geocoderQuery = { - 'location': { - 'lat': parseFloat(storedData['latitude']), - 'lng': parseFloat(storedData['longitude']), + location: { + lat: parseFloat(storedData.latitude), + lng: parseFloat(storedData.longitude), }, }; @@ -379,7 +379,7 @@ $(function () { // Check over all address matches for (var index = 0; index < jsonResponse.length; index++) { var address = jsonResponse[index]; - var addressComponents = address['address_components']; + var addressComponents = address.address_components; // Break out of the loop if a locality is found if (locality !== 'unknown') { @@ -389,11 +389,11 @@ $(function () { // Check over all address components for (var componentIndex = 0; componentIndex < addressComponents.length; componentIndex++) { var component = addressComponents[componentIndex]; - var componentTypes = component['types']; + var componentTypes = component.types; // Find the locality component if (componentTypes.indexOf(targetType) !== -1) { - locality = component['short_name']; + locality = component.short_name; break; } } @@ -409,13 +409,13 @@ $(function () { qgLocation.fn.getCoordinates = function () { var storedData = qgLocation.fn.getStoredLocation(); - if (typeof (storedData['latitude']) === 'undefined') { - var address = storedData['address']; + if (typeof (storedData.latitude) === 'undefined') { + var address = storedData.address; if (address) { // Get location coordinates from storage var geocoderQuery = { - 'address': storedData['address'], + address: storedData.address, }; // Query the Google Maps API with location coordinates @@ -423,7 +423,7 @@ $(function () { } } else { // Notify the rest of the page - $('body').trigger('custom', qgLocation['vars']['event_location_found']); + $('body').trigger('custom', qgLocation.vars.event_location_found); } }; @@ -434,10 +434,10 @@ $(function () { // Check over all address matches for (var index = 0; index < jsonResponse.length; index++) { var address = jsonResponse[index]; - var geometry = address['geometry']; + var geometry = address.geometry; if (typeof (geometry) !== 'undefined') { - coordinates = geometry['location']; + coordinates = geometry.location; if (typeof (coordinates) !== 'undefined') { break; @@ -459,12 +459,12 @@ $(function () { qgLocation.fn.querySuburbsAPI = function () { var suburbsURL = 'https://gisservices.information.qld.gov.au/arcgis/rest/services/PlanningCadastre/LandParcelPropertyFramework/MapServer/19/query'; var suburbsParams = { - 'f': 'json', - 'where': 'ADMINAREANAME+%3C%3E+%27Null%27', - 'returnGeometry': 'false', - 'spatialRel': 'esriSpatialRelIntersects', - 'outFields': 'ADMINAREANAME', - 'orderByFields': 'ADMINAREANAME%20ASC', + f: 'json', + where: 'ADMINAREANAME+%3C%3E+%27Null%27', + returnGeometry: 'false', + spatialRel: 'esriSpatialRelIntersects', + outFields: 'ADMINAREANAME', + orderByFields: 'ADMINAREANAME%20ASC', }; // Construct query params from data @@ -485,26 +485,26 @@ $(function () { // Check the ArcGIS API qgLocation.fn.processSuburbsData = function (jsonResponse) { var locationList = []; - var userSuburb = qgLocation['vars']['suburb_input']; + var userSuburb = qgLocation.vars.suburb_input; if (jsonResponse.hasOwnProperty('features')) { // Add each suburb to the location list - jsonResponse['features'].forEach(function (object) { - var sourceName = object['attributes']['ADMINAREANAME'] || object['attributes']['adminareaname']; + jsonResponse.features.forEach(function (object) { + var sourceName = object.attributes.ADMINAREANAME || object.attributes.adminareaname; sourceName = sourceName.toLowerCase(); var suburbLGA = titleCase(sourceName); var suburbObject = { - 'name': sourceName, - 'name_friendly': suburbLGA, - 'name_formatted': suburbLGA, - 'suburb': suburbLGA.split(',')[0], + name: sourceName, + name_friendly: suburbLGA, + name_formatted: suburbLGA, + suburb: suburbLGA.split(',')[0], }; // Filter out the suburb if user input exists if (userSuburb !== '') { // Compare values if (sourceName.indexOf(userSuburb) === 0) { - suburbObject['name_formatted'] = getBoldText(userSuburb, suburbLGA); + suburbObject.name_formatted = getBoldText(userSuburb, suburbLGA); locationList.push(suburbObject); } @@ -534,9 +534,9 @@ $(function () { var scriptElement = document.createElement('script'); // Populate tag - scriptElement['type'] = 'text/javascript'; - scriptElement['src'] = scriptURL; - scriptElement['id'] = scriptID; + scriptElement.type = 'text/javascript'; + scriptElement.src = scriptURL; + scriptElement.id = scriptID; // Insert into the DOM document.querySelector('body').appendChild(scriptElement); @@ -565,13 +565,13 @@ $(function () { var dataEvent = ''; // Check for coordinates - if (typeof (storedData['latitude']) !== 'undefined') { - if (storedData['locality'] !== 'unknown') { + if (typeof (storedData.latitude) !== 'undefined') { + if (storedData.locality !== 'unknown') { // All location data found, update the page - dataEvent = qgLocation['vars']['event_locality_set']; + dataEvent = qgLocation.vars.event_locality_set; } else { // Coordinates exist, find locality - dataEvent = qgLocation['vars']['event_coordinates_set']; + dataEvent = qgLocation.vars.event_coordinates_set; } } @@ -588,7 +588,7 @@ $(function () { // Check for saved location qgLocation.fn.getStoredLocation = function () { - var cookieName = qgLocation['vars']['cookie_name']; + var cookieName = qgLocation.vars.cookie_name; var storedData = getCookie(cookieName); if (storedData !== '') { @@ -601,7 +601,7 @@ $(function () { // The user has allowed geolocation qgLocation.fn.processPositionData = function (response) { - var positionData = response['coords']; + var positionData = response.coords; qgLocation.fn.setPositionData(positionData); closeDropdown(); @@ -609,29 +609,29 @@ $(function () { // The user has blocked geolocation qgLocation.fn.failure = function (response) { - var responseMessage = response['message']; + var responseMessage = response.message; - qgLocation['vars']['error_message'] = responseMessage; + qgLocation.vars.error_message = responseMessage; }; // Save the position data to the browser qgLocation.fn.setPositionData = function (positionData) { var location = { - 'latitude': positionData['latitude'], - 'longitude': positionData['longitude'], - 'locality': 'unknown', + latitude: positionData.latitude, + longitude: positionData.longitude, + locality: 'unknown', }; // Save to cookie qgLocation.fn.saveLocationCookie(location); // Notify the rest of the page - $('body').trigger('custom', qgLocation['vars']['event_coordinates_set']); + $('body').trigger('custom', qgLocation.vars.event_coordinates_set); }; // Save data to the location cookie qgLocation.fn.saveLocationCookie = function (cookieData) { - var cookieName = qgLocation['vars']['cookie_name']; + var cookieName = qgLocation.vars.cookie_name; var cookieValue = JSON.stringify(cookieData); var daysActive = 7; @@ -645,22 +645,22 @@ $(function () { // Handle no cookie present if (storedData === null) { storedData = { - 'locality': 'unknown', + locality: 'unknown', }; } // Handle optional address value if (address) { - storedData['address'] = address; + storedData.address = address; } - storedData['locality'] = locality; + storedData.locality = locality; // Save to cookie qgLocation.fn.saveLocationCookie(storedData); // Notify the rest of the page - $('body').trigger('custom', qgLocation['vars']['event_locality_set']); + $('body').trigger('custom', qgLocation.vars.event_locality_set); }; // Save the suburb coordinates @@ -673,14 +673,14 @@ $(function () { } // Data is processed differently depending on environment - storedData['latitude'] = coordinates.lat(); - storedData['longitude'] = coordinates.lng(); + storedData.latitude = coordinates.lat(); + storedData.longitude = coordinates.lng(); // Save to cookie qgLocation.fn.saveLocationCookie(storedData); // Notify the rest of the page - $('body').trigger('custom', qgLocation['vars']['event_location_found']); + $('body').trigger('custom', qgLocation.vars.event_location_found); }; // Populate the suburb suggestion list @@ -696,8 +696,8 @@ $(function () { suggestionHTML = '
        '; allSuburbs.forEach(function (suburbData) { - var suburbName = suburbData['suburb']; - var suburbHTML = suburbData['name_formatted']; + var suburbName = suburbData.suburb; + var suburbHTML = suburbData.name_formatted; suggestionHTML += '
      • '; }); @@ -714,7 +714,7 @@ $(function () { // Visually set the location data qgLocation.fn.setLocationName = function () { var storedData = qgLocation.fn.getStoredLocation(); - var locality = storedData['locality']; + var locality = storedData.locality; // Update header $('.header-location .dropdown-toggle').attr('aria-label', 'Your location is ' + locality); @@ -742,7 +742,7 @@ $(function () { } // Query Funnelback with location and service centre types - var locationOrigin = storedData['latitude'] + ',' + storedData['longitude']; + var locationOrigin = storedData.latitude + ',' + storedData.longitude; var targetURL = serviceCentreModule.attr('data-centres'); var queryMetadata = centreTypes.join('+'); @@ -758,7 +758,7 @@ $(function () { // Process the service centre response qgLocation.fn.findServiceCentre = function (jsonResponse) { - var results = jsonResponse['response']['resultPacket']['results']; + var results = jsonResponse.response.resultPacket.results; var centreData = null; var centreContainer = $('.qg-service-centre__results'); var centreHTML = ''; @@ -767,15 +767,15 @@ $(function () { centreData = results[0]; } - if (centreData && centreData['listMetadata']) { - var centreName = centreData['listMetadata']['t']; - var centreID = centreData['listMetadata']['id']; - var centreDistance = centreData['kmFromOrigin']; - var centreAddress1 = centreData['listMetadata']['address1']; - var centreAddress2 = centreData['listMetadata']['address2']; + if (centreData && centreData.listMetadata) { + var centreName = centreData.listMetadata.t; + var centreID = centreData.listMetadata.id; + var centreDistance = centreData.kmFromOrigin; + var centreAddress1 = centreData.listMetadata.address1; + var centreAddress2 = centreData.listMetadata.address2; // Build URL - var centreType = centreData['listMetadata']['datasource']; + var centreType = centreData.listMetadata.datasource; if (centreType !== undefined) { centreType = centreType[0].toLowerCase(); } @@ -873,4 +873,3 @@ $(function () { $('body').on('click', '.qg-location-setter-close', qgLocation.fn.closeServiceCentre); $('body').on('keydown', '.qg-location-setter-autocomplete button', qgLocation.fn.keyboardNavigation); }); - diff --git a/src/assets/_project/_blocks/layout/section-nav/qg-section-nav.js b/src/assets/_project/_blocks/layout/section-nav/qg-section-nav.js index b307f1629..7bce02656 100644 --- a/src/assets/_project/_blocks/layout/section-nav/qg-section-nav.js +++ b/src/assets/_project/_blocks/layout/section-nav/qg-section-nav.js @@ -33,9 +33,9 @@ var activeSideNav = (function () { var currentPageTitle = getCurrentTitle(); if ($('.guide-sub-nav').length > 0){ // In case of Guide Navigation, sub heading are in H2 tags. - let contentHeading = $.trim($('h2', '#qg-primary-content').eq(0).text()); + const contentHeading = $.trim($('h2', '#qg-primary-content').eq(0).text()); $('.guide-sub-nav >li').each(function () { - let guideNavHeading = $(this).clone().find('.page-number').remove().end().text().trim(); + const guideNavHeading = $(this).clone().find('.page-number').remove().end().text().trim(); if (refineText(guideNavHeading) === refineText(contentHeading)) { $(this).find('a').addClass('active').removeAttr('href'); } diff --git a/src/assets/_project/_blocks/layout/section-nav/qg-step-nav.js b/src/assets/_project/_blocks/layout/section-nav/qg-step-nav.js index 23a74f762..1afa9505d 100644 --- a/src/assets/_project/_blocks/layout/section-nav/qg-step-nav.js +++ b/src/assets/_project/_blocks/layout/section-nav/qg-step-nav.js @@ -1,5 +1,5 @@ import breakpoints from '../../utils/breakpoints.js'; -let stepNav = { +const stepNav = { config: { $guideSubNav: $('.qg-section-nav .guide-sub-nav'), $qgSectionNav: $('.qg-section-nav', '.qg-section-nav'), @@ -39,7 +39,7 @@ let stepNav = { if (($(window).width() < breakpoints.bsMd)) { if ($('#step-nav .guide-sub-nav').length === 0) { this.config.$heading.after(this.view(this.getActiveNav(), this.countListItems())); - let $getSubNav = this.config.$guideSubNav.clone(); + const $getSubNav = this.config.$guideSubNav.clone(); $('#step-nav li').append($getSubNav); } $('#step-nav').hover(() => { diff --git a/src/assets/_project/_blocks/legacy/bootstrap-accessibility.js b/src/assets/_project/_blocks/legacy/bootstrap-accessibility.js index bc8919400..196de1438 100644 --- a/src/assets/_project/_blocks/legacy/bootstrap-accessibility.js +++ b/src/assets/_project/_blocks/legacy/bootstrap-accessibility.js @@ -25,197 +25,194 @@ * ======================================================================== */ (function($) { - "use strict"; - - var uniqueId = function(prefix) { - return (prefix || 'ui-id') + '-' + Math.floor((Math.random()*1000)+1) - } - - // Alert Extension - // =============================== - - $('.alert').attr('role', 'alert') - $('.close').removeAttr('aria-hidden').wrapInner('').append('Close') + 'use strict'; + + var uniqueId = function(prefix) { + return (prefix || 'ui-id') + '-' + Math.floor((Math.random() * 1000) + 1); + }; + + // Alert Extension + // =============================== + + $('.alert').attr('role', 'alert'); + $('.close').removeAttr('aria-hidden').wrapInner('').append('Close'); + + // TOOLTIP Extension + // =============================== + + var showTooltip = $.fn.tooltip.Constructor.prototype.show; + var hideTooltip = $.fn.tooltip.Constructor.prototype.hide; + + $.fn.tooltip.Constructor.prototype.show = function () { + showTooltip.apply(this, arguments); + var $tip = this.tip(); + var tooltipID = $tip.attr('id') || uniqueId('ui-tooltip'); + $tip.attr({ role: 'tooltip', id: tooltipID }); + this.$element.attr('aria-describedby', tooltipID); + }; + + $.fn.tooltip.Constructor.prototype.hide = function () { + hideTooltip.apply(this, arguments); + removeMultiValAttributes(this.$element, 'aria-describedby', this.tip().attr('id')); + return this; + }; + + // Popover Extension + // =============================== + var showPopover = $.fn.popover.Constructor.prototype.setContent; + var hideTPopover = $.fn.popover.Constructor.prototype.hide; + + $.fn.popover.Constructor.prototype.setContent = function(){ + showPopover.apply(this, arguments); + var $tip = this.tip(); + var tooltipID = $tip.attr('id') || uniqueId('ui-tooltip'); + $tip.attr({ role: 'alert', id: tooltipID }); + this.$element.attr('aria-describedby', tooltipID); + this.$element.focus(); + }; + $.fn.popover.Constructor.prototype.hide = function(){ + hideTooltip.apply(this, arguments); + removeMultiValAttributes(this.$element, 'aria-describedby', this.tip().attr('id')); + }; + + //Modal Extension + $('.modal-dialog').attr({ role: 'document' }); + var modalhide = $.fn.modal.Constructor.prototype.hide; + $.fn.modal.Constructor.prototype.hide = function(){ + var modalOpener = this.$element.parent().find('[data-target="#' + this.$element.attr('id') + '"]'); + modalhide.apply(this, arguments); + modalOpener.focus(); + }; + + // DROPDOWN Extension + // =============================== + + var toggle = '[data-toggle=dropdown]'; + var $par; + var firstItem; + var focusDelay = 200; + var menus = $(toggle).parent().find('ul').attr('role', 'menu'); + var lis = menus.find('li').attr('role', 'presentation'); + + lis.find('a').attr({ role: 'menuitem', tabIndex: '-1' }); + $(toggle).attr({ 'aria-haspopup': 'true', 'aria-expanded': 'false' }); + + $(toggle).parent().on('shown.bs.dropdown', function(e){ + $par = $(this); + var $toggle = $par.find(toggle); + $toggle.attr('aria-expanded', 'true'); + + setTimeout(function(){ + firstItem = $('.dropdown-menu [role=menuitem]:visible', $par)[0]; + try { firstItem.focus(); } catch (ex) {} + }, focusDelay); + }); + + $(toggle).parent().on('hidden.bs.dropdown', function(e){ + $par = $(this); + var $toggle = $par.find(toggle); + $toggle.attr('aria-expanded', 'false'); + }); + + //Adding Space Key Behaviour, opens on spacebar + $.fn.dropdown.Constructor.prototype.keydown = function (e) { + var $par, + firstItem; + if (!/(32)/.test(e.keyCode)) return; + $par = $(this).parent(); + $(this).trigger('click'); + e.preventDefault() && e.stopPropagation(); + }; + + $(document) + .on('focusout.dropdown.data-api', '.dropdown-menu', function(e){ + var $this = $(this); + var that = this; + setTimeout(function() { + if (!$.contains(that, document.activeElement)){ + $this.parent().removeClass('open'); + $this.parent().find('[data-toggle=dropdown]').attr('aria-expanded', 'false'); + } + }, 150); + }) + .on('keydown.bs.dropdown.data-api', toggle + ', [role=menu]', $.fn.dropdown.Constructor.prototype.keydown); - // TOOLTIP Extension - // =============================== + // Tab Extension + // =============================== - var showTooltip = $.fn.tooltip.Constructor.prototype.show - , hideTooltip = $.fn.tooltip.Constructor.prototype.hide + var $tablist = $('.nav-tabs'); + var $lis = $tablist.children('li'); + var $tabs = $tablist.find('[data-toggle="tab"], [data-toggle="pill"]'); - $.fn.tooltip.Constructor.prototype.show = function () { - showTooltip.apply(this, arguments) - var $tip = this.tip() - , tooltipID = $tip.attr('id') || uniqueId('ui-tooltip') - $tip.attr({'role':'tooltip','id' : tooltipID}) - this.$element.attr('aria-describedby', tooltipID) - } + $tablist.attr('role', 'tablist'); + $lis.attr('role', 'presentation'); + $tabs.attr('role', 'tab'); - $.fn.tooltip.Constructor.prototype.hide = function () { - hideTooltip.apply(this, arguments) - removeMultiValAttributes(this.$element, 'aria-describedby', this.tip().attr('id')) - return this - } + $tabs.each(function(index) { + var tabpanel = $($(this).attr('href')); + var tab = $(this); + var tabid = tab.attr('id') || uniqueId('ui-tab'); - // Popover Extension - // =============================== - var showPopover = $.fn.popover.Constructor.prototype.setContent - , hideTPopover = $.fn.popover.Constructor.prototype.hide - - $.fn.popover.Constructor.prototype.setContent = function(){ - showPopover.apply(this, arguments) - var $tip = this.tip() - , tooltipID = $tip.attr('id') || uniqueId('ui-tooltip') - $tip.attr({'role':'alert','id' : tooltipID}) - this.$element.attr('aria-describedby', tooltipID) - this.$element.focus() - } - $.fn.popover.Constructor.prototype.hide = function(){ - hideTooltip.apply(this, arguments) - removeMultiValAttributes(this.$element, 'aria-describedby', this.tip().attr('id')) - } + tab.attr('id', tabid); - //Modal Extension - $('.modal-dialog').attr( {'role' : 'document'}) - var modalhide = $.fn.modal.Constructor.prototype.hide - $.fn.modal.Constructor.prototype.hide = function(){ - var modalOpener = this.$element.parent().find('[data-target="#' + this.$element.attr('id') + '"]') - modalhide.apply(this, arguments) - modalOpener.focus() + if (tab.parent().hasClass('active')){ + tab.attr({ tabIndex: '0', 'aria-expanded': 'true', 'aria-selected': 'true', 'aria-controls': tab.attr('href').substr(1) }); + tabpanel.attr({ role: 'tabpanel', tabIndex: '0', 'aria-hidden': 'false', 'aria-labelledby': tabid }); + } else { + tab.attr({ tabIndex: '-1', 'aria-expanded': 'false', 'aria-selected': 'false', 'aria-controls': tab.attr('href').substr(1) }); + tabpanel.attr({ role: 'tabpanel', tabIndex: '-1', 'aria-hidden': 'true', 'aria-labelledby': tabid }); } + }); - // DROPDOWN Extension - // =============================== + $.fn.tab.Constructor.prototype.keydown = function (e) { + var $this = $(this); + var $items; + var $ul = $this.closest('ul[role=tablist] '); + var index; + var k = e.which || e.keyCode; - var toggle = '[data-toggle=dropdown]' - , $par - , firstItem - , focusDelay = 200 - , menus = $(toggle).parent().find('ul').attr('role','menu') - , lis = menus.find('li').attr('role','presentation') + $this = $(this); + if (!/(37|38|39|40)/.test(k)) return; - lis.find('a').attr({'role':'menuitem', 'tabIndex':'-1'}) - $(toggle).attr({ 'aria-haspopup':'true', 'aria-expanded': 'false'}) + $items = $ul.find('[role=tab]:visible'); + index = $items.index($items.filter(':focus')); - $(toggle).parent().on('shown.bs.dropdown',function(e){ - $par = $(this) - var $toggle = $par.find(toggle) - $toggle.attr('aria-expanded','true') + if (k == 38 || k == 37) index--; // up & left + if (k == 39 || k == 40) index++; // down & right - setTimeout(function(){ - firstItem = $('.dropdown-menu [role=menuitem]:visible', $par)[0] - try{ firstItem.focus()} catch(ex) {} - }, focusDelay) - }) + if (index < 0) index = $items.length - 1; + if (index == $items.length) index = 0; - $(toggle).parent().on('hidden.bs.dropdown',function(e){ - $par = $(this) - var $toggle = $par.find(toggle) - $toggle.attr('aria-expanded','false') - }) - - //Adding Space Key Behaviour, opens on spacebar - $.fn.dropdown.Constructor.prototype.keydown = function (e) { - var $par - , firstItem - if (!/(32)/.test(e.keyCode)) return - $par = $(this).parent() - $(this).trigger ("click") - e.preventDefault() && e.stopPropagation() + var nextTab = $items.eq(index); + if (nextTab.attr('role') === 'tab'){ + nextTab.tab('show') //Comment this line for dynamically loaded tabPabels, to save Ajax requests on arrow key navigation + .focus(); } + // nextTab.focus() - $(document) - .on('focusout.dropdown.data-api', '.dropdown-menu', function(e){ - var $this = $(this) - , that = this - setTimeout(function() { - if(!$.contains(that, document.activeElement)){ - $this.parent().removeClass('open') - $this.parent().find('[data-toggle=dropdown]').attr('aria-expanded','false') - } - }, 150) - }) - .on('keydown.bs.dropdown.data-api', toggle + ', [role=menu]' , $.fn.dropdown.Constructor.prototype.keydown) - - - // Tab Extension - // =============================== - - var $tablist = $('.nav-tabs') - , $lis = $tablist.children('li') - , $tabs = $tablist.find('[data-toggle="tab"], [data-toggle="pill"]') - - $tablist.attr('role', 'tablist') - $lis.attr('role', 'presentation') - $tabs.attr('role', 'tab') - - $tabs.each(function( index ) { - var tabpanel = $($(this).attr('href')) - , tab = $(this) - , tabid = tab.attr('id') || uniqueId('ui-tab') - - tab.attr('id', tabid) - - if(tab.parent().hasClass('active')){ - tab.attr( { 'tabIndex' : '0', 'aria-expanded' : 'true', 'aria-selected' : 'true', 'aria-controls': tab.attr('href').substr(1) } ) - tabpanel.attr({ 'role' : 'tabpanel', 'tabIndex' : '0', 'aria-hidden' : 'false', 'aria-labelledby':tabid }) - }else{ - tab.attr( { 'tabIndex' : '-1', 'aria-expanded' : 'false', 'aria-selected' : 'false', 'aria-controls': tab.attr('href').substr(1) } ) - tabpanel.attr( { 'role' : 'tabpanel', 'tabIndex' : '-1', 'aria-hidden' : 'true', 'aria-labelledby':tabid } ) - } - }) - - $.fn.tab.Constructor.prototype.keydown = function (e) { - var $this = $(this) - , $items - , $ul = $this.closest('ul[role=tablist] ') - , index - , k = e.which || e.keyCode - - $this = $(this) - if (!/(37|38|39|40)/.test(k)) return - - $items = $ul.find('[role=tab]:visible') - index = $items.index($items.filter(':focus')) - - if (k == 38 || k == 37) index-- // up & left - if (k == 39 || k == 40) index++ // down & right - - - if(index < 0) index = $items.length -1 - if(index == $items.length) index = 0 - - var nextTab = $items.eq(index) - if(nextTab.attr('role') ==='tab'){ - - nextTab.tab('show') //Comment this line for dynamically loaded tabPabels, to save Ajax requests on arrow key navigation - .focus() - } - // nextTab.focus() - - e.preventDefault() - e.stopPropagation() - } + e.preventDefault(); + e.stopPropagation(); + }; - $(document).on('keydown.tab.data-api','[data-toggle="tab"], [data-toggle="pill"]' , $.fn.tab.Constructor.prototype.keydown) + $(document).on('keydown.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', $.fn.tab.Constructor.prototype.keydown); - var tabactivate = $.fn.tab.Constructor.prototype.activate; - $.fn.tab.Constructor.prototype.activate = function (element, container, callback) { - var $active = container.find('> .active') - $active.find('[data-toggle=tab]').attr({ 'tabIndex' : '-1','aria-selected' : false,'aria-expanded' : false }) - $active.filter('.tab-pane').attr({ 'aria-hidden' : true,'tabIndex' : '-1' }) + var tabactivate = $.fn.tab.Constructor.prototype.activate; + $.fn.tab.Constructor.prototype.activate = function (element, container, callback) { + var $active = container.find('> .active'); + $active.find('[data-toggle=tab]').attr({ tabIndex: '-1', 'aria-selected': false, 'aria-expanded': false }); + $active.filter('.tab-pane').attr({ 'aria-hidden': true, tabIndex: '-1' }); - tabactivate.apply(this, arguments) + tabactivate.apply(this, arguments); - element.addClass('active') - element.find('[data-toggle=tab]').attr({ 'tabIndex' : '0','aria-selected' : true,'aria-expanded' : true }) - element.filter('.tab-pane').attr({ 'aria-hidden' : false,'tabIndex' : '0' }) - } + element.addClass('active'); + element.find('[data-toggle=tab]').attr({ tabIndex: '0', 'aria-selected': true, 'aria-expanded': true }); + element.filter('.tab-pane').attr({ 'aria-hidden': false, tabIndex: '0' }); + }; - // Collapse Extension - // =============================== + // Collapse Extension + // =============================== - /* + /* // Disabled because it was creating accessibility issues var $colltabs = $('[data-toggle="collapse"]') @@ -312,111 +309,107 @@ */ - // Carousel Extension - // =============================== - - $('.carousel').each(function (index) { - var $this = $(this) - , prev = $this.find('[data-slide="prev"]') - , next = $this.find('[data-slide="next"]') - , $options = $this.find('.item') - , $listbox = $options.parent() - - $this.attr( { 'data-interval' : 'false', 'data-wrap' : 'false' } ) - $listbox.attr('role', 'listbox') - $options.attr('role', 'option') - - var spanPrev = document.createElement('span') - spanPrev.setAttribute('class', 'sr-only') - spanPrev.innerHTML='Previous' - - var spanNext = document.createElement('span') - spanNext.setAttribute('class', 'sr-only') - spanNext.innerHTML='Next' - - prev.attr('role', 'button') - next.attr('role', 'button') - - prev.append(spanPrev) - next.append(spanNext) - - $options.each(function () { - var item = $(this) - if(item.hasClass('active')){ - item.attr({ 'aria-selected': 'true', 'tabindex' : '0' }) - }else{ - item.attr({ 'aria-selected': 'false', 'tabindex' : '-1' }) - } - }) - }) - - var slideCarousel = $.fn.carousel.Constructor.prototype.slide - $.fn.carousel.Constructor.prototype.slide = function (type, next) { - var $active = this.$element.find('.item.active') - , $next = next || $active[type]() - - slideCarousel.apply(this, arguments) - - $active - .one($.support.transition.end, function () { - $active.attr({'aria-selected':false, 'tabIndex': '-1'}) - $next.attr({'aria-selected':true, 'tabIndex': '0'}) - //.focus() - }) + // Carousel Extension + // =============================== + + $('.carousel').each(function (index) { + var $this = $(this); + var prev = $this.find('[data-slide="prev"]'); + var next = $this.find('[data-slide="next"]'); + var $options = $this.find('.item'); + var $listbox = $options.parent(); + + $this.attr({ 'data-interval': 'false', 'data-wrap': 'false' }); + $listbox.attr('role', 'listbox'); + $options.attr('role', 'option'); + + var spanPrev = document.createElement('span'); + spanPrev.setAttribute('class', 'sr-only'); + spanPrev.innerHTML = 'Previous'; + + var spanNext = document.createElement('span'); + spanNext.setAttribute('class', 'sr-only'); + spanNext.innerHTML = 'Next'; + + prev.attr('role', 'button'); + next.attr('role', 'button'); + + prev.append(spanPrev); + next.append(spanNext); + + $options.each(function () { + var item = $(this); + if (item.hasClass('active')){ + item.attr({ 'aria-selected': 'true', tabindex: '0' }); + } else { + item.attr({ 'aria-selected': 'false', tabindex: '-1' }); + } + }); + }); + + var slideCarousel = $.fn.carousel.Constructor.prototype.slide; + $.fn.carousel.Constructor.prototype.slide = function (type, next) { + var $active = this.$element.find('.item.active'); + var $next = next || $active[type](); + + slideCarousel.apply(this, arguments); + + $active + .one($.support.transition.end, function () { + $active.attr({ 'aria-selected': false, tabIndex: '-1' }); + $next.attr({ 'aria-selected': true, tabIndex: '0' }); + //.focus() + }); + }; + + $.fn.carousel.Constructor.prototype.keydown = function (e) { + var $this = $(this); + var $ul = $this.closest('div[role=listbox]'); + var $items = $ul.find('[role=option]'); + var $parent = $ul.parent(); + var k = e.which || e.keyCode; + var index; + var i; + + if (!/(37|38|39|40)/.test(k)) return; + + index = $items.index($items.filter('.active')); + if (k == 37 || k == 38) { // Up + $parent.carousel('prev'); + index--; + if (index < 0) index = $items.length - 1; + else $this.prev().focus(); + } + if (k == 39 || k == 40) { // Down + $parent.carousel('next'); + index++; + if (index == $items.length) index = 0; + else { + $this.one($.support.transition.end, function () { + $this.next().focus(); + }); + } } - $.fn.carousel.Constructor.prototype.keydown = function (e) { - var $this = $(this) - , $ul = $this.closest('div[role=listbox]') - , $items = $ul.find('[role=option]') - , $parent = $ul.parent() - , k = e.which || e.keyCode - , index - , i - - if (!/(37|38|39|40)/.test(k)) return - - index = $items.index($items.filter('.active')) - if (k == 37 || k == 38) { // Up - $parent.carousel('prev') - index-- - if(index < 0) index = $items.length -1 - else $this.prev().focus() - - } - if (k == 39 || k == 40) { // Down - $parent.carousel('next') - index++ - if(index == $items.length) index = 0 - else { - $this.one($.support.transition.end, function () { - $this.next().focus() - }) - } + e.preventDefault(); + e.stopPropagation(); + }; + $(document).on('keydown.carousel.data-api', 'div[role=option]', $.fn.carousel.Constructor.prototype.keydown); - } + // GENERAL UTILITY FUNCTIONS + // =============================== - e.preventDefault() - e.stopPropagation() + var removeMultiValAttributes = function (el, attr, val) { + var describedby = (el.attr(attr) || '').split(/\s+/); + var index = $.inArray(val, describedby); + if (index !== -1) { + describedby.splice(index, 1); } - $(document).on('keydown.carousel.data-api', 'div[role=option]', $.fn.carousel.Constructor.prototype.keydown) - - // GENERAL UTILITY FUNCTIONS - // =============================== - - var removeMultiValAttributes = function (el, attr, val) { - var describedby = (el.attr( attr ) || "").split( /\s+/ ) - , index = $.inArray(val, describedby) - if ( index !== -1 ) { - describedby.splice( index, 1 ) - } - describedby = $.trim( describedby.join( " " ) ) - if (describedby ) { - el.attr( attr, describedby ) - } else { - el.removeAttr( attr ) - } + describedby = $.trim(describedby.join(' ')); + if (describedby) { + el.attr(attr, describedby); + } else { + el.removeAttr(attr); } - - + }; })(jQuery); diff --git a/src/assets/_project/_blocks/legacy/bootstrap-extensions.js b/src/assets/_project/_blocks/legacy/bootstrap-extensions.js index 1df309333..372e627dc 100644 --- a/src/assets/_project/_blocks/legacy/bootstrap-extensions.js +++ b/src/assets/_project/_blocks/legacy/bootstrap-extensions.js @@ -4,17 +4,17 @@ * ======================================================================== */ (function($) { - "use strict"; + 'use strict'; - // this[this.$element.hasClass('in') ? 'hide' : 'show']() - var collToggle = $.fn.collapse.Constructor.prototype.toggle; - $.fn.collapse.Constructor.prototype.toggle = function(){ - if( this.$trigger.is("input[type=radio]") ) { - if( this.$trigger.prop("checked", true) && ! this.$element.attr('aria-expanded') != true ) { - this.show(); - } - } else { - collToggle.call(this); // Default behaviour - } + // this[this.$element.hasClass('in') ? 'hide' : 'show']() + var collToggle = $.fn.collapse.Constructor.prototype.toggle; + $.fn.collapse.Constructor.prototype.toggle = function(){ + if (this.$trigger.is('input[type=radio]')) { + if (this.$trigger.prop('checked', true) && !this.$element.attr('aria-expanded') != true) { + this.show(); + } + } else { + collToggle.call(this); // Default behaviour } + }; })(jQuery); diff --git a/src/assets/_project/_blocks/legacy/forms/forms.js b/src/assets/_project/_blocks/legacy/forms/forms.js index 81881d319..18357eb9c 100644 --- a/src/assets/_project/_blocks/legacy/forms/forms.js +++ b/src/assets/_project/_blocks/legacy/forms/forms.js @@ -5,441 +5,422 @@ 'use strict'; var validationErrorMessage = 'Please check your answers'; - var SUBMIT_TOLERANCE = 10000, - DEFAULT_STATUS_HTML = ``, - // fields that validate - candidateForValidation = 'input, select, textarea', - - - // invalidFilter - invalidFilter = function () { - return !(this.disabled || this.validity.valid); - }, + var SUBMIT_TOLERANCE = 10000; + var DEFAULT_STATUS_HTML = ``; + // fields that validate + var candidateForValidation = 'input, select, textarea'; + + // invalidFilter + var invalidFilter = function () { + return !(this.disabled || this.validity.valid); + }; + // follow plugin conventions for storing plugin data + // http://docs.jquery.com/Plugins/Authoring#Data + var pluginDataKey = 'formValidation'; + var pluginData = function (key, value) { + var dataHash = this.data(pluginDataKey) || this.data(pluginDataKey, {}).data(pluginDataKey); + + if (typeof key !== 'undefined') { + if (typeof value !== 'undefined') { + dataHash[key] = value; + return value; + } else if (typeof dataHash[key] !== 'undefined') { + return dataHash[key]; + } + return null; + } - // follow plugin conventions for storing plugin data - // http://docs.jquery.com/Plugins/Authoring#Data - pluginDataKey = 'formValidation', - pluginData = function (key, value) { - var dataHash = this.data(pluginDataKey) || this.data(pluginDataKey, {}).data(pluginDataKey); + return dataHash; + }; - if (typeof key !== 'undefined') { - if (typeof value !== 'undefined') { - dataHash[key] = value; - return value; - } else if (typeof dataHash[key] !== 'undefined') { - return dataHash[key]; + // helper for .label, .hint and .alert + var getLabelComponent = function (component, options) { + return this.map(function (index, domElement) { + var $element = $(domElement); + var labelElement = null; + var foundElement = null; + + if (typeof options === 'object' && options.level === 'group') { + foundElement = $element.formValidation('group').find(component)[0]; + } else if ($element.is(':radio, :checkbox')) { + foundElement = $element.closest('fieldset').find(component)[0]; + } else { + labelElement = $element.closest('form').find('label[for="' + domElement.id + '"]'); + foundElement = labelElement.children(component)[0]; + if (!foundElement) { + if (component === '.hint') { + labelElement.append(''); + foundElement = labelElement.children(component)[0]; + } } - return null; } + return foundElement; + }); + }; - return dataHash; - }, - - - // helper for .label, .hint and .alert - getLabelComponent = function (component, options) { - return this.map(function (index, domElement) { - var $element = $(domElement), - labelElement = null, - foundElement = null; - - if (typeof options === 'object' && options.level === 'group') { - foundElement = $element.formValidation('group').find(component)[0]; - } else if ($element.is(':radio, :checkbox')) { - foundElement = $element.closest('fieldset').find(component)[0]; + var changeValidityCheck = function () { + var $this = $(this); + var alertElement = $this.formValidation('alert'); + var alertLevel; + var invalidContainers; + + // is this control valid? + if (this.validity.valid) { + // is it part of a group that contain other invalid controls? + if ($this.formValidation('question').find('.alert').filter(alertElement).length > 0) { + alertElement.remove(); + } else { + // update message from first invalid field in group + invalidContainers = $this.formValidation('group').find(candidateForValidation).filter(invalidFilter); + if (invalidContainers.length > 0) { + alertElement.text(invalidContainers.formValidation('getValidationMessage')); } else { - labelElement = $element.closest('form').find('label[for="' + domElement.id + '"]'); - foundElement = labelElement.children(component)[0]; - if (!foundElement) { - if (component === '.hint') { - labelElement.append(''); - foundElement = labelElement.children(component)[0]; - } - } + // all fields valid + alertElement.remove(); } - return foundElement; - }); - }, - + } - changeValidityCheck = function () { - var $this = $(this), - alertElement = $this.formValidation('alert'), - alertLevel, - invalidContainers; + // remove invalid class from ancestors that do not contain invalid fields + $this.parentsUntil('form', '.invalid').filter(function () { + return $(this).find(candidateForValidation).filter(invalidFilter).length === 0; + }) + // remove .invalid class + .removeClass('invalid') + // remove old alerts (change handler should have already done this) + .find($(`.alert:contains(${validationErrorMessage})`)) + .remove(); + } else { + // does alert exist? + if (alertElement.length === 0) { + alertElement = $(''); + } + // show message + alertElement.text($this.formValidation('getValidationMessage')); + // append to form + if ($this.formValidation('group').hasClass('atomic')) { + alertLevel = { level: 'group' }; + } - // is this control valid? - if (this.validity.valid) { - // is it part of a group that contain other invalid controls? - if ($this.formValidation('question').find('.alert').filter(alertElement).length > 0) { - alertElement.remove(); - } else { - // update message from first invalid field in group - invalidContainers = $this.formValidation('group').find(candidateForValidation).filter(invalidFilter); - if (invalidContainers.length > 0) { - alertElement.text(invalidContainers.formValidation('getValidationMessage')); - } else { - // all fields valid - alertElement.remove(); - } - } + $this.formValidation('label', alertLevel).parent().find('.label, abbr[title="(required)"]').eq(-1) + .after(alertElement); - // remove invalid class from ancestors that do not contain invalid fields - $this.parentsUntil('form', '.invalid').filter(function () { - return $(this).find(candidateForValidation).filter(invalidFilter).length === 0; - }) - // remove .invalid class - .removeClass('invalid') - // remove old alerts (change handler should have already done this) - .find( $( `.alert:contains(${validationErrorMessage})` ) ) - .remove(); - } else { - // does alert exist? - if (alertElement.length === 0) { - alertElement = $(''); - } - // show message - alertElement.text($this.formValidation('getValidationMessage')); - // append to form - if ($this.formValidation('group').hasClass('atomic')) { - alertLevel = { 'level': 'group' }; - } + // NOTE we don't flag the question as .invalid now + // .invalid only happens on submit, to soften inline validation errors + } + }; - $this.formValidation( 'label', alertLevel ).parent().find( '.label, abbr[title="(required)"]' ).eq( -1 ) - .after(alertElement); + // checks for invalid elements + // returns number of invalid elements + var submitValidityCheck = function () { + // form object + var form = $(this).closest('form'); - // NOTE we don't flag the question as .invalid now - // .invalid only happens on submit, to soften inline validation errors + // invalid fields + var invalid = form.find(candidateForValidation).filter(function invalidFields() { + // skip disabled + if (this.disabled) { + return false; } - }, - - // checks for invalid elements - // returns number of invalid elements - submitValidityCheck = function () { - // form object - var form = $(this).closest('form'), + // only check radio button groups once (skip individual radio button) + if (this.type === 'radio') { + if (!invalidFields.cache) { + invalidFields.cache = {}; + } else if (invalidFields.cache[this.name] === true) { + return false; + } + invalidFields.cache[this.name] = true; + } - // invalid fields - invalid = form.find(candidateForValidation).filter(function invalidFields() { - // skip disabled - if (this.disabled) { - return false; - } + return this.validity && !this.validity.valid; + }); - // only check radio button groups once (skip individual radio button) - if (this.type === 'radio') { - if (!invalidFields.cache) { - invalidFields.cache = {}; - } else if (invalidFields.cache[this.name] === true) { - return false; - } - invalidFields.cache[this.name] = true; - } + // alert container + var alert = pluginData.call(form, 'summaryElement') || pluginData.call(form, 'summaryElement', $(DEFAULT_STATUS_HTML)); - return this.validity && !this.validity.valid; - }), - - // alert container - alert = pluginData.call(form, 'summaryElement') || pluginData.call(form, 'summaryElement', $(DEFAULT_STATUS_HTML)), - - // messages within alert - messages = alert.find('ol'), - - // track groups - lastGroupSeen = true; - - if (invalid.length > 0) { - // remove old messages - messages.find('li').remove(); - - // add new messages - invalid.each(function () { - // get field - var $this = $(this), - // get group (if exists) - group = $this.formValidation('group'), - // get label or group label - label = $this.formValidation('label', { - level: group.length > 0 ? 'group' : null - }), - labelId, - item; - - // get the label id - if (label.length > 0) { - labelId = label[0].id || label.generateId('label-' + this.id)[0].id; - } else { - labelId = this.name; - } + // messages within alert + var messages = alert.find('ol'); - // get alert item - item = pluginData.call( $this, 'summaryElement' ) || pluginData.call( $this, 'summaryElement', $( '
      • ' )); + // track groups + var lastGroupSeen = true; - if ( group.length === 0 || group[0] !== lastGroupSeen ) { - // update last group seen - lastGroupSeen = group[ 0 ]; + if (invalid.length > 0) { + // remove old messages + messages.find('li').remove(); - // create error message with link to label - item - .find('a') - .text( label.text().replace( /\?$/, '' ) + ': ' + $this.formValidation( 'getValidationMessage' )) - .end() - .appendTo( messages ); - } else { - // remove from DOM - item.remove(); - } + // add new messages + invalid.each(function () { + // get field + var $this = $(this); + // get group (if exists) + var group = $this.formValidation('group'); + // get label or group label + var label = $this.formValidation('label', { + level: group.length > 0 ? 'group' : null, }); - } + var labelId; + var item; - return invalid.length; - }, + // get the label id + if (label.length > 0) { + labelId = label[0].id || label.generateId('label-' + this.id)[0].id; + } else { + labelId = this.name; + } + // get alert item + item = pluginData.call($this, 'summaryElement') || pluginData.call($this, 'summaryElement', $('
      • ')); - submitValidationHandler = function (event) { - // validate form - var count = submitValidityCheck.call( this ), - form = $( this ); + if (group.length === 0 || group[0] !== lastGroupSeen) { + // update last group seen + lastGroupSeen = group[0]; - // remove invalid class from questions that do not contain invalid fields - form.find( '.invalid' ).filter(function() { - return $( this ).find( candidateForValidation ).filter( invalidFilter ).length === 0; - }) - // remove .invalid class - .removeClass( 'invalid' ) - // remove old alerts (change handler should have already done this) - .find( $( `.alert:contains(${validationErrorMessage})` ) ) - .remove() - ; + // create error message with link to label + item + .find('a') + .text(label.text().replace(/\?$/, '') + ': ' + $this.formValidation('getValidationMessage')) + .end() + .appendTo(messages); + } else { + // remove from DOM + item.remove(); + } + }); + } + return invalid.length; + }; - // anything invalid? - if ( count > 0 ) { - // cancel submit - event.stopImmediatePropagation(); - event.preventDefault(); + var submitValidationHandler = function (event) { + // validate form + var count = submitValidityCheck.call(this); + var form = $(this); - // show the error summary - (function(form) { - var summary = pluginData.call( form, 'summaryElement' ); - // hide any previous status blocks - form.prev( `.alert:contains(${validationErrorMessage})` ).not( summary ).remove(); - // show the new summary - form.before( summary.fadeIn() ); - // focus/scroll summary element - if (window.innerWidth < 992) { - $( window ).scrollTop( summary.offset().top - $('.qg-site-header').height()); - } else { - $( window ).scrollTop( summary.offset().top ); - } - }( form )); + // remove invalid class from questions that do not contain invalid fields + form.find('.invalid').filter(function() { + return $(this).find(candidateForValidation).filter(invalidFilter).length === 0; + }) + // remove .invalid class + .removeClass('invalid') + // remove old alerts (change handler should have already done this) + .find($(`.alert:contains(${validationErrorMessage})`)) + .remove() + ; - // find all the invalid fields - form.find( candidateForValidation ).filter( invalidFilter ).each(function() { - // update inline alerts - changeValidityCheck.call( this ); - }) - // set .invalid on ancestor LI elements - .parentsUntil( 'form', '.questions > li' ) - // but not sections - .not( '.section, .compact' ) - .addClass( 'invalid' ) - ; + // anything invalid? + if (count > 0) { + // cancel submit + event.stopImmediatePropagation(); + event.preventDefault(); + + // show the error summary + (function(form) { + var summary = pluginData.call(form, 'summaryElement'); + // hide any previous status blocks + form.prev(`.alert:contains(${validationErrorMessage})`).not(summary).remove(); + // show the new summary + form.before(summary.fadeIn()); + // focus/scroll summary element + if (window.innerWidth < 992) { + $(window).scrollTop(summary.offset().top - $('.qg-site-header').height()); + } else { + $(window).scrollTop(summary.offset().top); + } + }(form)); - // trigger x-invalid - form.trigger( 'x-invalid' ); + // find all the invalid fields + form.find(candidateForValidation).filter(invalidFilter).each(function() { + // update inline alerts + changeValidityCheck.call(this); + }) + // set .invalid on ancestor LI elements + .parentsUntil('form', '.questions > li') + // but not sections + .not('.section, .compact') + .addClass('invalid') + ; - // cancel submit - return false; - } - }, + // trigger x-invalid + form.trigger('x-invalid'); + // cancel submit + return false; + } + }; - // bind this AFTER the validation handler - // only invoked if validation did not prevent submit - // This will softlock submit if form submit passes this function with in SUBMIT_TOLERANCE timerange - submitDoneHandler = function( event ) { - // use event.timeStamp when available and $.now() otherwise - var timeStamp = event.timeStamp || $.now(), - form = $( this ), - summaryElement = pluginData.call( form, 'summaryElement' ), - lastSubmitTimeStamp + // bind this AFTER the validation handler + // only invoked if validation did not prevent submit + // This will softlock submit if form submit passes this function with in SUBMIT_TOLERANCE timerange + var submitDoneHandler = function(event) { + // use event.timeStamp when available and $.now() otherwise + var timeStamp = event.timeStamp || $.now(); + var form = $(this); + var summaryElement = pluginData.call(form, 'summaryElement'); + var lastSubmitTimeStamp ; - // remove summary element from DOM on successful submit - if ( summaryElement ) { - summaryElement.remove(); - } - - // is this submit event too soon after the last one? - lastSubmitTimeStamp = pluginData.call( form, 'lastSubmitTimeStamp' ); - if ( lastSubmitTimeStamp && timeStamp - lastSubmitTimeStamp < SUBMIT_TOLERANCE ) { - // cancel the submit event - event.stopImmediatePropagation(); - event.preventDefault(); - return false; - } else { - // store the timestamp - pluginData.call( form, 'lastSubmitTimeStamp', timeStamp ); - } - }, - + // remove summary element from DOM on successful submit + if (summaryElement) { + summaryElement.remove(); + } - // plugin methods - methods = { - // $( x ).formValidation( 'alert' ) -- get - // get alert text - alert: function() { - return this.map(function( index, domElement ) { - var $element = $( domElement ), - group; + // is this submit event too soon after the last one? + lastSubmitTimeStamp = pluginData.call(form, 'lastSubmitTimeStamp'); + if (lastSubmitTimeStamp && timeStamp - lastSubmitTimeStamp < SUBMIT_TOLERANCE) { + // cancel the submit event + event.stopImmediatePropagation(); + event.preventDefault(); + return false; + } else { + // store the timestamp + pluginData.call(form, 'lastSubmitTimeStamp', timeStamp); + } + }; - if ( $element.is( ':radio, :checkbox' ) === true ) { - return $element.closest( 'fieldset' ).find( 'legend > .alert' )[ 0 ]; + // plugin methods + var methods = { + // $( x ).formValidation( 'alert' ) -- get + // get alert text + alert: function() { + return this.map(function(index, domElement) { + var $element = $(domElement); + var group; + + if ($element.is(':radio, :checkbox') === true) { + return $element.closest('fieldset').find('legend > .alert')[0]; + } else { + // atomic groups + group = $element.formValidation('group').filter('.atomic'); + if (group.length > 0) { + return group.find('legend > .alert')[0]; } else { - // atomic groups - group = $element.formValidation( 'group' ).filter( '.atomic' ); - if ( group.length > 0 ) { - return group.find( 'legend > .alert' )[ 0 ]; - } else { - return $( 'label[for="' + domElement.id + '"] > .alert' )[ 0 ]; - } + return $('label[for="' + domElement.id + '"] > .alert')[0]; } - }); - }, - - - // $( x ).formValidation( 'label' ) - // $( x ).formValidation( 'label', { level : group }) - // return .label associated with element or containing group - label : function( options ) { - return getLabelComponent.call( this, '.label', options ); - }, - - - // $( x ).formValidation( 'hint' ) - // $( x ).formValidation( 'hint', { level : group }) - // return .hint associated with element or containing group - hint : function( options ) { - return getLabelComponent.call( this, '.hint', options ); - }, - - - // $( x ).formValidation( 'question' ) - // return question element for item - question : function( options ) { - // looking for group? - if ( typeof options === 'object' && options.level === 'group' ) { - // return the group - return this.formValidation( 'group' ); } + }); + }, - // not looking for group - return this.map(function( index, domElement ) { - return $( domElement ).parentsUntil( 'form', '.questions > li' )[ 0 ]; - }); - }, - - - // $( x ).formValidation( 'group' ) - // return group element for item - group : function() { - return this.map(function( index, domElement ) { - return $( domElement ).parentsUntil( 'form', '.group' ).filter(function() { - // ignore groups that do not contain fieldsets - return $( this ).children( 'fieldset' ).length > 0; - })[ 0 ]; - }); - }, + // $( x ).formValidation( 'label' ) + // $( x ).formValidation( 'label', { level : group }) + // return .label associated with element or containing group + label: function(options) { + return getLabelComponent.call(this, '.label', options); + }, + // $( x ).formValidation( 'hint' ) + // $( x ).formValidation( 'hint', { level : group }) + // return .hint associated with element or containing group + hint: function(options) { + return getLabelComponent.call(this, '.hint', options); + }, - // $( x ).formValidation( 'validate' ) - // binds validation handler functions - // sets @novalidate on form to disable built-in validation - // TODO allow this to be called multiple times without binding additional handlers! - validate : function() { - return this.each(function() { - $( this ).closest( 'form' ) - // turn off native validation - .attr( 'novalidate', true ) - // unbind and rebind handlers - .off( 'submit', submitDoneHandler ) - .off( 'submit', submitValidationHandler ) - // validate this form - .on( 'submit', submitValidationHandler ) - // if validation did not cancel submit… - .on( 'submit', submitDoneHandler ) - // bind inline validation handlers to form elements - .find( candidateForValidation ) - .off( 'change', changeValidityCheck ) - .on( 'change', changeValidityCheck ) - ; - }); - }, + // $( x ).formValidation( 'question' ) + // return question element for item + question: function(options) { + // looking for group? + if (typeof options === 'object' && options.level === 'group') { + // return the group + return this.formValidation('group'); + } - // jQuery("div.alert.alert-warning").remove(); //as this function only add's to it. submitDoneHandler did the removal on success. - // $( x ).formValidation( 'validate', event ) - // validates the form it is attached too - // return false if invalid - // var fakeEvent = jQuery.Event( "click" ); - // $("form#myForm").formValidation("validateNow", fakeEvent); - // The fakeEvent captures the .stopImmediatePropagation() .preventDefault() - // and to allow you to check with: - //isDefaultPrevented, isImmediatePropagationStopped - validateNow : function( event ) { - return submitValidationHandler.call( this, event ); - }, + // not looking for group + return this.map(function(index, domElement) { + return $(domElement).parentsUntil('form', '.questions > li')[0]; + }); + }, + // $( x ).formValidation( 'group' ) + // return group element for item + group: function() { + return this.map(function(index, domElement) { + return $(domElement).parentsUntil('form', '.group').filter(function() { + // ignore groups that do not contain fieldsets + return $(this).children('fieldset').length > 0; + })[0]; + }); + }, - // $( x ).formValidation( 'getValidationMessage' ) - // return String validation message, e.g. "Must be completed" - getValidationMessage : function() { + // $( x ).formValidation( 'validate' ) + // binds validation handler functions + // sets @novalidate on form to disable built-in validation + // TODO allow this to be called multiple times without binding additional handlers! + validate: function() { + return this.each(function() { + $(this).closest('form') + // turn off native validation + .attr('novalidate', true) + // unbind and rebind handlers + .off('submit', submitDoneHandler) + .off('submit', submitValidationHandler) + // validate this form + .on('submit', submitValidationHandler) + // if validation did not cancel submit… + .on('submit', submitDoneHandler) + // bind inline validation handlers to form elements + .find(candidateForValidation) + .off('change', changeValidityCheck) + .on('change', changeValidityCheck) + ; + }); + }, - var validityState = this[ 0 ].validity; + // jQuery("div.alert.alert-warning").remove(); //as this function only add's to it. submitDoneHandler did the removal on success. + // $( x ).formValidation( 'validate', event ) + // validates the form it is attached too + // return false if invalid + // var fakeEvent = jQuery.Event( "click" ); + // $("form#myForm").formValidation("validateNow", fakeEvent); + // The fakeEvent captures the .stopImmediatePropagation() .preventDefault() + // and to allow you to check with: + //isDefaultPrevented, isImmediatePropagationStopped + validateNow: function(event) { + return submitValidationHandler.call(this, event); + }, - if ( typeof validityState === 'undefined' || validityState.valid === true ) { - return ''; - } else if ( validityState.valueMissing ) { - return 'Must be completed'; - } else if ( validityState.customError ) { - return this[ 0 ].validationMessage; - } else if ( validityState.typeMismatch ) { - return 'Must be an email address'; - } else if ( validityState.patternMismatch ) { - return 'Must use the format shown'; - } else { - return 'Must be a valid answer'; - } + // $( x ).formValidation( 'getValidationMessage' ) + // return String validation message, e.g. "Must be completed" + getValidationMessage: function() { + var validityState = this[0].validity; + + if (typeof validityState === 'undefined' || validityState.valid === true) { + return ''; + } else if (validityState.valueMissing) { + return 'Must be completed'; + } else if (validityState.customError) { + return this[0].validationMessage; + } else if (validityState.typeMismatch) { + return 'Must be an email address'; + } else if (validityState.patternMismatch) { + return 'Must use the format shown'; + } else { + return 'Must be a valid answer'; } + }, - }; + }; - $.fn.formValidation = function( method ) { + $.fn.formValidation = function(method) { // Method calling logic // http://docs.jquery.com/Plugins/Authoring#Plugin_Methods - if ( methods[method] ) { - return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 )); - } else if ( typeof method === 'object' || ! method ) { - return methods.init.apply( this, arguments ); + if (methods[method]) { + return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); + } else if (typeof method === 'object' || !method) { + return methods.init.apply(this, arguments); } else { - $.error( 'Method ' + method + ' does not exist on jQuery.formValidation' ); + $.error('Method ' + method + ' does not exist on jQuery.formValidation'); } - }; - // legacy API $.fn.forcesForms = $.fn.formValidation; -}( jQuery )); +}(jQuery)); /*! Generate ID - v1.0.3 - 2014-09-18 * https://github.com/bboyle/Generate-ID * Copyright (c) 2014 Ben Boyle; Licensed MIT */ -(function( $ ) { +(function($) { 'use strict'; - /** * Assigns a unique value to `@id` unless hasAttribute( 'id' ) is true * @@ -447,358 +428,325 @@ * * @return jquery object (chaining supported) */ - $.fn.generateId = function( preferredId ) { - + $.fn.generateId = function(preferredId) { var i = 1; - if ( ! preferredId ) { + if (!preferredId) { preferredId = 'id'; } else { - preferredId = $.trim( preferredId.toLowerCase().replace( /[^a-z0-9_]+/g, ' ' )).replace( /\s+/g, '-' ); + preferredId = $.trim(preferredId.toLowerCase().replace(/[^a-z0-9_]+/g, ' ')).replace(/\s+/g, '-'); } return this.each(function() { - var id; - if ( ! this.getAttribute( 'id' )) { - + if (!this.getAttribute('id')) { id = preferredId; - while ( document.getElementById( id )) { - id = preferredId + String( i ); + while (document.getElementById(id)) { + id = preferredId + String(i); i++; } - this.setAttribute( 'id', id ); + this.setAttribute('id', id); } }); - }; - - -}( jQuery )); +}(jQuery)); /*! HTML5 constraintValidationAPI - v1.0.7 - 2015-02-19 * https://github.com/bboyle/html5-constraint-validation-API * Copyright (c) 2015 Ben Boyle; Licensed MIT */ /*exported initConstraintValidationAPI*/ -if ( jQuery !== 'undefined' ) { - (function( $ ) { +if (jQuery !== 'undefined') { + (function($) { 'use strict'; - // http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address // 1*( atext / "." ) "@" ldh-str 1*( "." ldh-str ) - var REXP_EMAIL = /^[A-Za-z0-9!#$%&'*+\-\/=\?\^_`\{\|\}~\.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)*$/, - - // fields that validate - candidateForValidation = 'input, select, textarea', - - // for feature detection - input = $( '' ).get( 0 ), + var REXP_EMAIL = /^[A-Za-z0-9!#$%&'*+\-\/=\?\^_`\{\|\}~\.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)*$/; - // polyfill test - polyfill = typeof input.validity !== 'object', + // fields that validate + var candidateForValidation = 'input, select, textarea'; - // radio button bug (google earth internal browser) - radioButtonBug = ! polyfill && $( '' ).get( 0 ).validity.valueMissing === true, - validateBuggyRadioButtons, + // for feature detection + var input = $('').get(0); - // invalid fields filter - isInvalid = function() { - return ! ( this.disabled || this.validity.valid ); - }, + // polyfill test + var polyfill = typeof input.validity !== 'object'; - // get all radio buttons - getRadioButtonsInGroup = function( radio ) { - return $( radio.form.elements[ radio.name ] ).filter( '[name="' + radio.name + '"]' ); - }, + // radio button bug (google earth internal browser) + var radioButtonBug = !polyfill && $('').get(0).validity.valueMissing === true; + var validateBuggyRadioButtons; + // invalid fields filter + var isInvalid = function() { + return !(this.disabled || this.validity.valid); + }; - // manage validity state object - validityState = function( typeMismatch, valueMissing, customError, message, patternMismatch ) { - - if ( typeof message === 'string' ) { - customError = !! message; - } - return { - customError: customError, - typeMismatch: !! typeMismatch, - patternMismatch: !! patternMismatch, - valueMissing: !! valueMissing, - valid: ! valueMissing && ! customError && ! typeMismatch && ! patternMismatch - }; - }, + // get all radio buttons + var getRadioButtonsInGroup = function(radio) { + return $(radio.form.elements[radio.name]).filter('[name="' + radio.name + '"]'); + }; + // manage validity state object + var validityState = function(typeMismatch, valueMissing, customError, message, patternMismatch) { + if (typeof message === 'string') { + customError = !!message; + } + return { + customError: customError, + typeMismatch: !!typeMismatch, + patternMismatch: !!patternMismatch, + valueMissing: !!valueMissing, + valid: !valueMissing && !customError && !typeMismatch && !patternMismatch, + }; + }; - validateField = function(message) { - var $this = $( this ), - required = !!$this.attr( 'required' ), - radio = this.type === 'radio' && getRadioButtonsInGroup( this ), - valueMissing, - invalidEmail = this.getAttribute( 'type' ) === 'email' && !!this.value && ! REXP_EMAIL.test( this.value ), - patternMismatch, - pattern, - newValidityState + var validateField = function(message) { + var $this = $(this); + var required = !!$this.attr('required'); + var radio = this.type === 'radio' && getRadioButtonsInGroup(this); + var valueMissing; + var invalidEmail = this.getAttribute('type') === 'email' && !!this.value && !REXP_EMAIL.test(this.value); + var patternMismatch; + var pattern; + var newValidityState ; - // radio buttons are required if any single radio button is flagged as required - if ( radio && !required ) { - required = radio.filter( '[required]' ).length > 0; - } - // if required, check for missing value - if ( required ){ - - if ( /^select$/i.test( this.nodeName )) { - valueMissing = this.selectedIndex === 0 && this.options[ 0 ].value === ''; - - } else if ( radio ) { - valueMissing = radio.filter( ':checked' ).length === 0; - - } else if ( this.type === 'checkbox' ) { - valueMissing = !this.checked; - - } else { - valueMissing = !this.value; - } - - } - - if ( !! this.getAttribute( 'pattern' ) ) { - if ( this.value.length > 0 ) { - // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-input-element-attributes.html#compiled-pattern-regular-expression - pattern = new RegExp( '^(?:' + this.getAttribute( 'pattern' ) + ')$' ); - - patternMismatch = ! pattern.test( this.value ); - - } else { - patternMismatch = false; - } - } - - // set .validityState - newValidityState = validityState( invalidEmail, valueMissing, this.validity.customError || false, message, patternMismatch ); - if ( radio ) { - getRadioButtonsInGroup( this ).each(function() { this.validity = newValidityState; }); + // radio buttons are required if any single radio button is flagged as required + if (radio && !required) { + required = radio.filter('[required]').length > 0; + } + // if required, check for missing value + if (required){ + if (/^select$/i.test(this.nodeName)) { + valueMissing = this.selectedIndex === 0 && this.options[0].value === ''; + } else if (radio) { + valueMissing = radio.filter(':checked').length === 0; + } else if (this.type === 'checkbox') { + valueMissing = !this.checked; } else { - this.validity = newValidityState; + valueMissing = !this.value; } + } - // set .validationMessage - if ( this.validity.valid ) { - this.validationMessage = ''; - - } else if ( this.validity.customError ) { - if ( typeof message === 'string' ) { - this.validationMessage = message; - } - - } else if ( this.validity.valueMissing ) { - this.validationMessage = 'Please answer this question'; - - } else if ( this.validity.typeMismatch ) { - this.validationMessage = 'Please type an email address'; - - } else if ( this.validity.patternMismatch ) { - this.validationMessage = 'Please use the format shown'; + if (this.getAttribute('pattern')) { + if (this.value.length > 0) { + // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-input-element-attributes.html#compiled-pattern-regular-expression + pattern = new RegExp('^(?:' + this.getAttribute('pattern') + ')$'); + patternMismatch = !pattern.test(this.value); } else { - this.validationMessage = 'Please answer the question correctly'; + patternMismatch = false; } + } - return this.disabled || this.validity.valid; - }, - - - changeHandler = function( event ) { - var target = event.target; - - validateField.call( target ); + // set .validityState + newValidityState = validityState(invalidEmail, valueMissing, this.validity.customError || false, message, patternMismatch); + if (radio) { + getRadioButtonsInGroup(this).each(function() { this.validity = newValidityState; }); + } else { + this.validity = newValidityState; + } - if ( target.type === 'radio' ) { - getRadioButtonsInGroup( target ).each(function() { - this.validity = target.validity; - this.validationMessage = target.validationMessage; - }); + // set .validationMessage + if (this.validity.valid) { + this.validationMessage = ''; + } else if (this.validity.customError) { + if (typeof message === 'string') { + this.validationMessage = message; } - }, - + } else if (this.validity.valueMissing) { + this.validationMessage = 'Please answer this question'; + } else if (this.validity.typeMismatch) { + this.validationMessage = 'Please type an email address'; + } else if (this.validity.patternMismatch) { + this.validationMessage = 'Please use the format shown'; + } else { + this.validationMessage = 'Please answer the question correctly'; + } - submitHandler = function( event ){ + return this.disabled || this.validity.valid; + }; - var form = $( this ), - novalidate = !!form.attr( 'novalidate' ), - invalid = false - ; + var changeHandler = function(event) { + var target = event.target; - // polyfill validation? - if ( polyfill ) { - // check fields - form.find( candidateForValidation ).each(function() { + validateField.call(target); - invalid = !validateField.call( this ); + if (target.type === 'radio') { + getRadioButtonsInGroup(target).each(function() { + this.validity = target.validity; + this.validationMessage = target.validationMessage; + }); + } + }; + var submitHandler = function(event){ + var form = $(this); + var novalidate = !!form.attr('novalidate'); + var invalid = false + ; - // unless @novalidate - if ( ! novalidate ) { - // if invalid - if ( invalid ) { - // use triggerHandler because invalid does not bubble - $( this ).triggerHandler( 'invalid' ); - } + // polyfill validation? + if (polyfill) { + // check fields + form.find(candidateForValidation).each(function() { + invalid = !validateField.call(this); + + // unless @novalidate + if (!novalidate) { + // if invalid + if (invalid) { + // use triggerHandler because invalid does not bubble + $(this).triggerHandler('invalid'); } - }); - } - - // NOTE all the code below runs in all browsers to polyfill implementation bugs + } + }); + } - // required radio button check - if ( radioButtonBug ) { - validateBuggyRadioButtons( this ); - } + // NOTE all the code below runs in all browsers to polyfill implementation bugs - // Opera 11 on OSX fires submit event even when fields are invalid - // correct implementations will not invoke this submit handler until all fields are valid + // required radio button check + if (radioButtonBug) { + validateBuggyRadioButtons(this); + } - // unless @novalidate - // if there are invalid fields - if ( ! novalidate && form.find( candidateForValidation ).filter( isInvalid ).length > 0 ) { - // abort submit - event.stopImmediatePropagation(); - event.preventDefault(); - return false; - } - }, + // Opera 11 on OSX fires submit event even when fields are invalid + // correct implementations will not invoke this submit handler until all fields are valid + // unless @novalidate + // if there are invalid fields + if (!novalidate && form.find(candidateForValidation).filter(isInvalid).length > 0) { + // abort submit + event.stopImmediatePropagation(); + event.preventDefault(); + return false; + } + }; - initConstraintValidationAPI = function() { - var candidates = $( candidateForValidation ); + var initConstraintValidationAPI = function() { + var candidates = $(candidateForValidation); - // INPUT validityState - if ( polyfill ) { - // set us up the API - candidates.filter(function() { - return typeof this.validity !== 'object'; - }).each(function() { + // INPUT validityState + if (polyfill) { + // set us up the API + candidates.filter(function() { + return typeof this.validity !== 'object'; + }).each(function() { + this.validity = validityState(false, false, false, '', false); + this.validationMessage = ''; + }); - this.validity = validityState( false, false, false, '', false ); - this.validationMessage = ''; + // check validity on change + candidates + .off('change.constraintValidationAPI') + .on('change.constraintValidationAPI', changeHandler) + ; + } - }); + // INPUT validitationMessage + if (typeof input.validationMessage !== 'string') { + // set us up the API + candidates.filter(function() { + return typeof this.validationMessage !== 'string'; + }).each(function() { + this.validationMessage = ''; + }); + } - // check validity on change - candidates - .off( 'change.constraintValidationAPI' ) - .on( 'change.constraintValidationAPI', changeHandler ) - ; - } + // INPUT checkValidity + if (typeof input.checkValidity !== 'function') { + // set us up the API + candidates.filter(function() { + return typeof this.checkValidity !== 'function'; + }).each(function() { + var domElement = this; + + this.checkValidity = function() { + var valid = validateField.call(domElement); + + // if invalid, and unless novalidate + if (!valid && !this.form.getAttribute('novalidate')) { + // use triggerHandler because invalid does not bubble + $(domElement).triggerHandler('invalid'); + } - // INPUT validitationMessage - if ( typeof input.validationMessage !== 'string' ) { - // set us up the API - candidates.filter(function() { - return typeof this.validationMessage !== 'string'; - }).each(function() { - this.validationMessage = ''; - }); - } + return valid; + }; + }); + } - // INPUT checkValidity - if ( typeof input.checkValidity !== 'function' ) { - // set us up the API - candidates.filter(function() { - return typeof this.checkValidity !== 'function'; - }).each(function() { - var domElement = this; - - this.checkValidity = function() { - var valid = validateField.call( domElement ); - - // if invalid, and unless novalidate - if ( ! valid && ! this.form.getAttribute( 'novalidate' )) { - // use triggerHandler because invalid does not bubble - $( domElement ).triggerHandler( 'invalid' ); - } + // INPUT setCustomValidity + if (typeof input.setCustomValidity !== 'function') { + // set us up the API + candidates.filter(function() { + return typeof this.setCustomValidity !== 'function'; + }).each(function() { + var that = this; - return valid; - }; - }); - } + this.setCustomValidity = function(message) { + validateField.call(that, message); + }; + }); + } - // INPUT setCustomValidity - if ( typeof input.setCustomValidity !== 'function' ) { - // set us up the API - candidates.filter(function() { - return typeof this.setCustomValidity !== 'function'; - }).each(function() { - var that = this; - - this.setCustomValidity = function( message ) { - validateField.call( that, message ); - }; + // check for required radio button bug (google earth internal browser) + if (radioButtonBug) { + validateBuggyRadioButtons = function(form) { + var seen = {}; + var radio, + valueMissing; + + // check every required radio button + $('input', form).filter(':radio').filter('[required],[aria-required="true"]').each(function() { + if (typeof seen[this.name] === 'undefined') { + seen[this.name] = true; + + radio = getRadioButtonsInGroup(this); + valueMissing = radio.filter(':checked').length === 0; + + if (valueMissing) { + // make sure @required is set to use validation API + radio.attr('required', 'required'); + } else { + // using @aria-required=true so we can track this control + // removing @required here to bypass validation bug + radio.attr('aria-required', true).removeAttr('required'); + } + } }); - } - - // check for required radio button bug (google earth internal browser) - if ( radioButtonBug ) { - validateBuggyRadioButtons = function( form ) { - var seen = {}; - var radio, - valueMissing; - - // check every required radio button - $( 'input', form ).filter( ':radio' ).filter( '[required],[aria-required="true"]' ).each(function() { - if ( typeof seen[ this.name ] === 'undefined' ) { - seen[ this.name ] = true; + }; - radio = getRadioButtonsInGroup( this ); - valueMissing = radio.filter( ':checked' ).length === 0; + // initial validity + $('form').each(validateBuggyRadioButtons); - if ( valueMissing ) { - // make sure @required is set to use validation API - radio.attr( 'required', 'required' ); - } else { - // using @aria-required=true so we can track this control - // removing @required here to bypass validation bug - radio.attr( 'aria-required', true ).removeAttr( 'required' ); - } - } - }); - }; - - // initial validity - $( 'form' ).each( validateBuggyRadioButtons ); - - // watch changes - if ( ! polyfill ) { - candidates.filter( ':radio' ) - .off( 'change.constraintValidationAPI' ) - .on( 'change.constraintValidationAPI', function() { - validateBuggyRadioButtons( this.form ); - }) - ; - } + // watch changes + if (!polyfill) { + candidates.filter(':radio') + .off('change.constraintValidationAPI') + .on('change.constraintValidationAPI', function() { + validateBuggyRadioButtons(this.form); + }) + ; } - - // check validity on submit - // this should be bound before all other submit handlers bound to the same form - // otherwise they will execute before this handler can cancel submit (oninvalid) - $( 'form' ) - .off( 'submit.constraintValidationAPI' ) - .on( 'submit.constraintValidationAPI', submitHandler ) - ; } - ; + // check validity on submit + // this should be bound before all other submit handlers bound to the same form + // otherwise they will execute before this handler can cancel submit (oninvalid) + $('form') + .off('submit.constraintValidationAPI') + .on('submit.constraintValidationAPI', submitHandler) + ; + } + ; // run immediately and ondocumentready initConstraintValidationAPI(); - $( initConstraintValidationAPI ); - + $(initConstraintValidationAPI); // expose init function window.initConstraintValidationAPI = initConstraintValidationAPI; - - - }( jQuery )); + }(jQuery)); } /* * jQuery Simply Countable plugin @@ -814,33 +762,29 @@ if ( jQuery !== 'undefined' ) { */ (function($){ - $.fn.simplyCountable = function(options){ - options = $.extend({ - counter: '#counter', - countType: 'characters', - maxCount: 140, - strictMax: false, - countDirection: 'down', - safeClass: 'safe', - overClass: 'over', - thousandSeparator: ',', - onOverCount: function(){}, - onSafeCount: function(){}, - onMaxCount: function(){} + counter: '#counter', + countType: 'characters', + maxCount: 140, + strictMax: false, + countDirection: 'down', + safeClass: 'safe', + overClass: 'over', + thousandSeparator: ',', + onOverCount: function(){}, + onSafeCount: function(){}, + onMaxCount: function(){}, }, options); - var navKeys = [33,34,35,36,37,38,39,40]; + var navKeys = [33, 34, 35, 36, 37, 38, 39, 40]; return $(this).each(function() { - - var countable = $(this), - counter = $(options.counter); + var countable = $(this); + var counter = $(options.counter); if (!counter.length) { return false; } var countCheck = function() { - var count; var revCount; @@ -862,7 +806,7 @@ if ( jQuery !== 'undefined' ) { prefix = '-'; } for (var i = ct.length - 3; i > 0; i -= 3){ - ct = ct.substr(0,i) + options.thousandSeparator + ct.substr(i); + ct = ct.substr(0, i) + options.thousandSeparator + ct.substr(i); } } return prefix + ct; @@ -888,7 +832,7 @@ if ( jQuery !== 'undefined' ) { options.onMaxCount(countInt(), countable, counter); } if (options.countType === 'words') { - var allowedText = content.match( new RegExp('\\s?(\\S+\\s+){'+ options.maxCount +'}') ); + var allowedText = content.match(new RegExp('\\s?(\\S+\\s+){' + options.maxCount + '}')); if (allowedText) { changeCountableValue(allowedText[0]); } @@ -912,7 +856,6 @@ if ( jQuery !== 'undefined' ) { counter.removeClass(options.overClass).addClass(options.safeClass); options.onSafeCount(countInt(), countable, counter); } - }; countCheck(); @@ -932,374 +875,366 @@ if ( jQuery !== 'undefined' ) { break; } }); - }); - }; - })(jQuery);/*! relevance - v2.1.0 - 2015-03-04 * https://github.com/bboyle/relevance * Copyright (c) 2015 Ben Boyle; Licensed MIT */ -if ( jQuery !== 'undefined' ) { - (function( $ ) { +if (jQuery !== 'undefined') { + (function($) { 'use strict'; - var relevantEvent = 'relevant', - irrelevantEvent = 'irrelevant', - elementsToDisable = 'button, input, select, textarea', - polyfillHidden = (function() { - var hidden = $( '' ); - var hiddenSupported = hidden.appendTo( 'body' ).is( ':hidden' ); - hidden.remove(); - return ! hiddenSupported; - }()), - - formElementsByName = function( form, name ) { - // filter out the @id matching of HTMLFormElement.elements[] - return $( form.elements[ name ] ).filter( '[name="' + name + '"]' ); - }, + var relevantEvent = 'relevant'; + var irrelevantEvent = 'irrelevant'; + var elementsToDisable = 'button, input, select, textarea'; + var polyfillHidden = (function() { + var hidden = $(''); + var hiddenSupported = hidden.appendTo('body').is(':hidden'); + hidden.remove(); + return !hiddenSupported; + }()); + + var formElementsByName = function(form, name) { + // filter out the @id matching of HTMLFormElement.elements[] + return $(form.elements[name]).filter('[name="' + name + '"]'); + }; - filterRelevant = function() { - return $( this ).closest( '[hidden]' ).length === 0; - }, + var filterRelevant = function() { + return $(this).closest('[hidden]').length === 0; + }; - filterIrrelevant = function() { - return $( this ).closest( '[hidden]' ).length > 0; - }, + var filterIrrelevant = function() { + return $(this).closest('[hidden]').length > 0; + }; - valueMap = function( element ) { - return element.value; - }, + var valueMap = function(element) { + return element.value; + }; - valueInArray = function( possibleValues, actualValues ) { - var i; - if ( typeof possibleValues !== 'object' ) { - possibleValues = [possibleValues]; - } + var valueInArray = function(possibleValues, actualValues) { + var i; + if (typeof possibleValues !== 'object') { + possibleValues = [possibleValues]; + } - for ( i = 0; i < actualValues.length; i++ ) { - if ( $.inArray( actualValues[ i ], possibleValues ) !== -1 ) { - return true; - } + for (i = 0; i < actualValues.length; i++) { + if ($.inArray(actualValues[i], possibleValues) !== -1) { + return true; } + } - return false; - }, + return false; + }; - // when changing a control that alters relevance of other elements… - recalculateRelevance = function() { - // assume dependency map exists - var map = $( this.form ).data( 'relevance' ).dependencyMap[ this.name ], - values = $.map( formElementsByName( this.form, this.name ).filter( 'select,:checked' ).filter( ':visible' ), valueMap ) + // when changing a control that alters relevance of other elements… + var recalculateRelevance = function() { + // assume dependency map exists + var map = $(this.form).data('relevance').dependencyMap[this.name]; + var values = $.map(formElementsByName(this.form, this.name).filter('select,:checked').filter(':visible'), valueMap) ; - $.each( map, function( index, config ) { - config.items.relevance( 'relevant', valueInArray( config.values, values ) !== config.negate ); - }); - }, + $.each(map, function(index, config) { + config.items.relevance('relevant', valueInArray(config.values, values) !== config.negate); + }); + }; - // when an element changes relevance, check descendent controls that alter relevance in turn… - recalculateDependents = function( isRelevant ) { - var form, - dependencyMap, - targets; - - // any change to relevant toggles? - form = this.closest( 'form' ); - if ( form.length ) { - dependencyMap = form.data( 'relevance' ); - if ( typeof dependencyMap === 'object' ) { - dependencyMap = dependencyMap.dependencyMap; - if ( typeof dependencyMap === 'object' ) { - // get descendent-or-self select, radio and checkbox - targets = this.add( this.find( 'select,input' )).filter( 'select,:radio,:checkbox' ); - // get unique @name for select, radio and checkbox - targets = $.unique( $.map( targets, function( elementOfArray ) { - return elementOfArray.name; - })); - $.each( targets, function( index, name ) { - var map = dependencyMap[ name ], - values; - - if ( typeof map === 'object' ) { - $.each( map, function( index, config ) { - if ( isRelevant === false ) { - config.items.relevance( 'relevant', false ); - - } else { - values = $.map( formElementsByName( form[ 0 ], name ).filter( 'select,:checked' ).filter( ':visible' ), valueMap ); - config.items.relevance( 'relevant', valueInArray( config.values, values ) !== config.negate ); - } - }); - } - }); - } + // when an element changes relevance, check descendent controls that alter relevance in turn… + var recalculateDependents = function(isRelevant) { + var form, + dependencyMap, + targets; + + // any change to relevant toggles? + form = this.closest('form'); + if (form.length) { + dependencyMap = form.data('relevance'); + if (typeof dependencyMap === 'object') { + dependencyMap = dependencyMap.dependencyMap; + if (typeof dependencyMap === 'object') { + // get descendent-or-self select, radio and checkbox + targets = this.add(this.find('select,input')).filter('select,:radio,:checkbox'); + // get unique @name for select, radio and checkbox + targets = $.unique($.map(targets, function(elementOfArray) { + return elementOfArray.name; + })); + $.each(targets, function(index, name) { + var map = dependencyMap[name]; + var values; + + if (typeof map === 'object') { + $.each(map, function(index, config) { + if (isRelevant === false) { + config.items.relevance('relevant', false); + } else { + values = $.map(formElementsByName(form[0], name).filter('select,:checked').filter(':visible'), valueMap); + config.items.relevance('relevant', valueInArray(config.values, values) !== config.negate); + } + }); + } + }); } } + } + }; + + var methods = { + + // $( x ).relevance( 'relevant', true ) + // if the element is hidden, fire a 'relevant' event + // $( x ).relevance( 'relevant', false ) + // if the element is visible, fire an "irrelevant" event + relevant: function(makeRelevant) { + var targets; + if (makeRelevant) { + targets = this.filter(filterIrrelevant).trigger(relevantEvent); + } else { + targets = this.filter(filterRelevant).trigger(irrelevantEvent); + } + if (targets.length) { + recalculateDependents.call(targets, makeRelevant); + } + return this; }, + // $( x ).relevance( 'show' ) + // shows the element (does not check if element is already visible) + // triggers 'relevant-done' after showing is complete + show: function() { + // enable elements before they are shown + this.add(this.find(elementsToDisable)) + // but not any controls that will remain irrelevant + .not(this.find('[hidden]').find(elementsToDisable)) + .each(function() { + this.removeAttribute('disabled'); + }); - methods = { + // stop animation, remove @hidden and @aria-hidden, start showing + if (polyfillHidden) { + this.stop(true, true).slideDown(); + } + return this.removeAttr('hidden').removeAttr('aria-hidden'); + }, - // $( x ).relevance( 'relevant', true ) - // if the element is hidden, fire a 'relevant' event - // $( x ).relevance( 'relevant', false ) - // if the element is visible, fire an "irrelevant" event - relevant: function( makeRelevant ) { - var targets; - if ( makeRelevant ) { - targets = this.filter( filterIrrelevant ).trigger( relevantEvent ); - } else { - targets = this.filter( filterRelevant ).trigger( irrelevantEvent ); - } - if ( targets.length ) { - recalculateDependents.call( targets, makeRelevant ); - } - return this; - }, - - // $( x ).relevance( 'show' ) - // shows the element (does not check if element is already visible) - // triggers 'relevant-done' after showing is complete - show: function() { - // enable elements before they are shown - this.add( this.find( elementsToDisable )) - // but not any controls that will remain irrelevant - .not( this.find( '[hidden]' ).find( elementsToDisable )) - .each(function() { - this.removeAttribute( 'disabled' ); - }); + // $( x ).relevance( 'hide' ) + // hides the element (does not check if element is already hidden) + hide: function() { + this.attr({ + hidden: 'hidden', + 'aria-hidden': 'true', + }); - // stop animation, remove @hidden and @aria-hidden, start showing - if ( polyfillHidden ) { - this.stop( true, true ).slideDown(); - } - return this.removeAttr( 'hidden' ).removeAttr( 'aria-hidden' ); - }, - - // $( x ).relevance( 'hide' ) - // hides the element (does not check if element is already hidden) - hide: function() { - this.attr({ - hidden: 'hidden', - 'aria-hidden': 'true' + if (polyfillHidden) { + this.stop(true, true).hide(0, function() { + var $this = $(this); + // disable elements (including self if appropriate) + $this.filter(elementsToDisable).add($this.find(elementsToDisable)).each(function() { + this.setAttribute('disabled', 'disabled'); + }); + }); + } else { + this.filter(elementsToDisable).add(this.find(elementsToDisable)).each(function() { + this.setAttribute('disabled', 'disabled'); }); + } - if ( polyfillHidden ) { - this.stop( true, true ).hide( 0, function() { - var $this = $( this ); - // disable elements (including self if appropriate) - $this.filter( elementsToDisable ).add( $this.find( elementsToDisable )).each(function() { - this.setAttribute( 'disabled', 'disabled' ); - }); - }); - } else { - this.filter( elementsToDisable ).add( this.find( elementsToDisable )).each(function() { - this.setAttribute( 'disabled', 'disabled' ); - }); - } + return this; + }, - return this; - }, - - // $( x ).relevance( 'relevantWhen', { name: radio/checkbox/select, value: requiredValue, negate: false | true }) - // sets up dependent relevance - // example: $( '#red' ).relevance( 'relevantWhen', { name: 'rgb', value: 'red' }) - // example: $( '#red' ).relevance( 'relevantWhen', { id: 'rgb-red', value: 'red' }) - // #red will be shown/hidden when '@name=rgb' value changes. - relevantWhen: function( config ) { - var form, - data, - name, - values; - - values = config.values || [config.value]; - - if ( config.name ) { - name = config.name; - } else if ( config.id ) { - name = document.getElementById( config.id ).name; - } else if ( config.container ) { - name = $( config.container ).find( 'select,:radio,:checkbox' ).attr( 'name' ); - } - config.negate = config.negate === true; - - // find the form that has this control - form = this.closest( 'form' ); - // get dependency map (create it if needed) - data = form.data( 'relevance' ); - if ( typeof data !== 'object' ) { - data = {}; - form.data( 'relevance', data ); - } - if ( typeof data.dependencyMap !== 'object' ) { - data.dependencyMap = {}; - } - if ( typeof data.dependencyMap[ name ] !== 'object' ) { - data.dependencyMap[ name ] = []; - // setup event handlers for name - formElementsByName( form[ 0 ], name ) - .filter( ':radio,:checkbox' ) - .on( 'click', recalculateRelevance ) - .end() - .filter( 'select' ) - .on( 'change', recalculateRelevance ) - ; - } - // add or update relevance rule - data.dependencyMap[ name ].push({ - items: this, - values: values, - negate: config.negate - }); + // $( x ).relevance( 'relevantWhen', { name: radio/checkbox/select, value: requiredValue, negate: false | true }) + // sets up dependent relevance + // example: $( '#red' ).relevance( 'relevantWhen', { name: 'rgb', value: 'red' }) + // example: $( '#red' ).relevance( 'relevantWhen', { id: 'rgb-red', value: 'red' }) + // #red will be shown/hidden when '@name=rgb' value changes. + relevantWhen: function(config) { + var form, + data, + name, + values; + + values = config.values || [config.value]; + + if (config.name) { + name = config.name; + } else if (config.id) { + name = document.getElementById(config.id).name; + } else if (config.container) { + name = $(config.container).find('select,:radio,:checkbox').attr('name'); + } + config.negate = config.negate === true; + + // find the form that has this control + form = this.closest('form'); + // get dependency map (create it if needed) + data = form.data('relevance'); + if (typeof data !== 'object') { + data = {}; + form.data('relevance', data); + } + if (typeof data.dependencyMap !== 'object') { + data.dependencyMap = {}; + } + if (typeof data.dependencyMap[name] !== 'object') { + data.dependencyMap[name] = []; + // setup event handlers for name + formElementsByName(form[0], name) + .filter(':radio,:checkbox') + .on('click', recalculateRelevance) + .end() + .filter('select') + .on('change', recalculateRelevance) + ; + } + // add or update relevance rule + data.dependencyMap[name].push({ + items: this, + values: values, + negate: config.negate, + }); - // initial relevance - this.relevance( 'relevant', valueInArray( values, $.map( formElementsByName( form[ 0 ], name ).filter( 'select,:checked' ).filter( ':visible' ), valueMap )) !== config.negate ); - - return this; - }, - - // $( x ).relevance( 'instructions', options ) - // sets up relevance handling based on text instructions - // options ::= { instructions: '.relevance', questions: '.questions > li' } - instructions: function( options ) { - options = $.extend( { - instructionSelector: '.relevance', - questionSelector: '.questions > li' - }, options ); - - this.find( options.instructionSelector ).each(function() { - var $this = $( this ), - value = $this.text(), - question = $this.closest( options.questionSelector ), - toggle = question.prevAll( options.questionSelector ), - i, - answers, - nestedToggles, - match = false, - negate = false; - - // pattern: (If different to ) - if ( /If different to/.test( value )) { - // assume previous 'li' is the toggle - match = true; - toggle = toggle.eq( 0 ); - value = toggle.find( ':checkbox' ).val(); - negate = true; - } else { - value = value.replace( /^.*chose\s+\S([^'"’]+)\S\s+above.*$/, '$1' ); - // which of the previous questions is the toggle? - i = 0; - while ( i < toggle.length ) { - // does this item have the answer we need? - answers = $.map( toggle.eq( i ).find( 'option,:radio,:checkbox' ), valueMap ); - if ( valueInArray( value, answers )) { - nestedToggles = toggle.eq( i ).find( options.questionSelector ); - if ( nestedToggles.length ) { - toggle = $( nestedToggles.get().reverse() ); - i = 0; - } else { - match = true; - toggle = toggle.eq( i ); // toggle.length becomes 1, loop will exit - i = 1; // exit loop - } + // initial relevance + this.relevance('relevant', valueInArray(values, $.map(formElementsByName(form[0], name).filter('select,:checked').filter(':visible'), valueMap)) !== config.negate); + + return this; + }, + + // $( x ).relevance( 'instructions', options ) + // sets up relevance handling based on text instructions + // options ::= { instructions: '.relevance', questions: '.questions > li' } + instructions: function(options) { + options = $.extend({ + instructionSelector: '.relevance', + questionSelector: '.questions > li', + }, options); + + this.find(options.instructionSelector).each(function() { + var $this = $(this); + var value = $this.text(); + var question = $this.closest(options.questionSelector); + var toggle = question.prevAll(options.questionSelector); + var i; + var answers; + var nestedToggles; + var match = false; + var negate = false; + + // pattern: (If different to ) + if (/If different to/.test(value)) { + // assume previous 'li' is the toggle + match = true; + toggle = toggle.eq(0); + value = toggle.find(':checkbox').val(); + negate = true; + } else { + value = value.replace(/^.*chose\s+\S([^'"’]+)\S\s+above.*$/, '$1'); + // which of the previous questions is the toggle? + i = 0; + while (i < toggle.length) { + // does this item have the answer we need? + answers = $.map(toggle.eq(i).find('option,:radio,:checkbox'), valueMap); + if (valueInArray(value, answers)) { + nestedToggles = toggle.eq(i).find(options.questionSelector); + if (nestedToggles.length) { + toggle = $(nestedToggles.get().reverse()); + i = 0; } else { - i++; + match = true; + toggle = toggle.eq(i); // toggle.length becomes 1, loop will exit + i = 1; // exit loop } + } else { + i++; } } - if ( match ) { - toggle = toggle.add( toggle.find( 'select,input' )).filter( 'select,:radio,:checkbox' ); - question.relevance( 'relevantWhen', { name: toggle.attr( 'name' ), value: value, negate: negate }); - } - }); - return this; - } - }; + } + if (match) { + toggle = toggle.add(toggle.find('select,input')).filter('select,:radio,:checkbox'); + question.relevance('relevantWhen', { name: toggle.attr('name'), value: value, negate: negate }); + } + }); + return this; + }, + }; // fallback (default) event handling - $( document ).on( 'relevant irrelevant', function( event ) { - var target = $( event.target ); - if ( event.type === 'relevant' ) { - target.relevance( 'show' ); + $(document).on('relevant irrelevant', function(event) { + var target = $(event.target); + if (event.type === 'relevant') { + target.relevance('show'); } else { - target.relevance( 'hide' ); + target.relevance('hide'); } }); - $.fn.relevance = function( method ) { + $.fn.relevance = function(method) { // Method calling logic // http://docs.jquery.com/Plugins/Authoring#Plugin_Methods - if ( methods[method] ) { - return methods[ method ].apply( this, Array.prototype.slice.call(arguments, 1 )); - } else if ( typeof method === 'object' || !method ) { + if (methods[method]) { + return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); + } else if (typeof method === 'object' || !method) { // return methods.init.apply( this, arguments ); return this; } else { - $.error( 'Method ' + method + ' does not exist on jQuery.relevance' ); + $.error('Method ' + method + ' does not exist on jQuery.relevance'); } }; - }( jQuery )); + }(jQuery)); } -(function( $ ) { +(function($) { 'use strict'; // window.console.log( 'file-size-validation.js' ); var displayFileSize; - // bail out if no file API support - if ( typeof $( '' )[ 0 ].files !== 'object' ) { + if (typeof $('')[0].files !== 'object') { // duplicate fsize instruction before submit button - $( '.max-fsize' ).each(function() { - var fsize = $( this ), - form; - form = fsize.closest( '.preamble' ).nextAll( 'form' ).eq( 0 ); - form.find( '.actions' ).before( '

        ' + fsize.parent().html() + '

        ' ); + $('.max-fsize').each(function() { + var fsize = $(this); + var form; + form = fsize.closest('.preamble').nextAll('form').eq(0); + form.find('.actions').before('

        ' + fsize.parent().html() + '

        '); }); return; } - // display file size - displayFileSize = function( input ) { - input.nextAll( '.fsize' ).remove(); - if ( input[ 0 ].files.length > 0 ) { - var filesize = input[ 0 ].files[ 0 ].size / 1024; + displayFileSize = function(input) { + input.nextAll('.fsize').remove(); + if (input[0].files.length > 0) { + var filesize = input[0].files[0].size / 1024; - if ( filesize >= 1024 ) { + if (filesize >= 1024) { filesize = filesize / 1024; - input.after( 'File size: ' + ( Math.round( filesize * 10 ) / 10 ) + 'MB' + '' ); + input.after('File size: ' + (Math.round(filesize * 10) / 10) + 'MB' + ''); } else { - input.after( 'File size: ' + ( Math.round( filesize * 10 ) / 10 ) + 'KB' + '' ); + input.after('File size: ' + (Math.round(filesize * 10) / 10) + 'KB' + ''); } } }; - // forms with max file size $('.max-fsize').each(function() { - var fsize = $( this ), - form, - maxFileSize; + var fsize = $(this); + var form; + var maxFileSize; // read fsize, assume MB - maxFileSize = parseInt( fsize.text().replace( /\D+/g, '' ), 10 ) * 1024 * 1024; + maxFileSize = parseInt(fsize.text().replace(/\D+/g, ''), 10) * 1024 * 1024; // window.console.log( 'found max fsize', maxFileSize ); // get form (closest form after the preamble) - form = fsize.closest( '.preamble' ).nextAll( 'form' ).eq( 0 ); + form = fsize.closest('.preamble').nextAll('form').eq(0); - form.find( ':file' ).on( 'change', function() { - var input = $( this ); + form.find(':file').on('change', function() { + var input = $(this); - displayFileSize( input ); + displayFileSize(input); // recalculate file sizes - var total = 0, - valid; - $( ':file', this.form ).each(function( index, element ) { - var size = element.files.length ? element.files[ 0 ].size : 0; + var total = 0; + var valid; + $(':file', this.form).each(function(index, element) { + var size = element.files.length ? element.files[0].size : 0; total += size; // total = total + size; }); @@ -1308,148 +1243,138 @@ if ( jQuery !== 'undefined' ) { // window.console.info( 'file size validation:', total, '<', maxFileSize, total < maxFileSize ); - $( ':file', this.form ) + $(':file', this.form) // update validity for :file inputs with values .filter(function() { return !!this.value; }) - .each(function( index, element ) { - element.setCustomValidity( valid ? '' : 'Attachments are too large' ); + .each(function(index, element) { + element.setCustomValidity(valid ? '' : 'Attachments are too large'); }) // blank :file inputs should not have a custom error .filter(function() { - return ! this.value; + return !this.value; }) - .each(function( index, element ) { - element.setCustomValidity( '' ); + .each(function(index, element) { + element.setCustomValidity(''); }); - }); - }); - -}( jQuery )); -(function( $ ) { +}(jQuery)); +(function($) { 'use strict'; - var xorConstraintSubmitHandler = function( event ) { - // has one of the required fields been answered? - var xorFields = event.data[ 0 ], - validationMessage = event.data[ 1 ], - xorConstraintMet = xorFields.filter(function() { - return this.value.length > 1; - }).length > 0 + var xorConstraintSubmitHandler = function(event) { + // has one of the required fields been answered? + var xorFields = event.data[0]; + var validationMessage = event.data[1]; + var xorConstraintMet = xorFields.filter(function() { + return this.value.length > 1; + }).length > 0 ; - xorFields.each(function() { - this.setCustomValidity( - xorConstraintMet ? '' : validationMessage - ); - }); - }, + xorFields.each(function() { + this.setCustomValidity( + xorConstraintMet ? '' : validationMessage, + ); + }); + }; - xorConstraintChangeHandler = function( event, validationUiRefreshOnly ) { - if ( validationUiRefreshOnly === true ) { - // pass through to other change handlers - return; - } + var xorConstraintChangeHandler = function(event, validationUiRefreshOnly) { + if (validationUiRefreshOnly === true) { + // pass through to other change handlers + return; + } - var xorFields = event.data[ 0 ]; + var xorFields = event.data[0]; - // constraint validity check - xorConstraintSubmitHandler( event ); + // constraint validity check + xorConstraintSubmitHandler(event); - // trigger validation UI on other fields? - if ( event.type === 'change' ) { - xorFields.not( event.target ).triggerHandler( 'change', true ); - } + // trigger validation UI on other fields? + if (event.type === 'change') { + xorFields.not(event.target).triggerHandler('change', true); } + } ; - // plugin - $.fn.initXorConstraint = function( validationMessage ) { + $.fn.initXorConstraint = function(validationMessage) { // custom validation for XOR options - this.closest( 'form' ).on( 'submit', [this, validationMessage], xorConstraintSubmitHandler ); - this.on( 'change', [this, validationMessage], xorConstraintChangeHandler ); + this.closest('form').on('submit', [this, validationMessage], xorConstraintSubmitHandler); + this.on('change', [this, validationMessage], xorConstraintChangeHandler); }; }(jQuery)); -(function( $ ){ +(function($){ 'use strict'; - /* detect required field markers for IE6 */ - $( 'abbr[title*="required"]' ).addClass( 'required' ); - + $('abbr[title*="required"]').addClass('required'); // show/hide entire 'question' when fields become irrelevant - $( '.questions > li' ).not( '.section' ) - .on( 'relevant', function( event ) { - $( this ).relevance( 'show' ); + $('.questions > li').not('.section') + .on('relevant', function(event) { + $(this).relevance('show'); event.stopImmediatePropagation(); }) - .on( 'irrelevant', function( event ) { - $( this ).relevance( 'hide' ); + .on('irrelevant', function(event) { + $(this).relevance('hide'); event.stopImmediatePropagation(); }) ; - // click the table cell to click on a matrix option - $( '.matrix' ).delegate( 'td', 'click', function( evt ) { - $( evt.target ) - .find( 'input' ) - .trigger( 'click' ) - .trigger( 'change' ) + $('.matrix').delegate('td', 'click', function(evt) { + $(evt.target) + .find('input') + .trigger('click') + .trigger('change') ; }); - -}( jQuery )); - +}(jQuery)); /** * This file initialises forms */ -(function( $ ) { /* start closure */ +(function($) { /* start closure */ 'use strict'; var initValidation = function() { window.initConstraintValidationAPI(); - $( 'form' ).formValidation( 'validate' ); + $('form').formValidation('validate'); }; // now: hookup form validation initValidation(); // document ready: hookup form validation - $( initValidation ); + $(initValidation); // instruction based relevance - if ( $( '.relevance', 'form' ).length > 0 ) { - $('#qg-primary-content form').relevance( 'instructions' ); + if ($('.relevance', 'form').length > 0) { + $('#qg-primary-content form').relevance('instructions'); } }(jQuery)); /* end closure */ (function($) { 'use strict'; - // extend jquery to 'toggle required' - $.fn.toggleRequired = function( required ) { + $.fn.toggleRequired = function(required) { return this.each(function() { - var controls = $( this.form.elements[ this.name ] ), - question = $( this ).closest( '.questions > li' ); + var controls = $(this.form.elements[this.name]); + var question = $(this).closest('.questions > li'); - if ( required ) { - if ( question.find( 'abbr[title="(required)"]' ).length === 0 ) { - question.find( '.label' ).after( + if (required) { + if (question.find('abbr[title="(required)"]').length === 0) { + question.find('.label').after( // create ABBR shiv for IE6 - $( document.createElement( 'abbr' )) - .attr( 'title' , '(required)' ) - .text( '*' ) - .addClass( 'required' ) + $(document.createElement('abbr')) + .attr('title', '(required)') + .text('*') + .addClass('required'), ); } - controls.attr( 'required', 'required' ); + controls.attr('required', 'required'); } else { - controls.removeAttr( 'required' ); - question.find( 'abbr[title="(required)"]' ).remove(); + controls.removeAttr('required'); + question.find('abbr[title="(required)"]').remove(); } }); }; @@ -1460,137 +1385,135 @@ var qg = { oldIE: false }; qg.date = (function() { 'use strict'; - - var datePackage = {}, - - // Public holiday dates for 2010-2014 (viewed 2012-09-28) - // http://www.justice.qld.gov.au/fair-and-safe-work/industrial-relations/public-holidays/dates - qldHolidays = { - // 2010 - '2010-01-01' : 'New Year’s Day', - '2010-01-26' : 'Australia Day', - '2010-04-02' : 'Good Friday', - '2010-04-03' : 'Easter Saturday', - '2010-04-05' : 'Easter Monday', - '2010-04-26' : 'Anzac Day', - '2010-05-03' : 'Labour Day', - '2010-06-14' : 'Queen’s Birthday', - '2010-12-25' : 'Christmas Day', - '2010-12-27' : 'Boxing Day', - '2010-12-28' : 'Christmas Day holiday', - - // 2011 - '2011-01-01' : 'New Year’s Day', - '2011-01-03' : 'New Year’s Day holiday', - '2011-02-26' : 'Australia Day', - '2011-04-22' : 'Good Friday', - '2011-04-23' : 'Easter Saturday', - '2011-04-25' : 'Anzac Day', - '2011-04-26' : 'Easter Monday', - '2011-05-02' : 'Labour Day', - '2011-06-13' : 'Queen’s Birthday', - '2011-12-25' : 'Christmas Day', - '2011-12-26' : 'Boxing Day', - '2011-12-27' : 'Christmas Day holiday', - - // 2012 - '2012-01-01' : 'New Year’s Day', - '2012-01-02' : 'New Year’s Day holiday', - '2012-02-26' : 'Australia Day', - '2012-04-06' : 'Good Friday', - '2012-04-07' : 'Easter Saturday', - '2012-04-09' : 'Easter Monday', - '2012-04-25' : 'Anzac Day', - '2012-05-07' : 'Labour Day', - '2012-06-11' : 'Queen’s Diamond Jubilee', - '2012-10-01' : 'Queen’s Birthday', - '2012-12-25' : 'Christmas Day', - '2012-12-26' : 'Boxing Day', - - // 2013 - '2013-01-01' : 'New Year’s Day', - '2013-01-28' : 'Australia Day holiday', - '2013-03-29' : 'Good Friday', - '2013-03-30' : 'Easter Saturday', - '2013-04-01' : 'Easter Monday', - '2013-04-25' : 'Anzac Day', - '2013-06-10' : 'Queen’s Birthday', - '2013-10-07' : 'Labour Day', - '2013-12-25' : 'Christmas Day', - '2013-12-26' : 'Boxing Day', - - // 2014 - '2014-01-01' : 'New Year’s Day', - '2014-01-27' : 'Australia Day holiday', - '2014-04-18' : 'Good Friday', - '2014-04-19' : 'Easter Saturday', - '2014-04-21' : 'Easter Monday', - '2014-04-25' : 'Anzac Day', - '2014-06-09' : 'Queen’s Birthday', - '2014-10-06' : 'Labour Day', - '2014-12-25' : 'Christmas Day', - '2014-12-26' : 'Boxing Day', - - // 2015 - '2015-01-01' : 'New Year’s Day', - '2015-01-26' : 'Australia Day holiday', - '2015-04-03' : 'Good Friday', - '2015-04-04' : 'Easter Saturday', - '2015-04-06' : 'Easter Monday', - '2015-04-25' : 'Anzac Day', - '2015-06-08' : 'Queen’s Birthday', - '2015-10-05' : 'Labour Day', - '2015-12-25' : 'Christmas Day', - '2015-12-26' : 'Boxing Day', - '2015-12-28' : 'Boxing Day holiday', - - // 2016 - '2016-01-01' : 'New Year’s Day', - '2016-01-26' : 'Australia Day holiday', - '2016-03-25' : 'Good Friday', - '2016-03-26' : 'Easter Saturday', - '2016-03-28' : 'Easter Monday', - '2016-04-25' : 'Anzac Day', - '2016-06-13' : 'Queen’s Birthday', - '2016-10-03' : 'Labour Day', - '2016-12-25' : 'Christmas Day', - '2016-12-27' : 'Christmas Day holiday', - '2016-12-26' : 'Boxing Day', - - // 2017 - '2017-01-01' : 'New Year’s Day', - '2017-01-02' : 'New Year’s Day holiday', - '2017-01-26' : 'Australia Day holiday', - '2017-04-14' : 'Good Friday', - '2017-04-15' : 'Easter Saturday', - '2017-04-17' : 'Easter Monday', - '2017-04-25' : 'Anzac Day', - '2017-06-12' : 'Queen’s Birthday', - '2017-10-02' : 'Labour Day', - '2017-12-25' : 'Christmas Day', - '2017-12-26' : 'Boxing Day', - - // 2018 - '2018-01-01' : 'New Year’s Day', - '2018-01-26' : 'Australia Day holiday', - '2018-03-30' : 'Good Friday', - '2018-03-31' : 'Easter Saturday', - '2018-04-02' : 'Easter Monday', - '2018-04-25' : 'Anzac Day', - '2018-05-07' : 'Labour Day', - '2018-10-01' : 'Queen’s Birthday', - '2018-12-25' : 'Christmas Day', - '2018-12-26' : 'Boxing Day' - } + var datePackage = {}; + + // Public holiday dates for 2010-2014 (viewed 2012-09-28) + // http://www.justice.qld.gov.au/fair-and-safe-work/industrial-relations/public-holidays/dates + var qldHolidays = { + // 2010 + '2010-01-01': 'New Year’s Day', + '2010-01-26': 'Australia Day', + '2010-04-02': 'Good Friday', + '2010-04-03': 'Easter Saturday', + '2010-04-05': 'Easter Monday', + '2010-04-26': 'Anzac Day', + '2010-05-03': 'Labour Day', + '2010-06-14': 'Queen’s Birthday', + '2010-12-25': 'Christmas Day', + '2010-12-27': 'Boxing Day', + '2010-12-28': 'Christmas Day holiday', + + // 2011 + '2011-01-01': 'New Year’s Day', + '2011-01-03': 'New Year’s Day holiday', + '2011-02-26': 'Australia Day', + '2011-04-22': 'Good Friday', + '2011-04-23': 'Easter Saturday', + '2011-04-25': 'Anzac Day', + '2011-04-26': 'Easter Monday', + '2011-05-02': 'Labour Day', + '2011-06-13': 'Queen’s Birthday', + '2011-12-25': 'Christmas Day', + '2011-12-26': 'Boxing Day', + '2011-12-27': 'Christmas Day holiday', + + // 2012 + '2012-01-01': 'New Year’s Day', + '2012-01-02': 'New Year’s Day holiday', + '2012-02-26': 'Australia Day', + '2012-04-06': 'Good Friday', + '2012-04-07': 'Easter Saturday', + '2012-04-09': 'Easter Monday', + '2012-04-25': 'Anzac Day', + '2012-05-07': 'Labour Day', + '2012-06-11': 'Queen’s Diamond Jubilee', + '2012-10-01': 'Queen’s Birthday', + '2012-12-25': 'Christmas Day', + '2012-12-26': 'Boxing Day', + + // 2013 + '2013-01-01': 'New Year’s Day', + '2013-01-28': 'Australia Day holiday', + '2013-03-29': 'Good Friday', + '2013-03-30': 'Easter Saturday', + '2013-04-01': 'Easter Monday', + '2013-04-25': 'Anzac Day', + '2013-06-10': 'Queen’s Birthday', + '2013-10-07': 'Labour Day', + '2013-12-25': 'Christmas Day', + '2013-12-26': 'Boxing Day', + + // 2014 + '2014-01-01': 'New Year’s Day', + '2014-01-27': 'Australia Day holiday', + '2014-04-18': 'Good Friday', + '2014-04-19': 'Easter Saturday', + '2014-04-21': 'Easter Monday', + '2014-04-25': 'Anzac Day', + '2014-06-09': 'Queen’s Birthday', + '2014-10-06': 'Labour Day', + '2014-12-25': 'Christmas Day', + '2014-12-26': 'Boxing Day', + + // 2015 + '2015-01-01': 'New Year’s Day', + '2015-01-26': 'Australia Day holiday', + '2015-04-03': 'Good Friday', + '2015-04-04': 'Easter Saturday', + '2015-04-06': 'Easter Monday', + '2015-04-25': 'Anzac Day', + '2015-06-08': 'Queen’s Birthday', + '2015-10-05': 'Labour Day', + '2015-12-25': 'Christmas Day', + '2015-12-26': 'Boxing Day', + '2015-12-28': 'Boxing Day holiday', + + // 2016 + '2016-01-01': 'New Year’s Day', + '2016-01-26': 'Australia Day holiday', + '2016-03-25': 'Good Friday', + '2016-03-26': 'Easter Saturday', + '2016-03-28': 'Easter Monday', + '2016-04-25': 'Anzac Day', + '2016-06-13': 'Queen’s Birthday', + '2016-10-03': 'Labour Day', + '2016-12-25': 'Christmas Day', + '2016-12-27': 'Christmas Day holiday', + '2016-12-26': 'Boxing Day', + + // 2017 + '2017-01-01': 'New Year’s Day', + '2017-01-02': 'New Year’s Day holiday', + '2017-01-26': 'Australia Day holiday', + '2017-04-14': 'Good Friday', + '2017-04-15': 'Easter Saturday', + '2017-04-17': 'Easter Monday', + '2017-04-25': 'Anzac Day', + '2017-06-12': 'Queen’s Birthday', + '2017-10-02': 'Labour Day', + '2017-12-25': 'Christmas Day', + '2017-12-26': 'Boxing Day', + + // 2018 + '2018-01-01': 'New Year’s Day', + '2018-01-26': 'Australia Day holiday', + '2018-03-30': 'Good Friday', + '2018-03-31': 'Easter Saturday', + '2018-04-02': 'Easter Monday', + '2018-04-25': 'Anzac Day', + '2018-05-07': 'Labour Day', + '2018-10-01': 'Queen’s Birthday', + '2018-12-25': 'Christmas Day', + '2018-12-26': 'Boxing Day', + } ; - // is a public holiday - datePackage.isPublicHoliday = function( date ) { - var d = date.getDate(), - m = date.getMonth() + 1, - y = String( date.getFullYear() ), - dateString = y + ( m < 10 ? '-0' : '-' ) + m + ( d < 10 ? '-0' : '-' ) + d + datePackage.isPublicHoliday = function(date) { + var d = date.getDate(); + var m = date.getMonth() + 1; + var y = String(date.getFullYear()); + var dateString = y + (m < 10 ? '-0' : '-') + m + (d < 10 ? '-0' : '-') + d ; // return true, date is a public holiday @@ -1599,41 +1522,40 @@ qg.date = (function() { // TODO // return undefined, it is not known if the date is a public holiday (beyond 2 years in the future?) - return !!qldHolidays[ dateString ]; + return !!qldHolidays[dateString]; }; return datePackage; }()); (function($) { 'use strict'; - // find any textareas with a word count - $( '.hint' ).filter(function() { - return ( /Maximum:\s+\d+\s+words/ ).test( $( this ).text() ); + $('.hint').filter(function() { + return (/Maximum:\s+\d+\s+words/).test($(this).text()); }).each(function() { - var hint = $( this ), - max = parseInt( hint.text().replace( /Maximum:\s+(\d+)\s+words/, '$1' ), 10 ), - textField = hint.closest( 'label' ).nextAll( 'textarea' ), - counter; + var hint = $(this); + var max = parseInt(hint.text().replace(/Maximum:\s+(\d+)\s+words/, '$1'), 10); + var textField = hint.closest('label').nextAll('textarea'); + var counter; // add counter - counter = $( '' ).generateId( 'word-count' ); + counter = $('').generateId('word-count'); //eg. Maximum: 50 words (50 remaining) - hint.append( ' (', counter, ' remaining)' ); + hint.append(' (', counter, ' remaining)'); textField.simplyCountable({ - counter: '#' + counter[ 0 ].id, + counter: '#' + counter[0].id, countType: 'words', countDirection: 'down', maxCount: max, onOverCount: function() { - textField[ 0 ].setCustomValidity( 'Too many words' ); + textField[0].setCustomValidity('Too many words'); }, onSafeCount: function() { - textField[ 0 ].setCustomValidity( '' ); - } + textField[0].setCustomValidity(''); + }, }); }); -}( jQuery )); +}(jQuery)); //# sourceMappingURL=qg-forms.js.map diff --git a/src/assets/_project/_blocks/qg-main.js b/src/assets/_project/_blocks/qg-main.js index 0a2e5813f..654d1f469 100644 --- a/src/assets/_project/_blocks/qg-main.js +++ b/src/assets/_project/_blocks/qg-main.js @@ -24,7 +24,7 @@ import './components/site-search/qg-funnelback-v16-refs'; (function () { 'use strict'; - let franchiseTitle = window.qg.swe.franchiseTitle; + const franchiseTitle = window.qg.swe.franchiseTitle; activeSideNav.highlightNavItem(); stepNav.init(); feedbackForm.init(franchiseTitle); diff --git a/src/assets/_project/_blocks/utils/qg-datatables.js b/src/assets/_project/_blocks/utils/qg-datatables.js index 1681cafe5..c29be06fa 100644 --- a/src/assets/_project/_blocks/utils/qg-datatables.js +++ b/src/assets/_project/_blocks/utils/qg-datatables.js @@ -5,7 +5,7 @@ var addQGButtonClass = function () { $('.dataTable').each(function () { if (!$.fn.DataTable.isDataTable(this)) { $(this).DataTable({ - 'drawCallback': addQGButtonClass, + drawCallback: addQGButtonClass, }); } }); diff --git a/src/assets/_project/_blocks/utils/qg-load-google-api.js b/src/assets/_project/_blocks/utils/qg-load-google-api.js index dbd4ffb29..6c3addc22 100644 --- a/src/assets/_project/_blocks/utils/qg-load-google-api.js +++ b/src/assets/_project/_blocks/utils/qg-load-google-api.js @@ -26,7 +26,7 @@ export class QgLoadGoogleApi { **/ _checkEnvAndSetKey () { let googleApiKey; - let self = this; + const self = this; // if no franchise name identified then use the default key according to the environment if (window.location.hostname.search(/\bgithub\b/) !== -1) { googleApiKey = keys.defGoogle.docs; @@ -52,20 +52,20 @@ export class QgLoadGoogleApi { * @return {undefined} **/ _staticMaps () { - let googleApiKey = this._checkEnvAndSetKey(); + const googleApiKey = this._checkEnvAndSetKey(); var $mapImg = $('.qg-static-map'); function generateStaticMapImg (ele) { - let lat = ele.attr('data-lat') || -27.4673; - let lon = ele.attr('data-long') || 153.0233; - let zoom = ele.attr('data-zoom') || 17; - let height = ele.attr('data-height') || 189; + const lat = ele.attr('data-lat') || -27.4673; + const lon = ele.attr('data-long') || 153.0233; + const zoom = ele.attr('data-zoom') || 17; + const height = ele.attr('data-height') || 189; return 'https://maps.googleapis.com/maps/api/staticmap?size=373x' + height + '&maptype=roadmap&markers=' + lat + '%2C' + lon + '&key=' + googleApiKey + '&sensor=false&zoom=' + zoom; } // append static image on the maps description page if ($mapImg.length > 0) { var htmlInsert = $('
        '); $mapImg.each(function () { - let $this = $(this); + const $this = $(this); $this.find('img').attr('src', generateStaticMapImg($this.find('img'))); htmlInsert.append($this); }); @@ -81,11 +81,11 @@ export class QgLoadGoogleApi { * @return {undefined} **/ _loadGoogleApi (callback) { - let googleApiKey = this._checkEnvAndSetKey(); - let appendScript = url => { + const googleApiKey = this._checkEnvAndSetKey(); + const appendScript = url => { $('head').append(''); }; - let next = () => { + const next = () => { if (typeof callback === 'function') { callback(); } else { @@ -93,8 +93,8 @@ export class QgLoadGoogleApi { } }; if ($('#googleapi').length <= 0) { - let s = document.createElement('script'); - let u = `https://maps.googleapis.com/maps/api/js?key=${googleApiKey}®ion=AU&libraries=places`; + const s = document.createElement('script'); + const u = `https://maps.googleapis.com/maps/api/js?key=${googleApiKey}®ion=AU&libraries=places`; s.type = 'text/javascript'; s.id = 'googleapi'; s.src = u; diff --git a/src/assets/_project/_blocks/utils/qg-misc.js b/src/assets/_project/_blocks/utils/qg-misc.js index 971097525..8406518e0 100644 --- a/src/assets/_project/_blocks/utils/qg-misc.js +++ b/src/assets/_project/_blocks/utils/qg-misc.js @@ -12,8 +12,8 @@ if (name == null) return false; if (!url) url = window.location.href; name = name.replace(/[\\[\]]/g, '\\$&'); - let regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'); - let results = regex.exec(url); + const regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'); + const results = regex.exec(url); if (!results || !results[2]) return false; return decodeURIComponent(results[2].replace(/\+/g, ' ')); }; @@ -53,7 +53,7 @@ }); // check if a view is loaded in an iframe , this is to detect Squiz Matrix preview mode // and insert a class so that additional styles can be applied - let frameAttr = window.frameElement && window.frameElement.getAttribute('Name'); + const frameAttr = window.frameElement && window.frameElement.getAttribute('Name'); if (frameAttr && frameAttr === 'ees_modePreviewFrame') { $('.container-fluid').addClass('qg-edit-plus-styles'); } diff --git a/src/assets/_project/_blocks/utils/qg-quickexit.js b/src/assets/_project/_blocks/utils/qg-quickexit.js index 6f0d64e15..026fd9222 100644 --- a/src/assets/_project/_blocks/utils/qg-quickexit.js +++ b/src/assets/_project/_blocks/utils/qg-quickexit.js @@ -2,13 +2,13 @@ var handleQuickExit = function (e) { var $el = $('.qg-quick-exit'); if (document.documentElement.clientWidth > 992) { if ($(this).scrollTop() > 200) { - $el.css({ 'position': 'fixed', 'top': '0px' }); + $el.css({ position: 'fixed', top: '0px' }); } if ($(this).scrollTop() < 200) { - $el.css({ 'position': 'sticky', 'top': '0px' }); + $el.css({ position: 'sticky', top: '0px' }); } } else { - $el.css({ 'position': 'fixed', 'top': 'auto' }); + $el.css({ position: 'fixed', top: 'auto' }); } }; $(window).on('scroll', handleQuickExit); diff --git a/src/assets/_project/lib/ext/butterfly/jquery.butterfly.js b/src/assets/_project/lib/ext/butterfly/jquery.butterfly.js index 70edf2df1..9570de3b1 100644 --- a/src/assets/_project/lib/ext/butterfly/jquery.butterfly.js +++ b/src/assets/_project/lib/ext/butterfly/jquery.butterfly.js @@ -36,44 +36,44 @@ jQuery.butterfly = {}; jQuery.butterfly.defaultOptions = { - contentDefaultWidth: null, // For content (can be em, % or px) - null default means 50em if pxToEm is available or 700px otherwise (a good line length for legibility) - contentDefaultHeight: '100%', // For content (can be em, % or px) - mediaMaxWidth: '100%', // For images (can be em, % or px) - mediaMaxHeight: '100%', // For images (can be em, % or px) - treatAsMedia: false, // Set to true for content to be resized as if it's media (good for video content) - lightBoxMargin: null, // Margin around screen (can be em, % or px) - null default === 2em if pxToEm is available or 20px otherwise - animateResize: true, - animationSpeed: 150, - useIframe: 'autodetect', // load contents in an iframe (good for cross-domain URLs). Options are: 'autodetect' (will load iframe for external URLs), true (will load in an iframe). false (will atempt to load with ajax). - collapseHeightWhenPossible: true, // When content is shorter than available height, collapse height of lightbox - reuseFragment: false, // When using a fragment from the same page as the link, reuse the same DOM nodes (persisting their state) or clone a new copy? - closeButton: true, // Should we have a close button? - closeButtonImage: 'https://static.qgov.net.au/assets/v4/latest/lib/ext/butterfly/close.png', // Set to the path of your close button image - closeButtonCorner: 'tr', // Top left 'tl' or top right 'tr' or bottom left (bl) or bottom right (br) - top left is the most intuitive option that doesn't overlap scrollabrs - clickOverlayCloses: true, // Will clicking the overlay layer (the dark tinted area) close the lightbox? - preloadLoadingImage: '', // Specify an image path here and it will be preloaded - preloadGalleryControlsSprite: '', // Specify an image path here and it will be preloaded - galleryControlWidth: 49, // width of each control (default based on sprite that ships with butterfly) - galleryControlHeight: 85, // height of each control (default based on sprite that ships with butterfly) - galleryMode: 'rel', // Allow navigation between lightboxed images? Options are: rel (all links that have the same 'rel' attribute), 'container' (all links within the one container), 'all' (all linked images), or nothing '' (don't use galleries) - galleryContainers: '', // CSS selectors specifying elements that contain linked images to form discrete galleries. e.g: '.gallery-pets, #gallery-flowers' - galleryLoops: false, // When you reach the end of the gallery, should 'next' take you back to the begining? (and vice versa) - captionMode: 'title', // Whether to use captions, and if so, where to grab the caption text from? Options are: 'title' (the title attribute of the link), 'text' (any text within the link, including image alt text), or nothing '' (don't display captions) - preloadNextGalleryImage: true, // Should the next lightbox be preloaded if it's an image? - zoomFromClicked: false, // Experimental - callbackPreOpen: null, // Six callback functions can be defined that will be called at various points in the opening, closing and resizing of lightboxes - callbackPreResize: null, - callbackPostResize: null, - callbackPostOpen: null, - callbackPreClose: null, - callbackPostClose: null, - treatAsImage: false // If set to true, will treat all links as image links (overriding automatic type detection). + contentDefaultWidth: null, // For content (can be em, % or px) - null default means 50em if pxToEm is available or 700px otherwise (a good line length for legibility) + contentDefaultHeight: '100%', // For content (can be em, % or px) + mediaMaxWidth: '100%', // For images (can be em, % or px) + mediaMaxHeight: '100%', // For images (can be em, % or px) + treatAsMedia: false, // Set to true for content to be resized as if it's media (good for video content) + lightBoxMargin: null, // Margin around screen (can be em, % or px) - null default === 2em if pxToEm is available or 20px otherwise + animateResize: true, + animationSpeed: 150, + useIframe: 'autodetect', // load contents in an iframe (good for cross-domain URLs). Options are: 'autodetect' (will load iframe for external URLs), true (will load in an iframe). false (will atempt to load with ajax). + collapseHeightWhenPossible: true, // When content is shorter than available height, collapse height of lightbox + reuseFragment: false, // When using a fragment from the same page as the link, reuse the same DOM nodes (persisting their state) or clone a new copy? + closeButton: true, // Should we have a close button? + closeButtonImage: 'https://static.qgov.net.au/assets/v4/latest/lib/ext/butterfly/close.png', // Set to the path of your close button image + closeButtonCorner: 'tr', // Top left 'tl' or top right 'tr' or bottom left (bl) or bottom right (br) - top left is the most intuitive option that doesn't overlap scrollabrs + clickOverlayCloses: true, // Will clicking the overlay layer (the dark tinted area) close the lightbox? + preloadLoadingImage: '', // Specify an image path here and it will be preloaded + preloadGalleryControlsSprite: '', // Specify an image path here and it will be preloaded + galleryControlWidth: 49, // width of each control (default based on sprite that ships with butterfly) + galleryControlHeight: 85, // height of each control (default based on sprite that ships with butterfly) + galleryMode: 'rel', // Allow navigation between lightboxed images? Options are: rel (all links that have the same 'rel' attribute), 'container' (all links within the one container), 'all' (all linked images), or nothing '' (don't use galleries) + galleryContainers: '', // CSS selectors specifying elements that contain linked images to form discrete galleries. e.g: '.gallery-pets, #gallery-flowers' + galleryLoops: false, // When you reach the end of the gallery, should 'next' take you back to the begining? (and vice versa) + captionMode: 'title', // Whether to use captions, and if so, where to grab the caption text from? Options are: 'title' (the title attribute of the link), 'text' (any text within the link, including image alt text), or nothing '' (don't display captions) + preloadNextGalleryImage: true, // Should the next lightbox be preloaded if it's an image? + zoomFromClicked: false, // Experimental + callbackPreOpen: null, // Six callback functions can be defined that will be called at various points in the opening, closing and resizing of lightboxes + callbackPreResize: null, + callbackPostResize: null, + callbackPostOpen: null, + callbackPreClose: null, + callbackPostClose: null, + treatAsImage: false, // If set to true, will treat all links as image links (overriding automatic type detection). }; jQuery.butterfly.conf = { - overlayOpacity: '.7', - lightboxClass: 'lightbox', - lightboxLinkSelector: 'a.lightbox' + overlayOpacity: '.7', + lightboxClass: 'lightbox', + lightboxLinkSelector: 'a.lightbox', }; jQuery.butterfly.linkCount = 0; @@ -89,484 +89,469 @@ const DOM_VK_RIGHT = 39; const DOM_VK_DOWN = 40; const DOM_VK_ESCAPE = 27; -(function( $, ResizeEvents ) {// start closure - 'use strict'; +(function($, ResizeEvents) { // start closure + 'use strict'; + // functions and vars + var resizeLightBox, closeLightBox, initLightBox, openLightBox, loadLightBoxContent, + lightBoxKeypress, overlayClicked, loadLightBoxComplete, galleryControlsClick, + isImage, parsePixels, findOffsetToCentre, checkForContent; - // functions and vars - var resizeLightBox, closeLightBox, initLightBox, openLightBox, loadLightBoxContent, - lightBoxKeypress, overlayClicked, loadLightBoxComplete, galleryControlsClick, - isImage, parsePixels, findOffsetToCentre, checkForContent; + // helper functions - - // helper functions - - /** + /** * Get the keycode of an event */ - function getKeyCode(evt) { - evt = evt || window.event; - - if (evt.keyCode) { - return evt.keyCode; - } else if (evt.which) { - return evt.which; - } - return null; - } - - /** + function getKeyCode(evt) { + evt = evt || window.event; + + if (evt.keyCode) { + return evt.keyCode; + } else if (evt.which) { + return evt.which; + } + return null; + } + + /** * jQuery plugin that returns the text nodes within the target element, combined/concatenated with any alt text. */ - $.fn.accessibleText = function() { - if (this.is('img')) { - return this.attr( 'alt' ); - } else if (this.is('input')) { - return this.attr( 'value' ); - } else { - return $.map( this.contents(), function( domElement ) { - if ( domElement.nodeType === 3 ) { - return domElement.data; - } else if ( domElement.nodeType === 1 ) { - var $element = $( domElement ); - if ( $element.is( 'img, input' ) || $element.find( 'img[alt], input[value]' ).length > 0 ) { - return $element.accessibleText(); - } else { - return $element.text(); - } - } - }).join( '' ); - } - }; - - - // On DOMLoad - $(function() { - /*// IE6 fails, bail here. + $.fn.accessibleText = function() { + if (this.is('img')) { + return this.attr('alt'); + } else if (this.is('input')) { + return this.attr('value'); + } else { + return $.map(this.contents(), function(domElement) { + if (domElement.nodeType === 3) { + return domElement.data; + } else if (domElement.nodeType === 1) { + var $element = $(domElement); + if ($element.is('img, input') || $element.find('img[alt], input[value]').length > 0) { + return $element.accessibleText(); + } else { + return $element.text(); + } + } + }).join(''); + } + }; + + // On DOMLoad + $(function() { + /*// IE6 fails, bail here. if ($.browser.msie && $.browser.version < 7) { return; } */ - // If ResizeEvents plugin is available, listen for resize events - if (typeof ResizeEvents !== 'undefined') { - $(this).each(function(){ - ResizeEvents.bind ( - 'x-text-resize x-window-resize', // no need to catch 'x-initial-sizes', lightbox not open initially - resizeLightBox - ); - }); - } - - /** + // If ResizeEvents plugin is available, listen for resize events + if (typeof ResizeEvents !== 'undefined') { + $(this).each(function(){ + ResizeEvents.bind( + 'x-text-resize x-window-resize', // no need to catch 'x-initial-sizes', lightbox not open initially + resizeLightBox, + ); + }); + } + + /** * A plugin to centre a visible element on the screen */ - $.fn.centre = function () { - return this.css({ - 'position': 'fixed', - 'top': ( $(window).height() - this.outerHeight() ) / 2 + 'px', - 'left': ( $(window).width() - this.outerWidth() ) / 2 + 'px' - }); - }; - - // Create containers - $( document.body ) - .append( '
        ') - .bind( 'keydown', lightBoxKeypress ) - ; - - $( '#jb-overlay' ) - .fadeTo( 0, $.butterfly.conf.overlayOpacity, function() { - // hide when animation complete - $( this ).hide(); - }) - ; - $( '#jb-window' ) - .hide() - .click( overlayClicked ) - ; - $( '#jb-window-inner' ) - .centre() - ; - $( '#jb-window-content' ) - .css({ - overflow: 'hidden' - }) - .hide() - ; - - $.history.init( - function( hash ){ - if( hash === '' ) { - closeLightBox.apply(); - } else { - // restore the state from hash - if( /^!/.test( hash )) { - hash = hash.substring( 1 ); - $( '#' + hash ).trigger( 'click', [/*storeState*/false] ); - } - } - }, - { unescape: ',/' } - ); - }); - - - $.fn.butterfly = function( options ) { - - // IE6 fails, bail here. - /*if ($.browser.msie && $.browser.version < 7) { + $.fn.centre = function () { + return this.css({ + position: 'fixed', + top: ($(window).height() - this.outerHeight()) / 2 + 'px', + left: ($(window).width() - this.outerWidth()) / 2 + 'px', + }); + }; + + // Create containers + $(document.body) + .append('
        ') + .bind('keydown', lightBoxKeypress) + ; + + $('#jb-overlay') + .fadeTo(0, $.butterfly.conf.overlayOpacity, function() { + // hide when animation complete + $(this).hide(); + }) + ; + $('#jb-window') + .hide() + .click(overlayClicked) + ; + $('#jb-window-inner') + .centre() + ; + $('#jb-window-content') + .css({ + overflow: 'hidden', + }) + .hide() + ; + + $.history.init( + function(hash){ + if (hash === '') { + closeLightBox.apply(); + } else { + // restore the state from hash + if (/^!/.test(hash)) { + hash = hash.substring(1); + $('#' + hash).trigger('click', [/*storeState*/false]); + } + } + }, + { unescape: ',/' }, + ); + }); + + $.fn.butterfly = function(options) { + // IE6 fails, bail here. + /*if ($.browser.msie && $.browser.version < 7) { return; }*/ - options = typeof options !== 'undefined' ? options : {}; - - // Pre-load images - if (options.closeButtonImage) { - $(''); - } - if (options.preloadLoadingImage) { - $(''); - } - if (options.preloadGalleryControlsSprite) { - $(''); - } - - // Initialise lightbox links for each match - return this.each(function () { - initLightBox.apply(this, [options]); - }); - }; - - - initLightBox = function( options ) { - var pxToEmExists = (typeof Number.prototype.pxToEm !== 'undefined') ? true : false; - - // Merge runtime options with defaults - // Note: The first argument sent to extend is an empty object to - // prevent extend from overriding the default $.AKN.defaultOptions object. - options = (typeof options === 'undefined') - ? $.butterfly.defaultOptions - : $.extend({}, $.butterfly.defaultOptions, options) - ; - - if (options.lightBoxMargin === null) { - // if no margin specified, use 2em if pxToEm available, otherwise use 20px - options.lightBoxMargin = pxToEmExists ? '2em' : '20px' ; - } - if (options.contentDefaultWidth === null) { - // if no default width specified, use 50em if pxToEm available, otherwise use 700px (good line lengths for legibility) - options.contentDefaultWidth = pxToEmExists ? '50em' : '700px' ; - } - - // Assign an id if none exists - if (typeof $(this).attr('id') === 'undefined' || $(this).attr('id') === '') { // cater for jquery 1.6 and previous versions - $(this).attr('id', $.butterfly.conf.lightboxClass+'-uid-'+$.butterfly.linkCount); - } - options.linkID = $(this).attr('id'); - $.butterfly.linkCount++; - - $(this).data('options', options); - $(this).addClass($.butterfly.conf.lightboxClass); - $(this).click(openLightBox); - }; - - - openLightBox = function( e, storeState ) { - var options, originalTrigger, href, location, title, linkText, thisLink, selector, previousOptions; - - if (typeof e !== 'undefined') { - e.preventDefault(); // so that links aren't followed - } - - // Add state to history - storeState = (typeof storeState !== 'undefined') ? storeState : true ; - if (storeState) { - $.history.load('!'+$(this).attr('id')); - return; // This function will be called again by history.load after storing the state in the hash - } - - // when opening, overflow should always be set to hidden (it is changed as appropriate later once the content loads) - $('#jb-window-inner').css('overflow','hidden'); - - // if lightbox is open already and fragment was reused... clean up - if ($('#jb-overlay').is(':visible')) { - options = $('#jb-overlay').data('options'); - if (options.linkType === 'fragment' && options.reuseFragment) { - $('.jb-placeholder').remove(); - } - originalTrigger = options.originalTrigger; - } else { - // if opening for the first time, set the original trigger - originalTrigger = this; - } - - // get target content - location = window.location.href.replace( /#.*$/, '' ); - href = $(this).attr('href'); - if ( href.indexOf( location ) === 0 ) { - href = href.substring( location.length ); - } - title = $(this).attr('title'); - linkText = $(this).accessibleText(); - - // get options - options = $(this).data('options'); - options.href = href; - options.title = title; - options.linkText = linkText; - options.trigger = this; // current trigger element - options.originalTrigger = originalTrigger; // original trigger element - - // custom class? - document.getElementById( 'jb-window-inner' ).className = options.className || ''; - - if (options.treatAsImage || isImage(href)) { - options.linkType = 'image'; - } else if (href.substring(0,1) === '#') { - options.linkType = 'fragment'; - } else if (options.useIframe === true || (options.useIframe !== false && this.hostname !== window.location.hostname)) { - options.linkType = 'iframe'; - options.useIframe = true; - options.contentDefaultWidth = '100%'; - options.contentDefaultHeight = '100%'; - } else { - options.linkType = 'ajax'; - } - - // run preOpen callback function - if (options.callbackPreOpen !== null && typeof options.callbackPreOpen === 'function') { - options.callbackPreOpen.apply(this); - } - - // add/remove close button - if (options.closeButton) { - if ($('#jb-close-button').length === 0) { - $('#jb-window').prepend('Close lightbox'); - $('#jb-close-button').click(closeLightBox); - } - } else { - $('#jb-close-button').remove(); - } - - // add class if overlay can be clicked to close - if (options.clickOverlayCloses) { - $('#jb-window').addClass('reactive'); - } else { - $('#jb-window').removeClass('reactive'); - } - - // Find and store details of gallery (if configured) - thisLink = $(this); - if (options.galleryContainers !== '') { - options.galleryMode = 'container'; - } - options.gallerySelector = ''; - switch (options.galleryMode) { - case 'all': - options.gallerySelector = $.butterfly.conf.lightboxLinkSelector; - break; - case 'container': - $.each( options.galleryContainers.split( ',' ), function() { - selector = this + ' ' + $.butterfly.conf.lightboxLinkSelector; - if ( thisLink.is( selector )) { - options.gallerySelector = selector; - return false; // we found the container, break loop - } - }); - break; + options = typeof options !== 'undefined' ? options : {}; + + // Pre-load images + if (options.closeButtonImage) { + $(''); + } + if (options.preloadLoadingImage) { + $(''); + } + if (options.preloadGalleryControlsSprite) { + $(''); + } + + // Initialise lightbox links for each match + return this.each(function () { + initLightBox.apply(this, [options]); + }); + }; + + initLightBox = function(options) { + var pxToEmExists = (typeof Number.prototype.pxToEm !== 'undefined'); + + // Merge runtime options with defaults + // Note: The first argument sent to extend is an empty object to + // prevent extend from overriding the default $.AKN.defaultOptions object. + options = (typeof options === 'undefined') + ? $.butterfly.defaultOptions + : $.extend({}, $.butterfly.defaultOptions, options) + ; + + if (options.lightBoxMargin === null) { + // if no margin specified, use 2em if pxToEm available, otherwise use 20px + options.lightBoxMargin = pxToEmExists ? '2em' : '20px'; + } + if (options.contentDefaultWidth === null) { + // if no default width specified, use 50em if pxToEm available, otherwise use 700px (good line lengths for legibility) + options.contentDefaultWidth = pxToEmExists ? '50em' : '700px'; + } + + // Assign an id if none exists + if (typeof $(this).attr('id') === 'undefined' || $(this).attr('id') === '') { // cater for jquery 1.6 and previous versions + $(this).attr('id', $.butterfly.conf.lightboxClass + '-uid-' + $.butterfly.linkCount); + } + options.linkID = $(this).attr('id'); + $.butterfly.linkCount++; + + $(this).data('options', options); + $(this).addClass($.butterfly.conf.lightboxClass); + $(this).click(openLightBox); + }; + + openLightBox = function(e, storeState) { + var options, originalTrigger, href, location, title, linkText, thisLink, selector, previousOptions; + + if (typeof e !== 'undefined') { + e.preventDefault(); // so that links aren't followed + } + + // Add state to history + storeState = (typeof storeState !== 'undefined') ? storeState : true; + if (storeState) { + $.history.load('!' + $(this).attr('id')); + return; // This function will be called again by history.load after storing the state in the hash + } + + // when opening, overflow should always be set to hidden (it is changed as appropriate later once the content loads) + $('#jb-window-inner').css('overflow', 'hidden'); + + // if lightbox is open already and fragment was reused... clean up + if ($('#jb-overlay').is(':visible')) { + options = $('#jb-overlay').data('options'); + if (options.linkType === 'fragment' && options.reuseFragment) { + $('.jb-placeholder').remove(); + } + originalTrigger = options.originalTrigger; + } else { + // if opening for the first time, set the original trigger + originalTrigger = this; + } + + // get target content + location = window.location.href.replace(/#.*$/, ''); + href = $(this).attr('href'); + if (href.indexOf(location) === 0) { + href = href.substring(location.length); + } + title = $(this).attr('title'); + linkText = $(this).accessibleText(); + + // get options + options = $(this).data('options'); + options.href = href; + options.title = title; + options.linkText = linkText; + options.trigger = this; // current trigger element + options.originalTrigger = originalTrigger; // original trigger element + + // custom class? + document.getElementById('jb-window-inner').className = options.className || ''; + + if (options.treatAsImage || isImage(href)) { + options.linkType = 'image'; + } else if (href.substring(0, 1) === '#') { + options.linkType = 'fragment'; + } else if (options.useIframe === true || (options.useIframe !== false && this.hostname !== window.location.hostname)) { + options.linkType = 'iframe'; + options.useIframe = true; + options.contentDefaultWidth = '100%'; + options.contentDefaultHeight = '100%'; + } else { + options.linkType = 'ajax'; + } + + // run preOpen callback function + if (options.callbackPreOpen !== null && typeof options.callbackPreOpen === 'function') { + options.callbackPreOpen.apply(this); + } + + // add/remove close button + if (options.closeButton) { + if ($('#jb-close-button').length === 0) { + $('#jb-window').prepend('Close lightbox'); + $('#jb-close-button').click(closeLightBox); + } + } else { + $('#jb-close-button').remove(); + } + + // add class if overlay can be clicked to close + if (options.clickOverlayCloses) { + $('#jb-window').addClass('reactive'); + } else { + $('#jb-window').removeClass('reactive'); + } + + // Find and store details of gallery (if configured) + thisLink = $(this); + if (options.galleryContainers !== '') { + options.galleryMode = 'container'; + } + options.gallerySelector = ''; + switch (options.galleryMode) { + case 'all': + options.gallerySelector = $.butterfly.conf.lightboxLinkSelector; + break; + case 'container': + $.each(options.galleryContainers.split(','), function() { + selector = this + ' ' + $.butterfly.conf.lightboxLinkSelector; + if (thisLink.is(selector)) { + options.gallerySelector = selector; + return false; // we found the container, break loop + } + }); + break; // default: do nothing - } - if (options.gallerySelector === '' && $(this).attr('rel') !== '') { - options.gallerySelector = $.butterfly.conf.lightboxLinkSelector+'[rel="'+$(this).attr('rel')+'"]'; - } - - // grab previousOptions - previousOptions = $('#jb-overlay').data('options') || {}; - - // assign link options to lightbox - $(this).data('options', options); - $('#jb-overlay').data('options', options); - - // Temporarily focus here, until loading is complete - $('#jb-window').append('

        Loading...

        '); - $('#jb-loading').attr('tabindex', '0').focus(); - - if ($('#jb-overlay').is(':visible')) { - // if lightbox is open: - - // cleanup after fragment positioning - if (previousOptions.linkType === 'fragment' && previousOptions.reuseFragment) { - $('.jb-placeholder').after($(previousOptions.href)); - $('.jb-placeholder').remove(); - $(previousOptions.href).disableFocussableElements(); - } - - // hide/clear content - $('#jb-window-content') - .hide() - .empty() - ; - $('#jb-window').addClass('loading'); - - loadLightBoxContent.apply(this, [loadLightBoxComplete]); - - } else { - // if lightbox is closed: - // Disable focussable elements - $( document.body ).disableFocussableElements( '#jb-window *' ); - - // hide button - $('#jb-close-button').hide(); - - // hide gallery controls - $('#jb-gallery-controls').hide(); - - // show overlay - $('#jb-overlay').fadeIn(options.animationSpeed).centre(); - - // open small lightbox with loading spinner - $('#jb-window') - .addClass('loading') - .show() - ; - - // to zoom or not to zoom? - if (options.zoomFromClicked) { - // align window with clicked element (for 'zoom in' effect) - $('#jb-window-inner').css({ - top: $(this).offset().top, - left: $(this).offset().left, - width: $(this).width(), - height: $(this).height() - }); - } else { - // just centre - $('#jb-window-inner') - .css({ - width: '100px', - height: '100px' - }) - .centre() - ; - } - - // load new content to hidden layer - loadLightBoxContent.apply(this, [loadLightBoxComplete]); - } - // for any images in the lightbox, if they are now physically smaller than the relevant max-size, add click-to-zoom capability - }; - - - loadLightBoxComplete = function(){ - // once loaded - // init options - var options = $('#jb-overlay').data('options'); - - // restore focussable elements inside content (in case content cloned from current page) - $('#jb-window').restoreFocussableElements(); - - // remove spinner - $('#jb-window').removeClass('loading'); - - - // Redundant settimeout for webkit, cause otherwise dimensions are 0 when image loaded from cache. Thanks JKS! - // @see http://stackoverflow.com/questions/318630/get-real-image-width-and-height-with-javascript-in-safari-chrome#answer-4909227 - setTimeout(function(){ - - // Establish appropriate classes for new content type before fade in - $('#jb-window').removeClass('type-media type-image type-fragment type-ajax'); - switch (options.linkType) { - case 'image': - $('#jb-window').addClass('type-image type-media'); - $('#jb-window-inner').css('overflow','hidden'); - break; - case 'fragment': - $('#jb-window').addClass('type-fragment'); - $('#jb-window-inner').css('overflow','auto'); - break; - case 'iframe': - $('#jb-window').addClass('type-iframe'); - $('#jb-window-inner').css('overflow','hidden'); - break; - case 'ajax': - $('#jb-window').addClass('type-ajax'); - $('#jb-window-inner').css('overflow','auto'); - break; - } - if (options.treatAsMedia) { - $('#jb-window').addClass('type-media'); - } - - // resize - resizeLightBox.apply(this, [function(){ - var nextControl; - - if (options.linkType === 'iframe') { - $('#jb-window-content').css('visibility', 'visible'); - } - // fade in new content - $('#jb-window-content').fadeIn(options.animationSpeed, function(){ - - // set focus to start of lightbox content - $('#jb-window-content') - //.attr('tabindex',0) // add to tab index (now occurs during initialisation) - .focus() // set focus - ; - - // Remove temporary loading message - $('#jb-loading').remove(); - - // run postOpen callback function - if (options.callbackPostOpen !== null && typeof options.callbackPostOpen === 'function') { - options.callbackPostOpen.apply(this); - } - - // preload next gallery image? - nextControl = $('#jb-gallery-next'); - if ( - options.preloadNextGalleryImage && + } + if (options.gallerySelector === '' && $(this).attr('rel') !== '') { + options.gallerySelector = $.butterfly.conf.lightboxLinkSelector + '[rel="' + $(this).attr('rel') + '"]'; + } + + // grab previousOptions + previousOptions = $('#jb-overlay').data('options') || {}; + + // assign link options to lightbox + $(this).data('options', options); + $('#jb-overlay').data('options', options); + + // Temporarily focus here, until loading is complete + $('#jb-window').append('

        Loading...

        '); + $('#jb-loading').attr('tabindex', '0').focus(); + + if ($('#jb-overlay').is(':visible')) { + // if lightbox is open: + + // cleanup after fragment positioning + if (previousOptions.linkType === 'fragment' && previousOptions.reuseFragment) { + $('.jb-placeholder').after($(previousOptions.href)); + $('.jb-placeholder').remove(); + $(previousOptions.href).disableFocussableElements(); + } + + // hide/clear content + $('#jb-window-content') + .hide() + .empty() + ; + $('#jb-window').addClass('loading'); + + loadLightBoxContent.apply(this, [loadLightBoxComplete]); + } else { + // if lightbox is closed: + // Disable focussable elements + $(document.body).disableFocussableElements('#jb-window *'); + + // hide button + $('#jb-close-button').hide(); + + // hide gallery controls + $('#jb-gallery-controls').hide(); + + // show overlay + $('#jb-overlay').fadeIn(options.animationSpeed).centre(); + + // open small lightbox with loading spinner + $('#jb-window') + .addClass('loading') + .show() + ; + + // to zoom or not to zoom? + if (options.zoomFromClicked) { + // align window with clicked element (for 'zoom in' effect) + $('#jb-window-inner').css({ + top: $(this).offset().top, + left: $(this).offset().left, + width: $(this).width(), + height: $(this).height(), + }); + } else { + // just centre + $('#jb-window-inner') + .css({ + width: '100px', + height: '100px', + }) + .centre() + ; + } + + // load new content to hidden layer + loadLightBoxContent.apply(this, [loadLightBoxComplete]); + } + // for any images in the lightbox, if they are now physically smaller than the relevant max-size, add click-to-zoom capability + }; + + loadLightBoxComplete = function(){ + // once loaded + // init options + var options = $('#jb-overlay').data('options'); + + // restore focussable elements inside content (in case content cloned from current page) + $('#jb-window').restoreFocussableElements(); + + // remove spinner + $('#jb-window').removeClass('loading'); + + // Redundant settimeout for webkit, cause otherwise dimensions are 0 when image loaded from cache. Thanks JKS! + // @see http://stackoverflow.com/questions/318630/get-real-image-width-and-height-with-javascript-in-safari-chrome#answer-4909227 + setTimeout(function(){ + // Establish appropriate classes for new content type before fade in + $('#jb-window').removeClass('type-media type-image type-fragment type-ajax'); + switch (options.linkType) { + case 'image': + $('#jb-window').addClass('type-image type-media'); + $('#jb-window-inner').css('overflow', 'hidden'); + break; + case 'fragment': + $('#jb-window').addClass('type-fragment'); + $('#jb-window-inner').css('overflow', 'auto'); + break; + case 'iframe': + $('#jb-window').addClass('type-iframe'); + $('#jb-window-inner').css('overflow', 'hidden'); + break; + case 'ajax': + $('#jb-window').addClass('type-ajax'); + $('#jb-window-inner').css('overflow', 'auto'); + break; + } + if (options.treatAsMedia) { + $('#jb-window').addClass('type-media'); + } + + // resize + resizeLightBox.apply(this, [function(){ + var nextControl; + + if (options.linkType === 'iframe') { + $('#jb-window-content').css('visibility', 'visible'); + } + // fade in new content + $('#jb-window-content').fadeIn(options.animationSpeed, function(){ + // set focus to start of lightbox content + $('#jb-window-content') + //.attr('tabindex',0) // add to tab index (now occurs during initialisation) + .focus() // set focus + ; + + // Remove temporary loading message + $('#jb-loading').remove(); + + // run postOpen callback function + if (options.callbackPostOpen !== null && typeof options.callbackPostOpen === 'function') { + options.callbackPostOpen.apply(this); + } + + // preload next gallery image? + nextControl = $('#jb-gallery-next'); + if ( + options.preloadNextGalleryImage && nextControl.length > 0 && nextControl.is(':visible') && nextControl.attr('href') !== '#' && isImage(nextControl.attr('href')) - ) { - $(''); - } - }); - }]); - }, 0); - }; - - - resizeLightBox = function( callback ) { - - var options = $('#jb-overlay').data('options'), - lbMargin, availableWidth, availableHeight, contentDefaultWidth, contentDefaultHeight, mediaMaxWidth, mediaMaxHeight, w, h, - reductionRatio, prevWidth, topLeft, animationSpeed, buttonWidth, buttonHeight, buttonLeft, buttonTop, prevTop, prevLeft, nextTop, nextLeft; - - if (typeof options === 'undefined') { - return; // options haven't been assigned to lightbox overlay yet - } - - lbMargin = parseInt(parsePixels(options.lightBoxMargin), 10); - - availableWidth = $('#jb-window').width() - (lbMargin * 2); - availableHeight = $('#jb-window').height() - (lbMargin * 2); - - // find current default/max dimensions (convert to pixels if necessary) - contentDefaultWidth = parsePixels(options.contentDefaultWidth, availableWidth); - contentDefaultHeight = parsePixels(options.contentDefaultHeight, availableHeight); - mediaMaxWidth = parsePixels(options.mediaMaxWidth, availableWidth); - mediaMaxHeight = parsePixels(options.mediaMaxHeight, availableHeight); - - - // run preResize callback function - if (options.callbackPreResize !== null && typeof options.callbackPreResize === 'function') { - options.callbackPreResize.apply($('#jb-window'), [availableWidth, availableHeight, contentDefaultWidth, contentDefaultHeight, mediaMaxWidth, mediaMaxHeight]); - } - - /*// IE6 needs help with resizing the overlay and window + ) { + $(''); + } + }); + }]); + }, 0); + }; + + resizeLightBox = function(callback) { + var options = $('#jb-overlay').data('options'); + var lbMargin; var availableWidth; var availableHeight; var contentDefaultWidth; var contentDefaultHeight; var mediaMaxWidth; var mediaMaxHeight; var w; var h; + var reductionRatio; var prevWidth; var topLeft; var animationSpeed; var buttonWidth; var buttonHeight; var buttonLeft; var buttonTop; var prevTop; var prevLeft; var nextTop; var nextLeft; + + if (typeof options === 'undefined') { + return; // options haven't been assigned to lightbox overlay yet + } + + lbMargin = parseInt(parsePixels(options.lightBoxMargin), 10); + + availableWidth = $('#jb-window').width() - (lbMargin * 2); + availableHeight = $('#jb-window').height() - (lbMargin * 2); + + // find current default/max dimensions (convert to pixels if necessary) + contentDefaultWidth = parsePixels(options.contentDefaultWidth, availableWidth); + contentDefaultHeight = parsePixels(options.contentDefaultHeight, availableHeight); + mediaMaxWidth = parsePixels(options.mediaMaxWidth, availableWidth); + mediaMaxHeight = parsePixels(options.mediaMaxHeight, availableHeight); + + // run preResize callback function + if (options.callbackPreResize !== null && typeof options.callbackPreResize === 'function') { + options.callbackPreResize.apply($('#jb-window'), [availableWidth, availableHeight, contentDefaultWidth, contentDefaultHeight, mediaMaxWidth, mediaMaxHeight]); + } + + /*// IE6 needs help with resizing the overlay and window if ( $.browser.msie && $.browser.version === 6 ) { @@ -582,497 +567,473 @@ const DOM_VK_ESCAPE = 27; } */ - if (options.linkType === 'image' || options.treatAsMedia) { - - - - // measure content size - w = $('#jb-window-content').lightBoxContentWidth(); - h = $('#jb-window-content').lightBoxContentHeight(); - - - // compare dimensions against max width and height - if (w > mediaMaxWidth) { - reductionRatio = w / mediaMaxWidth; - w = mediaMaxWidth; - h = h / reductionRatio; - // $.debug('w ratio = '+reductionRatio); - } - if (h > mediaMaxHeight) { - reductionRatio = h / mediaMaxHeight; - h = mediaMaxHeight; - w = w / reductionRatio; - // $.debug('h ratio = '+reductionRatio); - } - - // compare dimensions against available width and height - if (w > availableWidth) { - reductionRatio = w / availableWidth; - w = availableWidth; - h = h * reductionRatio; - // $.debug('w ratio = '+reductionRatio); - } - if (h > availableHeight) { - reductionRatio = h / availableHeight; - h = availableHeight; - w = w * reductionRatio; - // $.debug('h ratio = '+reductionRatio); - } - // $.debug('max img width = '+options.mediaMaxWidth); - // $.debug('max img height = '+options.mediaMaxHeight); - - } else if (options.linkType === 'iframe') { - - w = contentDefaultWidth; - h = contentDefaultHeight; - - } else { - - // not an image or treat as media (must be content fragment) - - // $.debug('contentDefaultWidth = '+options.contentDefaultWidth); - // $.debug('contentDefaultHeight = '+options.contentDefaultHeight); - - // measure content width - w = $('#jb-window-content').lightBoxContentWidth(); - - if ( - contentDefaultWidth === '' || + if (options.linkType === 'image' || options.treatAsMedia) { + // measure content size + w = $('#jb-window-content').lightBoxContentWidth(); + h = $('#jb-window-content').lightBoxContentHeight(); + + // compare dimensions against max width and height + if (w > mediaMaxWidth) { + reductionRatio = w / mediaMaxWidth; + w = mediaMaxWidth; + h = h / reductionRatio; + // $.debug('w ratio = '+reductionRatio); + } + if (h > mediaMaxHeight) { + reductionRatio = h / mediaMaxHeight; + h = mediaMaxHeight; + w = w / reductionRatio; + // $.debug('h ratio = '+reductionRatio); + } + + // compare dimensions against available width and height + if (w > availableWidth) { + reductionRatio = w / availableWidth; + w = availableWidth; + h = h * reductionRatio; + // $.debug('w ratio = '+reductionRatio); + } + if (h > availableHeight) { + reductionRatio = h / availableHeight; + h = availableHeight; + w = w * reductionRatio; + // $.debug('h ratio = '+reductionRatio); + } + // $.debug('max img width = '+options.mediaMaxWidth); + // $.debug('max img height = '+options.mediaMaxHeight); + } else if (options.linkType === 'iframe') { + w = contentDefaultWidth; + h = contentDefaultHeight; + } else { + // not an image or treat as media (must be content fragment) + + // $.debug('contentDefaultWidth = '+options.contentDefaultWidth); + // $.debug('contentDefaultHeight = '+options.contentDefaultHeight); + + // measure content width + w = $('#jb-window-content').lightBoxContentWidth(); + + if ( + contentDefaultWidth === '' || contentDefaultWidth === '100%' || availableWidth < contentDefaultWidth - ) { - w = availableWidth; - } else { - w = contentDefaultWidth; - } - - if (options.collapseHeightWhenPossible) { - - // set new width temporarily - prevWidth = $('#jb-window-inner').width(); - //$('#jb-window-inner').width(w); // not kicking in fast enough, use animate to lock in new width - $('#jb-window-inner').animate({width: w}, 0); - - // measure height - h = $('#jb-window-content').lightBoxContentHeight( false ); - - // set width back to previous value - $('#jb-window-inner').width(prevWidth); - - if ( - availableHeight < h - ) { - h = availableHeight; - // } else { - // do nothing - // h = contentDefaultHeight; - } - - } else { - - // same height for all content boxes (based on contentDefaultHeight) - h = $('#jb-window-content').lightBoxContentHeight(); - if ( - contentDefaultHeight === '' || + ) { + w = availableWidth; + } else { + w = contentDefaultWidth; + } + + if (options.collapseHeightWhenPossible) { + // set new width temporarily + prevWidth = $('#jb-window-inner').width(); + //$('#jb-window-inner').width(w); // not kicking in fast enough, use animate to lock in new width + $('#jb-window-inner').animate({ width: w }, 0); + + // measure height + h = $('#jb-window-content').lightBoxContentHeight(false); + + // set width back to previous value + $('#jb-window-inner').width(prevWidth); + + if ( + availableHeight < h + ) { + h = availableHeight; + // } else { + // do nothing + // h = contentDefaultHeight; + } + } else { + // same height for all content boxes (based on contentDefaultHeight) + h = $('#jb-window-content').lightBoxContentHeight(); + if ( + contentDefaultHeight === '' || contentDefaultHeight === '100%' || availableHeight < contentDefaultHeight - ) { - h = availableHeight; - } else { - h = contentDefaultHeight; - } - } - } - - // $.debug('availableWidth = '+availableWidth); - // $.debug('availableHeight = '+availableHeight); - // $.debug('final w = '+w); - // $.debug('final h = '+h); - - topLeft = findOffsetToCentre(w, h); - - // if not animating resize, set speed to 0 - animationSpeed = options.animateResize ? options.animationSpeed : 0; - - $('#jb-close-button').hide(); - $('#jb-gallery-controls').hide(); - - if (options.linkType === 'iframe') { - $('#jb-window-inner iframe').css('visibility','hidden'); - } - - $('#jb-window-inner').animate({ - 'width' : w, - 'height' : h, - 'left' : topLeft[1], - 'top' : topLeft[0] - }, animationSpeed, 0, function() { - - options = $('#jb-overlay').data('options'); - w = $('#jb-window-inner').width(); - h = $('#jb-window-inner').height(); - - - // Show iframe - if (options.linkType === 'iframe') { - $('#jb-window-inner iframe') - .width(w) - .height(h) - ; - $('#jb-window-inner iframe').css('visibility','visible'); - } - - // Show close button - if ($('#jb-close-button').length > 0) { - buttonWidth = parseInt($('#jb-close-button').width(), 10); - buttonHeight = parseInt($('#jb-close-button').height(), 10); - - switch (options.closeButtonCorner) { - case 'tr': - buttonLeft = topLeft[1] + w - buttonWidth/2; - buttonTop = topLeft[0] - buttonHeight/2; - break; - case 'br': - buttonLeft = topLeft[1] + w - buttonWidth/2; - buttonTop = topLeft[0] + h - buttonHeight/2; - break; - case 'bl': - buttonLeft = topLeft[1] - buttonWidth/2; - buttonTop = topLeft[0] + h - buttonHeight/2; - break; - default: - // case 'tl': - buttonLeft = topLeft[1] - buttonWidth/2; - buttonTop = topLeft[0] - buttonHeight/2; - } - - $('#jb-close-button') - .css({ - position: 'absolute', - 'z-index': '999999', - left: buttonLeft, - top: buttonTop - }) - .show() - ; - } - - // Are gallery controls relevant? - if ($('#jb-gallery-controls').is('.active')) { - // Position gallery controls - prevTop = topLeft[0] + h/2 - options.galleryControlHeight/2; - prevLeft = topLeft[1] - options.galleryControlWidth; - $('#jb-gallery-prev').css({top: prevTop, left: prevLeft}); - - nextTop = topLeft[0] + h/2 - options.galleryControlHeight/2; - nextLeft = topLeft[1] + w; - $('#jb-gallery-next').css({top: nextTop, left: nextLeft}); - - // Show gallery controls - $('#jb-gallery-controls') - //.fadeIn() - .show() // faster! - ; - } - - // run postResize callback function - if (options.callbackPostResize !== null && typeof options.callbackPostResize === 'function') { - options.callbackPostResize.apply($('#jb-window'), [availableWidth, availableHeight, contentDefaultWidth, contentDefaultHeight, mediaMaxWidth, mediaMaxHeight]); - } - - if (typeof callback !== 'undefined' && typeof callback.apply !== 'undefined') { - callback.apply(); - } - }); - }; - - - loadLightBoxContent = function( callback ) { - - var options = $( '#jb-overlay' ).data( 'options' ), - href = options.href, - caption, gallerySet, prevControl, nextControl, prevLink, nextLink, - lbMargin, availableWidth, availableHeight, contentDefaultWidth, contentDefaultHeight, ajaxHref; - - // Populate caption - switch (options.captionMode) { - case 'title': - caption = options.title ? '

        ' + options.title + '

        ':''; - break; - case 'text': - caption = options.linkText ? '

        ' + options.linkText + '

        ':''; - break; - default: - caption = ''; - break; - } - - - // remove previous error states - $('#jb-window').removeClass('error-no-content'); - - // Setup/adjust gallery (next/prev) links - // Find the gallery set - gallerySet = $(options.gallerySelector); - - $('#jb-gallery-controls').removeClass('active'); - - if (gallerySet.length > 1 && gallerySet.isInSet('#'+options.linkID)) { - - // Setup the HTML for the gallery controls - if ($('#jb-gallery-controls').length === 0) { - $('#jb-window').append(''); - prevControl = $('Previous').click(galleryControlsClick); - nextControl = $('Next').click(galleryControlsClick); - $('#jb-gallery-controls').append(prevControl).append(nextControl); - prevControl.add(nextControl).css({ - position: 'absolute', - 'z-index': '99999', - display: 'block', - overflow: 'hidden' - }); - } else { - prevControl = $('#jb-gallery-prev'); - nextControl = $('#jb-gallery-next'); - prevControl.add(nextControl) - .removeClass('disabled') - .attr('tabindex', '0') - .attr('title', '') - .show() - ; - } - $('#jb-gallery-controls').hide(); - $('#jb-gallery-controls').addClass('active'); - - - // Find previous link - prevLink = gallerySet.prevInSet('#'+options.linkID); - if (prevLink === false) { - if (options.galleryLoops) { - prevLink = gallerySet.lastInSet(); - } else { - prevLink = $(''); - prevControl - .addClass('disabled') - .attr('tabindex', '-1') - // hide it or it traps mouse clicks - .hide() - ; - } - } - prevControl - .attr('href', prevLink.attr('href')) - .data('linkID', prevLink.attr('id')) - .attr('title', $.trim( prevLink.accessibleText() )) - ; - - // Find next link - nextLink = gallerySet.nextInSet('#'+options.linkID); - if (nextLink === false) { - if (options.galleryLoops) { - nextLink = gallerySet.firstInSet(); - } else { - nextLink = $(''); - nextControl - .addClass('disabled') - .attr('tabindex', '-1') - // hide it or it traps mouse clicks - .hide() - ; - } - } - nextControl - .attr('href', nextLink.attr('href')) - .data('linkID', nextLink.attr('id')) - .attr('title', $.trim( nextLink.accessibleText() )) - ; - - } else { - $('#jb-gallery-controls').hide(); - } - - switch (options.linkType) { - case 'fragment': // internal page fragment - - if (options.reuseFragment) { - $(href).after(''); - $('#jb-window-content').empty().append($(href)); // href becomes a selector for an id fragment - } else { - $('#jb-window-content').empty().append($(href).clone(true)); - } - - checkForContent.apply(this, [options.linkType, href]); - callback.apply(this); - break; - - case 'image': // link to image - - $('#jb-window-content').empty().append( - ''+caption - ); - $('#jb-window-content img') - .error(function(){ - checkForContent.apply(this, [options.linkType, href, callback]); - }) - .data('full-width', '') - .data('full-height', '') - .load(callback) - ; - break; - - case 'iframe': // link to iframe URL - $('#jb-window-content').show().css('visibility', 'hidden'); - $('#jb-window-content').empty().append( - '',preload:!0,css:{},attr:{scrolling:"auto"}},video:{tpl:'',format:"",autoStart:!0},defaultType:"image",animationEffect:"zoom",animationDuration:366,zoomOpacity:"auto",transitionEffect:"fade",transitionDuration:366,slideClass:"",baseClass:"",baseTpl:'',spinnerTpl:'
        ',errorTpl:'

        {{ERROR}}

        ',btnTpl:{download:'',zoom:'',close:'',arrowLeft:'',arrowRight:'',smallBtn:''},parentEl:"body",hideScrollbar:!0,autoFocus:!0,backFocus:!0,trapFocus:!0,fullScreen:{autoStart:!1},touch:{vertical:!0,momentum:!0},hash:null,media:{},slideShow:{autoStart:!1,speed:3e3},thumbs:{autoStart:!1,hideOnClose:!0,parentEl:".fancybox-container",axis:"y"},wheel:"auto",onInit:n.noop,beforeLoad:n.noop,afterLoad:n.noop,beforeShow:n.noop,afterShow:n.noop,beforeClose:n.noop,afterClose:n.noop,onActivate:n.noop,onDeactivate:n.noop,clickContent:function(t,e){return"image"===t.type&&"zoom"},clickSlide:"close",clickOutside:"close",dblclickContent:!1,dblclickSlide:!1,dblclickOutside:!1,mobile:{preventCaptionOverlap:!1,idleTime:!1,clickContent:function(t,e){return"image"===t.type&&"toggleControls"},clickSlide:function(t,e){return"image"===t.type?"toggleControls":"close"},dblclickContent:function(t,e){return"image"===t.type&&"zoom"},dblclickSlide:function(t,e){return"image"===t.type&&"zoom"}},lang:"en",i18n:{en:{CLOSE:"Close",NEXT:"Next",PREV:"Previous",ERROR:"The requested content cannot be loaded.
        Please try again later.",PLAY_START:"Start slideshow",PLAY_STOP:"Pause slideshow",FULL_SCREEN:"Full screen",THUMBS:"Thumbnails",DOWNLOAD:"Download",SHARE:"Share",ZOOM:"Zoom"},de:{CLOSE:"Schließen",NEXT:"Weiter",PREV:"Zurück",ERROR:"Die angeforderten Daten konnten nicht geladen werden.
        Bitte versuchen Sie es später nochmal.",PLAY_START:"Diaschau starten",PLAY_STOP:"Diaschau beenden",FULL_SCREEN:"Vollbild",THUMBS:"Vorschaubilder",DOWNLOAD:"Herunterladen",SHARE:"Teilen",ZOOM:"Vergrößern"}}},s=n(t),r=n(e),c=0,l=function(t){return t&&t.hasOwnProperty&&t instanceof n},d=function(){return t.requestAnimationFrame||t.webkitRequestAnimationFrame||t.mozRequestAnimationFrame||t.oRequestAnimationFrame||function(e){return t.setTimeout(e,1e3/60)}}(),u=function(){return t.cancelAnimationFrame||t.webkitCancelAnimationFrame||t.mozCancelAnimationFrame||t.oCancelAnimationFrame||function(e){t.clearTimeout(e)}}(),f=function(){var t,n=e.createElement("fakeelement"),o={transition:"transitionend",OTransition:"oTransitionEnd",MozTransition:"transitionend",WebkitTransition:"webkitTransitionEnd"};for(t in o)if(void 0!==n.style[t])return o[t];return"transitionend"}(),p=function(t){return t&&t.length&&t[0].offsetHeight},h=function(t,e){var o=n.extend(!0,{},t,e);return n.each(e,function(t,e){n.isArray(e)&&(o[t]=e)}),o},g=function(t){var o,i;return!(!t||t.ownerDocument!==e)&&(n(".fancybox-container").css("pointer-events","none"),o={x:t.getBoundingClientRect().left+t.offsetWidth/2,y:t.getBoundingClientRect().top+t.offsetHeight/2},i=e.elementFromPoint(o.x,o.y)===t,n(".fancybox-container").css("pointer-events",""),i)},b=function(t,e,o){var i=this;i.opts=h({index:o},n.fancybox.defaults),n.isPlainObject(e)&&(i.opts=h(i.opts,e)),n.fancybox.isMobile&&(i.opts=h(i.opts,i.opts.mobile)),i.id=i.opts.id||++c,i.currIndex=parseInt(i.opts.index,10)||0,i.prevIndex=null,i.prevPos=null,i.currPos=0,i.firstRun=!0,i.group=[],i.slides={},i.addContent(t),i.group.length&&i.init()};n.extend(b.prototype,{init:function(){var o,i,a=this,s=a.group[a.currIndex],r=s.opts;r.closeExisting&&n.fancybox.close(!0),n("body").addClass("fancybox-active"),!n.fancybox.getInstance()&&!1!==r.hideScrollbar&&!n.fancybox.isMobile&&e.body.scrollHeight>t.innerHeight&&(n("head").append('"),n("body").addClass("compensate-for-scrollbar")),i="",n.each(r.buttons,function(t,e){i+=r.btnTpl[e]||""}),o=n(a.translate(a,r.baseTpl.replace("{{buttons}}",i).replace("{{arrows}}",r.btnTpl.arrowLeft+r.btnTpl.arrowRight))).attr("id","fancybox-container-"+a.id).addClass(r.baseClass).data("FancyBox",a).appendTo(r.parentEl),a.$refs={container:o},["bg","inner","infobar","toolbar","stage","caption","navigation"].forEach(function(t){a.$refs[t]=o.find(".fancybox-"+t)}),a.trigger("onInit"),a.activate(),a.jumpTo(a.currIndex)},translate:function(t,e){var n=t.opts.i18n[t.opts.lang]||t.opts.i18n.en;return e.replace(/\{\{(\w+)\}\}/g,function(t,e){return void 0===n[e]?t:n[e]})},addContent:function(t){var e,o=this,i=n.makeArray(t);n.each(i,function(t,e){var i,a,s,r,c,l={},d={};n.isPlainObject(e)?(l=e,d=e.opts||e):"object"===n.type(e)&&n(e).length?(i=n(e),d=i.data()||{},d=n.extend(!0,{},d,d.options),d.$orig=i,l.src=o.opts.src||d.src||i.attr("href"),l.type||l.src||(l.type="inline",l.src=e)):l={type:"html",src:e+""},l.opts=n.extend(!0,{},o.opts,d),n.isArray(d.buttons)&&(l.opts.buttons=d.buttons),n.fancybox.isMobile&&l.opts.mobile&&(l.opts=h(l.opts,l.opts.mobile)),a=l.type||l.opts.type,r=l.src||"",!a&&r&&((s=r.match(/\.(mp4|mov|ogv|webm)((\?|#).*)?$/i))?(a="video",l.opts.video.format||(l.opts.video.format="video/"+("ogv"===s[1]?"ogg":s[1]))):r.match(/(^data:image\/[a-z0-9+\/=]*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg|ico)((\?|#).*)?$)/i)?a="image":r.match(/\.(pdf)((\?|#).*)?$/i)?(a="iframe",l=n.extend(!0,l,{contentType:"pdf",opts:{iframe:{preload:!1}}})):"#"===r.charAt(0)&&(a="inline")),a?l.type=a:o.trigger("objectNeedsType",l),l.contentType||(l.contentType=n.inArray(l.type,["html","inline","ajax"])>-1?"html":l.type),l.index=o.group.length,"auto"==l.opts.smallBtn&&(l.opts.smallBtn=n.inArray(l.type,["html","inline","ajax"])>-1),"auto"===l.opts.toolbar&&(l.opts.toolbar=!l.opts.smallBtn),l.$thumb=l.opts.$thumb||null,l.opts.$trigger&&l.index===o.opts.index&&(l.$thumb=l.opts.$trigger.find("img:first"),l.$thumb.length&&(l.opts.$orig=l.opts.$trigger)),l.$thumb&&l.$thumb.length||!l.opts.$orig||(l.$thumb=l.opts.$orig.find("img:first")),l.$thumb&&!l.$thumb.length&&(l.$thumb=null),l.thumb=l.opts.thumb||(l.$thumb?l.$thumb[0].src:null),"function"===n.type(l.opts.caption)&&(l.opts.caption=l.opts.caption.apply(e,[o,l])),"function"===n.type(o.opts.caption)&&(l.opts.caption=o.opts.caption.apply(e,[o,l])),l.opts.caption instanceof n||(l.opts.caption=void 0===l.opts.caption?"":l.opts.caption+""),"ajax"===l.type&&(c=r.split(/\s+/,2),c.length>1&&(l.src=c.shift(),l.opts.filter=c.shift())),l.opts.modal&&(l.opts=n.extend(!0,l.opts,{trapFocus:!0,infobar:0,toolbar:0,smallBtn:0,keyboard:0,slideShow:0,fullScreen:0,thumbs:0,touch:0,clickContent:!1,clickSlide:!1,clickOutside:!1,dblclickContent:!1,dblclickSlide:!1,dblclickOutside:!1})),o.group.push(l)}),Object.keys(o.slides).length&&(o.updateControls(),(e=o.Thumbs)&&e.isActive&&(e.create(),e.focus()))},addEvents:function(){var e=this;e.removeEvents(),e.$refs.container.on("click.fb-close","[data-fancybox-close]",function(t){t.stopPropagation(),t.preventDefault(),e.close(t)}).on("touchstart.fb-prev click.fb-prev","[data-fancybox-prev]",function(t){t.stopPropagation(),t.preventDefault(),e.previous()}).on("touchstart.fb-next click.fb-next","[data-fancybox-next]",function(t){t.stopPropagation(),t.preventDefault(),e.next()}).on("click.fb","[data-fancybox-zoom]",function(t){e[e.isScaledDown()?"scaleToActual":"scaleToFit"]()}),s.on("orientationchange.fb resize.fb",function(t){t&&t.originalEvent&&"resize"===t.originalEvent.type?(e.requestId&&u(e.requestId),e.requestId=d(function(){e.update(t)})):(e.current&&"iframe"===e.current.type&&e.$refs.stage.hide(),setTimeout(function(){e.$refs.stage.show(),e.update(t)},n.fancybox.isMobile?600:250))}),r.on("keydown.fb",function(t){var o=n.fancybox?n.fancybox.getInstance():null,i=o.current,a=t.keyCode||t.which;if(9==a)return void(i.opts.trapFocus&&e.focus(t));if(!(!i.opts.keyboard||t.ctrlKey||t.altKey||t.shiftKey||n(t.target).is("input,textarea,video,audio,select")))return 8===a||27===a?(t.preventDefault(),void e.close(t)):37===a||38===a?(t.preventDefault(),void e.previous()):39===a||40===a?(t.preventDefault(),void e.next()):void e.trigger("afterKeydown",t,a)}),e.group[e.currIndex].opts.idleTime&&(e.idleSecondsCounter=0,r.on("mousemove.fb-idle mouseleave.fb-idle mousedown.fb-idle touchstart.fb-idle touchmove.fb-idle scroll.fb-idle keydown.fb-idle",function(t){e.idleSecondsCounter=0,e.isIdle&&e.showControls(),e.isIdle=!1}),e.idleInterval=t.setInterval(function(){++e.idleSecondsCounter>=e.group[e.currIndex].opts.idleTime&&!e.isDragging&&(e.isIdle=!0,e.idleSecondsCounter=0,e.hideControls())},1e3))},removeEvents:function(){var e=this;s.off("orientationchange.fb resize.fb"),r.off("keydown.fb .fb-idle"),this.$refs.container.off(".fb-close .fb-prev .fb-next"),e.idleInterval&&(t.clearInterval(e.idleInterval),e.idleInterval=null)},previous:function(t){return this.jumpTo(this.currPos-1,t)},next:function(t){return this.jumpTo(this.currPos+1,t)},jumpTo:function(t,e){var o,i,a,s,r,c,l,d,u,f=this,h=f.group.length;if(!(f.isDragging||f.isClosing||f.isAnimating&&f.firstRun)){if(t=parseInt(t,10),!(a=f.current?f.current.opts.loop:f.opts.loop)&&(t<0||t>=h))return!1;if(o=f.firstRun=!Object.keys(f.slides).length,r=f.current,f.prevIndex=f.currIndex,f.prevPos=f.currPos,s=f.createSlide(t),h>1&&((a||s.index0)&&f.createSlide(t-1)),f.current=s,f.currIndex=s.index,f.currPos=s.pos,f.trigger("beforeShow",o),f.updateControls(),s.forcedDuration=void 0,n.isNumeric(e)?s.forcedDuration=e:e=s.opts[o?"animationDuration":"transitionDuration"],e=parseInt(e,10),i=f.isMoved(s),s.$slide.addClass("fancybox-slide--current"),o)return s.opts.animationEffect&&e&&f.$refs.container.css("transition-duration",e+"ms"),f.$refs.container.addClass("fancybox-is-open").trigger("focus"),f.loadSlide(s),void f.preload("image");c=n.fancybox.getTranslate(r.$slide),l=n.fancybox.getTranslate(f.$refs.stage),n.each(f.slides,function(t,e){n.fancybox.stop(e.$slide,!0)}),r.pos!==s.pos&&(r.isComplete=!1),r.$slide.removeClass("fancybox-slide--complete fancybox-slide--current"),i?(u=c.left-(r.pos*c.width+r.pos*r.opts.gutter),n.each(f.slides,function(t,o){o.$slide.removeClass("fancybox-animated").removeClass(function(t,e){return(e.match(/(^|\s)fancybox-fx-\S+/g)||[]).join(" ")});var i=o.pos*c.width+o.pos*o.opts.gutter;n.fancybox.setTranslate(o.$slide,{top:0,left:i-l.left+u}),o.pos!==s.pos&&o.$slide.addClass("fancybox-slide--"+(o.pos>s.pos?"next":"previous")),p(o.$slide),n.fancybox.animate(o.$slide,{top:0,left:(o.pos-s.pos)*c.width+(o.pos-s.pos)*o.opts.gutter},e,function(){o.$slide.css({transform:"",opacity:""}).removeClass("fancybox-slide--next fancybox-slide--previous"),o.pos===f.currPos&&f.complete()})})):e&&s.opts.transitionEffect&&(d="fancybox-animated fancybox-fx-"+s.opts.transitionEffect,r.$slide.addClass("fancybox-slide--"+(r.pos>s.pos?"next":"previous")),n.fancybox.animate(r.$slide,d,e,function(){r.$slide.removeClass(d).removeClass("fancybox-slide--next fancybox-slide--previous")},!1)),s.isLoaded?f.revealContent(s):f.loadSlide(s),f.preload("image")}},createSlide:function(t){var e,o,i=this;return o=t%i.group.length,o=o<0?i.group.length+o:o,!i.slides[t]&&i.group[o]&&(e=n('
        ').appendTo(i.$refs.stage),i.slides[t]=n.extend(!0,{},i.group[o],{pos:t,$slide:e,isLoaded:!1}),i.updateSlide(i.slides[t])),i.slides[t]},scaleToActual:function(t,e,o){var i,a,s,r,c,l=this,d=l.current,u=d.$content,f=n.fancybox.getTranslate(d.$slide).width,p=n.fancybox.getTranslate(d.$slide).height,h=d.width,g=d.height;l.isAnimating||l.isMoved()||!u||"image"!=d.type||!d.isLoaded||d.hasError||(l.isAnimating=!0,n.fancybox.stop(u),t=void 0===t?.5*f:t,e=void 0===e?.5*p:e,i=n.fancybox.getTranslate(u),i.top-=n.fancybox.getTranslate(d.$slide).top,i.left-=n.fancybox.getTranslate(d.$slide).left,r=h/i.width,c=g/i.height,a=.5*f-.5*h,s=.5*p-.5*g,h>f&&(a=i.left*r-(t*r-t),a>0&&(a=0),ap&&(s=i.top*c-(e*c-e),s>0&&(s=0),se-.5&&(l=e),d>o-.5&&(d=o),"image"===t.type?(u.top=Math.floor(.5*(o-d))+parseFloat(c.css("paddingTop")),u.left=Math.floor(.5*(e-l))+parseFloat(c.css("paddingLeft"))):"video"===t.contentType&&(a=t.opts.width&&t.opts.height?l/d:t.opts.ratio||16/9,d>l/a?d=l/a:l>d*a&&(l=d*a)),u.width=l,u.height=d,u)},update:function(t){var e=this;n.each(e.slides,function(n,o){e.updateSlide(o,t)})},updateSlide:function(t,e){var o=this,i=t&&t.$content,a=t.width||t.opts.width,s=t.height||t.opts.height,r=t.$slide;o.adjustCaption(t),i&&(a||s||"video"===t.contentType)&&!t.hasError&&(n.fancybox.stop(i),n.fancybox.setTranslate(i,o.getFitPos(t)),t.pos===o.currPos&&(o.isAnimating=!1,o.updateCursor())),o.adjustLayout(t),r.length&&(r.trigger("refresh"),t.pos===o.currPos&&o.$refs.toolbar.add(o.$refs.navigation.find(".fancybox-button--arrow_right")).toggleClass("compensate-for-scrollbar",r.get(0).scrollHeight>r.get(0).clientHeight)),o.trigger("onUpdate",t,e)},centerSlide:function(t){var e=this,o=e.current,i=o.$slide;!e.isClosing&&o&&(i.siblings().css({transform:"",opacity:""}),i.parent().children().removeClass("fancybox-slide--previous fancybox-slide--next"),n.fancybox.animate(i,{top:0,left:0,opacity:1},void 0===t?0:t,function(){i.css({transform:"",opacity:""}),o.isComplete||e.complete()},!1))},isMoved:function(t){var e,o,i=t||this.current;return!!i&&(o=n.fancybox.getTranslate(this.$refs.stage),e=n.fancybox.getTranslate(i.$slide),!i.$slide.hasClass("fancybox-animated")&&(Math.abs(e.top-o.top)>.5||Math.abs(e.left-o.left)>.5))},updateCursor:function(t,e){var o,i,a=this,s=a.current,r=a.$refs.container;s&&!a.isClosing&&a.Guestures&&(r.removeClass("fancybox-is-zoomable fancybox-can-zoomIn fancybox-can-zoomOut fancybox-can-swipe fancybox-can-pan"),o=a.canPan(t,e),i=!!o||a.isZoomable(),r.toggleClass("fancybox-is-zoomable",i),n("[data-fancybox-zoom]").prop("disabled",!i),o?r.addClass("fancybox-can-pan"):i&&("zoom"===s.opts.clickContent||n.isFunction(s.opts.clickContent)&&"zoom"==s.opts.clickContent(s))?r.addClass("fancybox-can-zoomIn"):s.opts.touch&&(s.opts.touch.vertical||a.group.length>1)&&"video"!==s.contentType&&r.addClass("fancybox-can-swipe"))},isZoomable:function(){var t,e=this,n=e.current;if(n&&!e.isClosing&&"image"===n.type&&!n.hasError){if(!n.isLoaded)return!0;if((t=e.getFitPos(n))&&(n.width>t.width||n.height>t.height))return!0}return!1},isScaledDown:function(t,e){var o=this,i=!1,a=o.current,s=a.$content;return void 0!==t&&void 0!==e?i=t1.5||Math.abs(a.height-s.height)>1.5)),s},loadSlide:function(t){var e,o,i,a=this;if(!t.isLoading&&!t.isLoaded){if(t.isLoading=!0,!1===a.trigger("beforeLoad",t))return t.isLoading=!1,!1;switch(e=t.type,o=t.$slide,o.off("refresh").trigger("onReset").addClass(t.opts.slideClass),e){case"image":a.setImage(t);break;case"iframe":a.setIframe(t);break;case"html":a.setContent(t,t.src||t.content);break;case"video":a.setContent(t,t.opts.video.tpl.replace(/\{\{src\}\}/gi,t.src).replace("{{format}}",t.opts.videoFormat||t.opts.video.format||"").replace("{{poster}}",t.thumb||""));break;case"inline":n(t.src).length?a.setContent(t,n(t.src)):a.setError(t);break;case"ajax":a.showLoading(t),i=n.ajax(n.extend({},t.opts.ajax.settings,{url:t.src,success:function(e,n){"success"===n&&a.setContent(t,e)},error:function(e,n){e&&"abort"!==n&&a.setError(t)}})),o.one("onReset",function(){i.abort()});break;default:a.setError(t)}return!0}},setImage:function(t){var o,i=this;setTimeout(function(){var e=t.$image;i.isClosing||!t.isLoading||e&&e.length&&e[0].complete||t.hasError||i.showLoading(t)},50),i.checkSrcset(t),t.$content=n('
        ').addClass("fancybox-is-hidden").appendTo(t.$slide.addClass("fancybox-slide--image")),!1!==t.opts.preload&&t.opts.width&&t.opts.height&&t.thumb&&(t.width=t.opts.width,t.height=t.opts.height,o=e.createElement("img"),o.onerror=function(){n(this).remove(),t.$ghost=null},o.onload=function(){i.afterLoad(t)},t.$ghost=n(o).addClass("fancybox-image").appendTo(t.$content).attr("src",t.thumb)),i.setBigImage(t)},checkSrcset:function(e){var n,o,i,a,s=e.opts.srcset||e.opts.image.srcset;if(s){i=t.devicePixelRatio||1,a=t.innerWidth*i,o=s.split(",").map(function(t){var e={};return t.trim().split(/\s+/).forEach(function(t,n){var o=parseInt(t.substring(0,t.length-1),10);if(0===n)return e.url=t;o&&(e.value=o,e.postfix=t[t.length-1])}),e}),o.sort(function(t,e){return t.value-e.value});for(var r=0;r=a||"x"===c.postfix&&c.value>=i){n=c;break}}!n&&o.length&&(n=o[o.length-1]),n&&(e.src=n.url,e.width&&e.height&&"w"==n.postfix&&(e.height=e.width/e.height*n.value,e.width=n.value),e.opts.srcset=s)}},setBigImage:function(t){var o=this,i=e.createElement("img"),a=n(i);t.$image=a.one("error",function(){o.setError(t)}).one("load",function(){var e;t.$ghost||(o.resolveImageSlideSize(t,this.naturalWidth,this.naturalHeight),o.afterLoad(t)),o.isClosing||(t.opts.srcset&&(e=t.opts.sizes,e&&"auto"!==e||(e=(t.width/t.height>1&&s.width()/s.height()>1?"100":Math.round(t.width/t.height*100))+"vw"),a.attr("sizes",e).attr("srcset",t.opts.srcset)),t.$ghost&&setTimeout(function(){t.$ghost&&!o.isClosing&&t.$ghost.hide()},Math.min(300,Math.max(1e3,t.height/1600))),o.hideLoading(t))}).addClass("fancybox-image").attr("src",t.src).appendTo(t.$content),(i.complete||"complete"==i.readyState)&&a.naturalWidth&&a.naturalHeight?a.trigger("load"):i.error&&a.trigger("error")},resolveImageSlideSize:function(t,e,n){var o=parseInt(t.opts.width,10),i=parseInt(t.opts.height,10);t.width=e,t.height=n,o>0&&(t.width=o,t.height=Math.floor(o*n/e)),i>0&&(t.width=Math.floor(i*e/n),t.height=i)},setIframe:function(t){var e,o=this,i=t.opts.iframe,a=t.$slide;t.$content=n('
        ').css(i.css).appendTo(a),a.addClass("fancybox-slide--"+t.contentType),t.$iframe=e=n(i.tpl.replace(/\{rnd\}/g,(new Date).getTime())).attr(i.attr).appendTo(t.$content),i.preload?(o.showLoading(t),e.on("load.fb error.fb",function(e){this.isReady=1,t.$slide.trigger("refresh"),o.afterLoad(t)}),a.on("refresh.fb",function(){var n,o,s=t.$content,r=i.css.width,c=i.css.height;if(1===e[0].isReady){try{n=e.contents(),o=n.find("body")}catch(t){}o&&o.length&&o.children().length&&(a.css("overflow","visible"),s.css({width:"100%","max-width":"100%",height:"9999px"}),void 0===r&&(r=Math.ceil(Math.max(o[0].clientWidth,o.outerWidth(!0)))),s.css("width",r||"").css("max-width",""),void 0===c&&(c=Math.ceil(Math.max(o[0].clientHeight,o.outerHeight(!0)))),s.css("height",c||""),a.css("overflow","auto")),s.removeClass("fancybox-is-hidden")}})):o.afterLoad(t),e.attr("src",t.src),a.one("onReset",function(){try{n(this).find("iframe").hide().unbind().attr("src","//about:blank")}catch(t){}n(this).off("refresh.fb").empty(),t.isLoaded=!1,t.isRevealed=!1})},setContent:function(t,e){var o=this;o.isClosing||(o.hideLoading(t),t.$content&&n.fancybox.stop(t.$content),t.$slide.empty(),l(e)&&e.parent().length?((e.hasClass("fancybox-content")||e.parent().hasClass("fancybox-content"))&&e.parents(".fancybox-slide").trigger("onReset"),t.$placeholder=n("
        ").hide().insertAfter(e),e.css("display","inline-block")):t.hasError||("string"===n.type(e)&&(e=n("
        ").append(n.trim(e)).contents()),t.opts.filter&&(e=n("
        ").html(e).find(t.opts.filter))),t.$slide.one("onReset",function(){n(this).find("video,audio").trigger("pause"),t.$placeholder&&(t.$placeholder.after(e.removeClass("fancybox-content").hide()).remove(),t.$placeholder=null),t.$smallBtn&&(t.$smallBtn.remove(),t.$smallBtn=null),t.hasError||(n(this).empty(),t.isLoaded=!1,t.isRevealed=!1)}),n(e).appendTo(t.$slide),n(e).is("video,audio")&&(n(e).addClass("fancybox-video"),n(e).wrap("
        "),t.contentType="video",t.opts.width=t.opts.width||n(e).attr("width"),t.opts.height=t.opts.height||n(e).attr("height")),t.$content=t.$slide.children().filter("div,form,main,video,audio,article,.fancybox-content").first(),t.$content.siblings().hide(),t.$content.length||(t.$content=t.$slide.wrapInner("
        ").children().first()),t.$content.addClass("fancybox-content"),t.$slide.addClass("fancybox-slide--"+t.contentType),o.afterLoad(t))},setError:function(t){t.hasError=!0,t.$slide.trigger("onReset").removeClass("fancybox-slide--"+t.contentType).addClass("fancybox-slide--error"),t.contentType="html",this.setContent(t,this.translate(t,t.opts.errorTpl)),t.pos===this.currPos&&(this.isAnimating=!1)},showLoading:function(t){var e=this;(t=t||e.current)&&!t.$spinner&&(t.$spinner=n(e.translate(e,e.opts.spinnerTpl)).appendTo(t.$slide).hide().fadeIn("fast"))},hideLoading:function(t){var e=this;(t=t||e.current)&&t.$spinner&&(t.$spinner.stop().remove(),delete t.$spinner)},afterLoad:function(t){var e=this;e.isClosing||(t.isLoading=!1,t.isLoaded=!0,e.trigger("afterLoad",t),e.hideLoading(t),!t.opts.smallBtn||t.$smallBtn&&t.$smallBtn.length||(t.$smallBtn=n(e.translate(t,t.opts.btnTpl.smallBtn)).appendTo(t.$content)),t.opts.protect&&t.$content&&!t.hasError&&(t.$content.on("contextmenu.fb",function(t){return 2==t.button&&t.preventDefault(),!0}),"image"===t.type&&n('
        ').appendTo(t.$content)),e.adjustCaption(t),e.adjustLayout(t),t.pos===e.currPos&&e.updateCursor(),e.revealContent(t))},adjustCaption:function(t){var e,n=this,o=t||n.current,i=o.opts.caption,a=o.opts.preventCaptionOverlap,s=n.$refs.caption,r=!1;s.toggleClass("fancybox-caption--separate",a),a&&i&&i.length&&(o.pos!==n.currPos?(e=s.clone().appendTo(s.parent()),e.children().eq(0).empty().html(i),r=e.outerHeight(!0),e.empty().remove()):n.$caption&&(r=n.$caption.outerHeight(!0)),o.$slide.css("padding-bottom",r||""))},adjustLayout:function(t){var e,n,o,i,a=this,s=t||a.current;s.isLoaded&&!0!==s.opts.disableLayoutFix&&(s.$content.css("margin-bottom",""),s.$content.outerHeight()>s.$slide.height()+.5&&(o=s.$slide[0].style["padding-bottom"],i=s.$slide.css("padding-bottom"),parseFloat(i)>0&&(e=s.$slide[0].scrollHeight,s.$slide.css("padding-bottom",0),Math.abs(e-s.$slide[0].scrollHeight)<1&&(n=i),s.$slide.css("padding-bottom",o))),s.$content.css("margin-bottom",n))},revealContent:function(t){var e,o,i,a,s=this,r=t.$slide,c=!1,l=!1,d=s.isMoved(t),u=t.isRevealed;return t.isRevealed=!0,e=t.opts[s.firstRun?"animationEffect":"transitionEffect"],i=t.opts[s.firstRun?"animationDuration":"transitionDuration"],i=parseInt(void 0===t.forcedDuration?i:t.forcedDuration,10),!d&&t.pos===s.currPos&&i||(e=!1),"zoom"===e&&(t.pos===s.currPos&&i&&"image"===t.type&&!t.hasError&&(l=s.getThumbPos(t))?c=s.getFitPos(t):e="fade"),"zoom"===e?(s.isAnimating=!0,c.scaleX=c.width/l.width,c.scaleY=c.height/l.height,a=t.opts.zoomOpacity,"auto"==a&&(a=Math.abs(t.width/t.height-l.width/l.height)>.1),a&&(l.opacity=.1,c.opacity=1),n.fancybox.setTranslate(t.$content.removeClass("fancybox-is-hidden"),l),p(t.$content),void n.fancybox.animate(t.$content,c,i,function(){s.isAnimating=!1,s.complete()})):(s.updateSlide(t),e?(n.fancybox.stop(r),o="fancybox-slide--"+(t.pos>=s.prevPos?"next":"previous")+" fancybox-animated fancybox-fx-"+e,r.addClass(o).removeClass("fancybox-slide--current"),t.$content.removeClass("fancybox-is-hidden"),p(r),"image"!==t.type&&t.$content.hide().show(0),void n.fancybox.animate(r,"fancybox-slide--current",i,function(){r.removeClass(o).css({transform:"",opacity:""}),t.pos===s.currPos&&s.complete()},!0)):(t.$content.removeClass("fancybox-is-hidden"),u||!d||"image"!==t.type||t.hasError||t.$content.hide().fadeIn("fast"),void(t.pos===s.currPos&&s.complete())))},getThumbPos:function(t){var e,o,i,a,s,r=!1,c=t.$thumb;return!(!c||!g(c[0]))&&(e=n.fancybox.getTranslate(c),o=parseFloat(c.css("border-top-width")||0),i=parseFloat(c.css("border-right-width")||0),a=parseFloat(c.css("border-bottom-width")||0),s=parseFloat(c.css("border-left-width")||0),r={top:e.top+o,left:e.left+s,width:e.width-i-s,height:e.height-o-a,scaleX:1,scaleY:1},e.width>0&&e.height>0&&r)},complete:function(){var t,e=this,o=e.current,i={};!e.isMoved()&&o.isLoaded&&(o.isComplete||(o.isComplete=!0,o.$slide.siblings().trigger("onReset"),e.preload("inline"),p(o.$slide),o.$slide.addClass("fancybox-slide--complete"),n.each(e.slides,function(t,o){o.pos>=e.currPos-1&&o.pos<=e.currPos+1?i[o.pos]=o:o&&(n.fancybox.stop(o.$slide),o.$slide.off().remove())}),e.slides=i),e.isAnimating=!1,e.updateCursor(),e.trigger("afterShow"),o.opts.video.autoStart&&o.$slide.find("video,audio").filter(":visible:first").trigger("play").one("ended",function(){Document.exitFullscreen?Document.exitFullscreen():this.webkitExitFullscreen&&this.webkitExitFullscreen(),e.next()}),o.opts.autoFocus&&"html"===o.contentType&&(t=o.$content.find("input[autofocus]:enabled:visible:first"),t.length?t.trigger("focus"):e.focus(null,!0)),o.$slide.scrollTop(0).scrollLeft(0))},preload:function(t){var e,n,o=this;o.group.length<2||(n=o.slides[o.currPos+1],e=o.slides[o.currPos-1],e&&e.type===t&&o.loadSlide(e),n&&n.type===t&&o.loadSlide(n))},focus:function(t,o){var i,a,s=this,r=["a[href]","area[href]",'input:not([disabled]):not([type="hidden"]):not([aria-hidden])',"select:not([disabled]):not([aria-hidden])","textarea:not([disabled]):not([aria-hidden])","button:not([disabled]):not([aria-hidden])","iframe","object","embed","video","audio","[contenteditable]",'[tabindex]:not([tabindex^="-"])'].join(",");s.isClosing||(i=!t&&s.current&&s.current.isComplete?s.current.$slide.find("*:visible"+(o?":not(.fancybox-close-small)":"")):s.$refs.container.find("*:visible"),i=i.filter(r).filter(function(){return"hidden"!==n(this).css("visibility")&&!n(this).hasClass("disabled")}),i.length?(a=i.index(e.activeElement),t&&t.shiftKey?(a<0||0==a)&&(t.preventDefault(),i.eq(i.length-1).trigger("focus")):(a<0||a==i.length-1)&&(t&&t.preventDefault(),i.eq(0).trigger("focus"))):s.$refs.container.trigger("focus"))},activate:function(){var t=this;n(".fancybox-container").each(function(){var e=n(this).data("FancyBox");e&&e.id!==t.id&&!e.isClosing&&(e.trigger("onDeactivate"),e.removeEvents(),e.isVisible=!1)}),t.isVisible=!0,(t.current||t.isIdle)&&(t.update(),t.updateControls()),t.trigger("onActivate"),t.addEvents()},close:function(t,e){var o,i,a,s,r,c,l,u=this,f=u.current,h=function(){u.cleanUp(t)};return!u.isClosing&&(u.isClosing=!0,!1===u.trigger("beforeClose",t)?(u.isClosing=!1,d(function(){u.update()}),!1):(u.removeEvents(),a=f.$content,o=f.opts.animationEffect,i=n.isNumeric(e)?e:o?f.opts.animationDuration:0,f.$slide.removeClass("fancybox-slide--complete fancybox-slide--next fancybox-slide--previous fancybox-animated"),!0!==t?n.fancybox.stop(f.$slide):o=!1,f.$slide.siblings().trigger("onReset").remove(),i&&u.$refs.container.removeClass("fancybox-is-open").addClass("fancybox-is-closing").css("transition-duration",i+"ms"),u.hideLoading(f),u.hideControls(!0),u.updateCursor(),"zoom"!==o||a&&i&&"image"===f.type&&!u.isMoved()&&!f.hasError&&(l=u.getThumbPos(f))||(o="fade"),"zoom"===o?(n.fancybox.stop(a),s=n.fancybox.getTranslate(a),c={top:s.top,left:s.left,scaleX:s.width/l.width,scaleY:s.height/l.height,width:l.width,height:l.height},r=f.opts.zoomOpacity, -"auto"==r&&(r=Math.abs(f.width/f.height-l.width/l.height)>.1),r&&(l.opacity=0),n.fancybox.setTranslate(a,c),p(a),n.fancybox.animate(a,l,i,h),!0):(o&&i?n.fancybox.animate(f.$slide.addClass("fancybox-slide--previous").removeClass("fancybox-slide--current"),"fancybox-animated fancybox-fx-"+o,i,h):!0===t?setTimeout(h,i):h(),!0)))},cleanUp:function(e){var o,i,a,s=this,r=s.current.opts.$orig;s.current.$slide.trigger("onReset"),s.$refs.container.empty().remove(),s.trigger("afterClose",e),s.current.opts.backFocus&&(r&&r.length&&r.is(":visible")||(r=s.$trigger),r&&r.length&&(i=t.scrollX,a=t.scrollY,r.trigger("focus"),n("html, body").scrollTop(a).scrollLeft(i))),s.current=null,o=n.fancybox.getInstance(),o?o.activate():(n("body").removeClass("fancybox-active compensate-for-scrollbar"),n("#fancybox-style-noscroll").remove())},trigger:function(t,e){var o,i=Array.prototype.slice.call(arguments,1),a=this,s=e&&e.opts?e:a.current;if(s?i.unshift(s):s=a,i.unshift(a),n.isFunction(s.opts[t])&&(o=s.opts[t].apply(s,i)),!1===o)return o;"afterClose"!==t&&a.$refs?a.$refs.container.trigger(t+".fb",i):r.trigger(t+".fb",i)},updateControls:function(){var t=this,o=t.current,i=o.index,a=t.$refs.container,s=t.$refs.caption,r=o.opts.caption;o.$slide.trigger("refresh"),r&&r.length?(t.$caption=s,s.children().eq(0).html(r)):t.$caption=null,t.hasHiddenControls||t.isIdle||t.showControls(),a.find("[data-fancybox-count]").html(t.group.length),a.find("[data-fancybox-index]").html(i+1),a.find("[data-fancybox-prev]").prop("disabled",!o.opts.loop&&i<=0),a.find("[data-fancybox-next]").prop("disabled",!o.opts.loop&&i>=t.group.length-1),"image"===o.type?a.find("[data-fancybox-zoom]").show().end().find("[data-fancybox-download]").attr("href",o.opts.image.src||o.src).show():o.opts.toolbar&&a.find("[data-fancybox-download],[data-fancybox-zoom]").hide(),n(e.activeElement).is(":hidden,[disabled]")&&t.$refs.container.trigger("focus")},hideControls:function(t){var e=this,n=["infobar","toolbar","nav"];!t&&e.current.opts.preventCaptionOverlap||n.push("caption"),this.$refs.container.removeClass(n.map(function(t){return"fancybox-show-"+t}).join(" ")),this.hasHiddenControls=!0},showControls:function(){var t=this,e=t.current?t.current.opts:t.opts,n=t.$refs.container;t.hasHiddenControls=!1,t.idleSecondsCounter=0,n.toggleClass("fancybox-show-toolbar",!(!e.toolbar||!e.buttons)).toggleClass("fancybox-show-infobar",!!(e.infobar&&t.group.length>1)).toggleClass("fancybox-show-caption",!!t.$caption).toggleClass("fancybox-show-nav",!!(e.arrows&&t.group.length>1)).toggleClass("fancybox-is-modal",!!e.modal)},toggleControls:function(){this.hasHiddenControls?this.showControls():this.hideControls()}}),n.fancybox={version:"3.5.7",defaults:a,getInstance:function(t){var e=n('.fancybox-container:not(".fancybox-is-closing"):last').data("FancyBox"),o=Array.prototype.slice.call(arguments,1);return e instanceof b&&("string"===n.type(t)?e[t].apply(e,o):"function"===n.type(t)&&t.apply(e,o),e)},open:function(t,e,n){return new b(t,e,n)},close:function(t){var e=this.getInstance();e&&(e.close(),!0===t&&this.close(t))},destroy:function(){this.close(!0),r.add("body").off("click.fb-start","**")},isMobile:/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),use3d:function(){var n=e.createElement("div");return t.getComputedStyle&&t.getComputedStyle(n)&&t.getComputedStyle(n).getPropertyValue("transform")&&!(e.documentMode&&e.documentMode<11)}(),getTranslate:function(t){var e;return!(!t||!t.length)&&(e=t[0].getBoundingClientRect(),{top:e.top||0,left:e.left||0,width:e.width,height:e.height,opacity:parseFloat(t.css("opacity"))})},setTranslate:function(t,e){var n="",o={};if(t&&e)return void 0===e.left&&void 0===e.top||(n=(void 0===e.left?t.position().left:e.left)+"px, "+(void 0===e.top?t.position().top:e.top)+"px",n=this.use3d?"translate3d("+n+", 0px)":"translate("+n+")"),void 0!==e.scaleX&&void 0!==e.scaleY?n+=" scale("+e.scaleX+", "+e.scaleY+")":void 0!==e.scaleX&&(n+=" scaleX("+e.scaleX+")"),n.length&&(o.transform=n),void 0!==e.opacity&&(o.opacity=e.opacity),void 0!==e.width&&(o.width=e.width),void 0!==e.height&&(o.height=e.height),t.css(o)},animate:function(t,e,o,i,a){var s,r=this;n.isFunction(o)&&(i=o,o=null),r.stop(t),s=r.getTranslate(t),t.on(f,function(c){(!c||!c.originalEvent||t.is(c.originalEvent.target)&&"z-index"!=c.originalEvent.propertyName)&&(r.stop(t),n.isNumeric(o)&&t.css("transition-duration",""),n.isPlainObject(e)?void 0!==e.scaleX&&void 0!==e.scaleY&&r.setTranslate(t,{top:e.top,left:e.left,width:s.width*e.scaleX,height:s.height*e.scaleY,scaleX:1,scaleY:1}):!0!==a&&t.removeClass(e),n.isFunction(i)&&i(c))}),n.isNumeric(o)&&t.css("transition-duration",o+"ms"),n.isPlainObject(e)?(void 0!==e.scaleX&&void 0!==e.scaleY&&(delete e.width,delete e.height,t.parent().hasClass("fancybox-slide--image")&&t.parent().addClass("fancybox-is-scaling")),n.fancybox.setTranslate(t,e)):t.addClass(e),t.data("timer",setTimeout(function(){t.trigger(f)},o+33))},stop:function(t,e){t&&t.length&&(clearTimeout(t.data("timer")),e&&t.trigger(f),t.off(f).css("transition-duration",""),t.parent().removeClass("fancybox-is-scaling"))}},n.fn.fancybox=function(t){var e;return t=t||{},e=t.selector||!1,e?n("body").off("click.fb-start",e).on("click.fb-start",e,{options:t},i):this.off("click.fb-start").on("click.fb-start",{items:this,options:t},i),this},r.on("click.fb-start","[data-fancybox]",i),r.on("click.fb-start","[data-fancybox-trigger]",function(t){n('[data-fancybox="'+n(this).attr("data-fancybox-trigger")+'"]').eq(n(this).attr("data-fancybox-index")||0).trigger("click.fb-start",{$trigger:n(this)})}),function(){var t=null;r.on("mousedown mouseup focus blur",".fancybox-button",function(e){switch(e.type){case"mousedown":t=n(this);break;case"mouseup":t=null;break;case"focusin":n(".fancybox-button").removeClass("fancybox-focus"),n(this).is(t)||n(this).is("[disabled]")||n(this).addClass("fancybox-focus");break;case"focusout":n(".fancybox-button").removeClass("fancybox-focus")}})}()}}(window,document,jQuery),function(t){"use strict";var e={youtube:{matcher:/(youtube\.com|youtu\.be|youtube\-nocookie\.com)\/(watch\?(.*&)?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*))(.*)/i,params:{autoplay:1,autohide:1,fs:1,rel:0,hd:1,wmode:"transparent",enablejsapi:1,html5:1},paramPlace:8,type:"iframe",url:"https://www.youtube-nocookie.com/embed/$4",thumb:"https://img.youtube.com/vi/$4/hqdefault.jpg"},vimeo:{matcher:/^.+vimeo.com\/(.*\/)?([\d]+)(.*)?/,params:{autoplay:1,hd:1,show_title:1,show_byline:1,show_portrait:0,fullscreen:1},paramPlace:3,type:"iframe",url:"//player.vimeo.com/video/$2"},instagram:{matcher:/(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i,type:"image",url:"//$1/p/$2/media/?size=l"},gmap_place:{matcher:/(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(((maps\/(place\/(.*)\/)?\@(.*),(\d+.?\d+?)z))|(\?ll=))(.*)?/i,type:"iframe",url:function(t){return"//maps.google."+t[2]+"/?ll="+(t[9]?t[9]+"&z="+Math.floor(t[10])+(t[12]?t[12].replace(/^\//,"&"):""):t[12]+"").replace(/\?/,"&")+"&output="+(t[12]&&t[12].indexOf("layer=c")>0?"svembed":"embed")}},gmap_search:{matcher:/(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(maps\/search\/)(.*)/i,type:"iframe",url:function(t){return"//maps.google."+t[2]+"/maps?q="+t[5].replace("query=","q=").replace("api=1","")+"&output=embed"}}},n=function(e,n,o){if(e)return o=o||"","object"===t.type(o)&&(o=t.param(o,!0)),t.each(n,function(t,n){e=e.replace("$"+t,n||"")}),o.length&&(e+=(e.indexOf("?")>0?"&":"?")+o),e};t(document).on("objectNeedsType.fb",function(o,i,a){var s,r,c,l,d,u,f,p=a.src||"",h=!1;s=t.extend(!0,{},e,a.opts.media),t.each(s,function(e,o){if(c=p.match(o.matcher)){if(h=o.type,f=e,u={},o.paramPlace&&c[o.paramPlace]){d=c[o.paramPlace],"?"==d[0]&&(d=d.substring(1)),d=d.split("&");for(var i=0;i1&&("youtube"===n.contentSource||"vimeo"===n.contentSource)&&o.load(n.contentSource)}})}(jQuery),function(t,e,n){"use strict";var o=function(){return t.requestAnimationFrame||t.webkitRequestAnimationFrame||t.mozRequestAnimationFrame||t.oRequestAnimationFrame||function(e){return t.setTimeout(e,1e3/60)}}(),i=function(){return t.cancelAnimationFrame||t.webkitCancelAnimationFrame||t.mozCancelAnimationFrame||t.oCancelAnimationFrame||function(e){t.clearTimeout(e)}}(),a=function(e){var n=[];e=e.originalEvent||e||t.e,e=e.touches&&e.touches.length?e.touches:e.changedTouches&&e.changedTouches.length?e.changedTouches:[e];for(var o in e)e[o].pageX?n.push({x:e[o].pageX,y:e[o].pageY}):e[o].clientX&&n.push({x:e[o].clientX,y:e[o].clientY});return n},s=function(t,e,n){return e&&t?"x"===n?t.x-e.x:"y"===n?t.y-e.y:Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2)):0},r=function(t){if(t.is('a,area,button,[role="button"],input,label,select,summary,textarea,video,audio,iframe')||n.isFunction(t.get(0).onclick)||t.data("selectable"))return!0;for(var e=0,o=t[0].attributes,i=o.length;ee.clientHeight,a=("scroll"===o||"auto"===o)&&e.scrollWidth>e.clientWidth;return i||a},l=function(t){for(var e=!1;;){if(e=c(t.get(0)))break;if(t=t.parent(),!t.length||t.hasClass("fancybox-stage")||t.is("body"))break}return e},d=function(t){var e=this;e.instance=t,e.$bg=t.$refs.bg,e.$stage=t.$refs.stage,e.$container=t.$refs.container,e.destroy(),e.$container.on("touchstart.fb.touch mousedown.fb.touch",n.proxy(e,"ontouchstart"))};d.prototype.destroy=function(){var t=this;t.$container.off(".fb.touch"),n(e).off(".fb.touch"),t.requestId&&(i(t.requestId),t.requestId=null),t.tapped&&(clearTimeout(t.tapped),t.tapped=null)},d.prototype.ontouchstart=function(o){var i=this,c=n(o.target),d=i.instance,u=d.current,f=u.$slide,p=u.$content,h="touchstart"==o.type;if(h&&i.$container.off("mousedown.fb.touch"),(!o.originalEvent||2!=o.originalEvent.button)&&f.length&&c.length&&!r(c)&&!r(c.parent())&&(c.is("img")||!(o.originalEvent.clientX>c[0].clientWidth+c.offset().left))){if(!u||d.isAnimating||u.$slide.hasClass("fancybox-animated"))return o.stopPropagation(),void o.preventDefault();i.realPoints=i.startPoints=a(o),i.startPoints.length&&(u.touch&&o.stopPropagation(),i.startEvent=o,i.canTap=!0,i.$target=c,i.$content=p,i.opts=u.opts.touch,i.isPanning=!1,i.isSwiping=!1,i.isZooming=!1,i.isScrolling=!1,i.canPan=d.canPan(),i.startTime=(new Date).getTime(),i.distanceX=i.distanceY=i.distance=0,i.canvasWidth=Math.round(f[0].clientWidth),i.canvasHeight=Math.round(f[0].clientHeight),i.contentLastPos=null,i.contentStartPos=n.fancybox.getTranslate(i.$content)||{top:0,left:0},i.sliderStartPos=n.fancybox.getTranslate(f),i.stagePos=n.fancybox.getTranslate(d.$refs.stage),i.sliderStartPos.top-=i.stagePos.top,i.sliderStartPos.left-=i.stagePos.left,i.contentStartPos.top-=i.stagePos.top,i.contentStartPos.left-=i.stagePos.left,n(e).off(".fb.touch").on(h?"touchend.fb.touch touchcancel.fb.touch":"mouseup.fb.touch mouseleave.fb.touch",n.proxy(i,"ontouchend")).on(h?"touchmove.fb.touch":"mousemove.fb.touch",n.proxy(i,"ontouchmove")),n.fancybox.isMobile&&e.addEventListener("scroll",i.onscroll,!0),((i.opts||i.canPan)&&(c.is(i.$stage)||i.$stage.find(c).length)||(c.is(".fancybox-image")&&o.preventDefault(),n.fancybox.isMobile&&c.parents(".fancybox-caption").length))&&(i.isScrollable=l(c)||l(c.parent()),n.fancybox.isMobile&&i.isScrollable||o.preventDefault(),(1===i.startPoints.length||u.hasError)&&(i.canPan?(n.fancybox.stop(i.$content),i.isPanning=!0):i.isSwiping=!0,i.$container.addClass("fancybox-is-grabbing")),2===i.startPoints.length&&"image"===u.type&&(u.isLoaded||u.$ghost)&&(i.canTap=!1,i.isSwiping=!1,i.isPanning=!1,i.isZooming=!0,n.fancybox.stop(i.$content),i.centerPointStartX=.5*(i.startPoints[0].x+i.startPoints[1].x)-n(t).scrollLeft(),i.centerPointStartY=.5*(i.startPoints[0].y+i.startPoints[1].y)-n(t).scrollTop(),i.percentageOfImageAtPinchPointX=(i.centerPointStartX-i.contentStartPos.left)/i.contentStartPos.width,i.percentageOfImageAtPinchPointY=(i.centerPointStartY-i.contentStartPos.top)/i.contentStartPos.height,i.startDistanceBetweenFingers=s(i.startPoints[0],i.startPoints[1]))))}},d.prototype.onscroll=function(t){var n=this;n.isScrolling=!0,e.removeEventListener("scroll",n.onscroll,!0)},d.prototype.ontouchmove=function(t){var e=this;return void 0!==t.originalEvent.buttons&&0===t.originalEvent.buttons?void e.ontouchend(t):e.isScrolling?void(e.canTap=!1):(e.newPoints=a(t),void((e.opts||e.canPan)&&e.newPoints.length&&e.newPoints.length&&(e.isSwiping&&!0===e.isSwiping||t.preventDefault(),e.distanceX=s(e.newPoints[0],e.startPoints[0],"x"),e.distanceY=s(e.newPoints[0],e.startPoints[0],"y"),e.distance=s(e.newPoints[0],e.startPoints[0]),e.distance>0&&(e.isSwiping?e.onSwipe(t):e.isPanning?e.onPan():e.isZooming&&e.onZoom()))))},d.prototype.onSwipe=function(e){var a,s=this,r=s.instance,c=s.isSwiping,l=s.sliderStartPos.left||0;if(!0!==c)"x"==c&&(s.distanceX>0&&(s.instance.group.length<2||0===s.instance.current.index&&!s.instance.current.opts.loop)?l+=Math.pow(s.distanceX,.8):s.distanceX<0&&(s.instance.group.length<2||s.instance.current.index===s.instance.group.length-1&&!s.instance.current.opts.loop)?l-=Math.pow(-s.distanceX,.8):l+=s.distanceX),s.sliderLastPos={top:"x"==c?0:s.sliderStartPos.top+s.distanceY,left:l},s.requestId&&(i(s.requestId),s.requestId=null),s.requestId=o(function(){s.sliderLastPos&&(n.each(s.instance.slides,function(t,e){var o=e.pos-s.instance.currPos;n.fancybox.setTranslate(e.$slide,{top:s.sliderLastPos.top,left:s.sliderLastPos.left+o*s.canvasWidth+o*e.opts.gutter})}),s.$container.addClass("fancybox-is-sliding"))});else if(Math.abs(s.distance)>10){if(s.canTap=!1,r.group.length<2&&s.opts.vertical?s.isSwiping="y":r.isDragging||!1===s.opts.vertical||"auto"===s.opts.vertical&&n(t).width()>800?s.isSwiping="x":(a=Math.abs(180*Math.atan2(s.distanceY,s.distanceX)/Math.PI),s.isSwiping=a>45&&a<135?"y":"x"),"y"===s.isSwiping&&n.fancybox.isMobile&&s.isScrollable)return void(s.isScrolling=!0);r.isDragging=s.isSwiping,s.startPoints=s.newPoints,n.each(r.slides,function(t,e){var o,i;n.fancybox.stop(e.$slide),o=n.fancybox.getTranslate(e.$slide),i=n.fancybox.getTranslate(r.$refs.stage),e.$slide.css({transform:"",opacity:"","transition-duration":""}).removeClass("fancybox-animated").removeClass(function(t,e){return(e.match(/(^|\s)fancybox-fx-\S+/g)||[]).join(" ")}),e.pos===r.current.pos&&(s.sliderStartPos.top=o.top-i.top,s.sliderStartPos.left=o.left-i.left),n.fancybox.setTranslate(e.$slide,{top:o.top-i.top,left:o.left-i.left})}),r.SlideShow&&r.SlideShow.isActive&&r.SlideShow.stop()}},d.prototype.onPan=function(){var t=this;if(s(t.newPoints[0],t.realPoints[0])<(n.fancybox.isMobile?10:5))return void(t.startPoints=t.newPoints);t.canTap=!1,t.contentLastPos=t.limitMovement(),t.requestId&&i(t.requestId),t.requestId=o(function(){n.fancybox.setTranslate(t.$content,t.contentLastPos)})},d.prototype.limitMovement=function(){var t,e,n,o,i,a,s=this,r=s.canvasWidth,c=s.canvasHeight,l=s.distanceX,d=s.distanceY,u=s.contentStartPos,f=u.left,p=u.top,h=u.width,g=u.height;return i=h>r?f+l:f,a=p+d,t=Math.max(0,.5*r-.5*h),e=Math.max(0,.5*c-.5*g),n=Math.min(r-h,.5*r-.5*h),o=Math.min(c-g,.5*c-.5*g),l>0&&i>t&&(i=t-1+Math.pow(-t+f+l,.8)||0),l<0&&i0&&a>e&&(a=e-1+Math.pow(-e+p+d,.8)||0),d<0&&aa?(t=t>0?0:t,t=ts?(e=e>0?0:e,e=e1&&(o.dMs>130&&s>10||s>50);o.sliderLastPos=null,"y"==t&&!e&&Math.abs(o.distanceY)>50?(n.fancybox.animate(o.instance.current.$slide,{top:o.sliderStartPos.top+o.distanceY+150*o.velocityY,opacity:0},200),i=o.instance.close(!0,250)):r&&o.distanceX>0?i=o.instance.previous(300):r&&o.distanceX<0&&(i=o.instance.next(300)),!1!==i||"x"!=t&&"y"!=t||o.instance.centerSlide(200),o.$container.removeClass("fancybox-is-sliding")},d.prototype.endPanning=function(){var t,e,o,i=this;i.contentLastPos&&(!1===i.opts.momentum||i.dMs>350?(t=i.contentLastPos.left,e=i.contentLastPos.top):(t=i.contentLastPos.left+500*i.velocityX,e=i.contentLastPos.top+500*i.velocityY),o=i.limitPosition(t,e,i.contentStartPos.width,i.contentStartPos.height),o.width=i.contentStartPos.width,o.height=i.contentStartPos.height,n.fancybox.animate(i.$content,o,366))},d.prototype.endZooming=function(){var t,e,o,i,a=this,s=a.instance.current,r=a.newWidth,c=a.newHeight;a.contentLastPos&&(t=a.contentLastPos.left,e=a.contentLastPos.top,i={top:e,left:t,width:r,height:c,scaleX:1,scaleY:1},n.fancybox.setTranslate(a.$content,i),rs.width||c>s.height?a.instance.scaleToActual(a.centerPointStartX,a.centerPointStartY,150):(o=a.limitPosition(t,e,r,c),n.fancybox.animate(a.$content,o,150)))},d.prototype.onTap=function(e){var o,i=this,s=n(e.target),r=i.instance,c=r.current,l=e&&a(e)||i.startPoints,d=l[0]?l[0].x-n(t).scrollLeft()-i.stagePos.left:0,u=l[0]?l[0].y-n(t).scrollTop()-i.stagePos.top:0,f=function(t){var o=c.opts[t];if(n.isFunction(o)&&(o=o.apply(r,[c,e])),o)switch(o){case"close":r.close(i.startEvent);break;case"toggleControls":r.toggleControls();break;case"next":r.next();break;case"nextOrClose":r.group.length>1?r.next():r.close(i.startEvent);break;case"zoom":"image"==c.type&&(c.isLoaded||c.$ghost)&&(r.canPan()?r.scaleToFit():r.isScaledDown()?r.scaleToActual(d,u):r.group.length<2&&r.close(i.startEvent))}};if((!e.originalEvent||2!=e.originalEvent.button)&&(s.is("img")||!(d>s[0].clientWidth+s.offset().left))){if(s.is(".fancybox-bg,.fancybox-inner,.fancybox-outer,.fancybox-container"))o="Outside";else if(s.is(".fancybox-slide"))o="Slide";else{if(!r.current.$content||!r.current.$content.find(s).addBack().filter(s).length)return;o="Content"}if(i.tapped){if(clearTimeout(i.tapped),i.tapped=null,Math.abs(d-i.tapX)>50||Math.abs(u-i.tapY)>50)return this;f("dblclick"+o)}else i.tapX=d,i.tapY=u,c.opts["dblclick"+o]&&c.opts["dblclick"+o]!==c.opts["click"+o]?i.tapped=setTimeout(function(){i.tapped=null,r.isAnimating||f("click"+o)},500):f("click"+o);return this}},n(e).on("onActivate.fb",function(t,e){e&&!e.Guestures&&(e.Guestures=new d(e))}).on("beforeClose.fb",function(t,e){e&&e.Guestures&&e.Guestures.destroy()})}(window,document,jQuery),function(t,e){"use strict";e.extend(!0,e.fancybox.defaults,{btnTpl:{slideShow:''},slideShow:{autoStart:!1,speed:3e3,progress:!0}});var n=function(t){this.instance=t,this.init()};e.extend(n.prototype,{timer:null,isActive:!1,$button:null,init:function(){var t=this,n=t.instance,o=n.group[n.currIndex].opts.slideShow;t.$button=n.$refs.toolbar.find("[data-fancybox-play]").on("click",function(){t.toggle()}),n.group.length<2||!o?t.$button.hide():o.progress&&(t.$progress=e('
        ').appendTo(n.$refs.inner))},set:function(t){var n=this,o=n.instance,i=o.current;i&&(!0===t||i.opts.loop||o.currIndex'},fullScreen:{autoStart:!1}}),e(t).on(n.fullscreenchange,function(){var t=o.isFullscreen(),n=e.fancybox.getInstance();n&&(n.current&&"image"===n.current.type&&n.isAnimating&&(n.isAnimating=!1,n.update(!0,!0,0),n.isComplete||n.complete()),n.trigger("onFullscreenChange",t),n.$refs.container.toggleClass("fancybox-is-fullscreen",t),n.$refs.toolbar.find("[data-fancybox-fullscreen]").toggleClass("fancybox-button--fsenter",!t).toggleClass("fancybox-button--fsexit",t))})}e(t).on({"onInit.fb":function(t,e){var i;if(!n)return void e.$refs.toolbar.find("[data-fancybox-fullscreen]").remove();e&&e.group[e.currIndex].opts.fullScreen?(i=e.$refs.container,i.on("click.fb-fullscreen","[data-fancybox-fullscreen]",function(t){t.stopPropagation(),t.preventDefault(),o.toggle()}),e.opts.fullScreen&&!0===e.opts.fullScreen.autoStart&&o.request(),e.FullScreen=o):e&&e.$refs.toolbar.find("[data-fancybox-fullscreen]").hide()},"afterKeydown.fb":function(t,e,n,o,i){e&&e.FullScreen&&70===i&&(o.preventDefault(),e.FullScreen.toggle())},"beforeClose.fb":function(t,e){e&&e.FullScreen&&e.$refs.container.hasClass("fancybox-is-fullscreen")&&o.exit()}})}(document,jQuery),function(t,e){"use strict";var n="fancybox-thumbs";e.fancybox.defaults=e.extend(!0,{btnTpl:{thumbs:''},thumbs:{autoStart:!1,hideOnClose:!0,parentEl:".fancybox-container",axis:"y"}},e.fancybox.defaults);var o=function(t){this.init(t)};e.extend(o.prototype,{$button:null,$grid:null,$list:null,isVisible:!1,isActive:!1,init:function(t){var e=this,n=t.group,o=0;e.instance=t,e.opts=n[t.currIndex].opts.thumbs,t.Thumbs=e,e.$button=t.$refs.toolbar.find("[data-fancybox-thumbs]");for(var i=0,a=n.length;i1));i++);o>1&&e.opts?(e.$button.removeAttr("style").on("click",function(){e.toggle()}),e.isActive=!0):e.$button.hide()},create:function(){var t,o=this,i=o.instance,a=o.opts.parentEl,s=[];o.$grid||(o.$grid=e('
        ').appendTo(i.$refs.container.find(a).addBack().filter(a)),o.$grid.on("click","a",function(){i.jumpTo(e(this).attr("data-index"))})),o.$list||(o.$list=e('
        ').appendTo(o.$grid)),e.each(i.group,function(e,n){t=n.thumb,t||"image"!==n.type||(t=n.src),s.push('")}),o.$list[0].innerHTML=s.join(""),"x"===o.opts.axis&&o.$list.width(parseInt(o.$grid.css("padding-right"),10)+i.group.length*o.$list.children().eq(0).outerWidth(!0))},focus:function(t){var e,n,o=this,i=o.$list,a=o.$grid;o.instance.current&&(e=i.children().removeClass("fancybox-thumbs-active").filter('[data-index="'+o.instance.current.index+'"]').addClass("fancybox-thumbs-active"),n=e.position(),"y"===o.opts.axis&&(n.top<0||n.top>i.height()-e.outerHeight())?i.stop().animate({scrollTop:i.scrollTop()+n.top},t):"x"===o.opts.axis&&(n.lefta.scrollLeft()+(a.width()-e.outerWidth()))&&i.parent().stop().animate({scrollLeft:n.left},t))},update:function(){var t=this;t.instance.$refs.container.toggleClass("fancybox-show-thumbs",this.isVisible),t.isVisible?(t.$grid||t.create(),t.instance.trigger("onThumbsShow"),t.focus(0)):t.$grid&&t.instance.trigger("onThumbsHide"),t.instance.update()},hide:function(){this.isVisible=!1,this.update()},show:function(){this.isVisible=!0,this.update()},toggle:function(){this.isVisible=!this.isVisible,this.update()}}),e(t).on({"onInit.fb":function(t,e){var n;e&&!e.Thumbs&&(n=new o(e),n.isActive&&!0===n.opts.autoStart&&n.show())},"beforeShow.fb":function(t,e,n,o){var i=e&&e.Thumbs;i&&i.isVisible&&i.focus(o?0:250)},"afterKeydown.fb":function(t,e,n,o,i){var a=e&&e.Thumbs;a&&a.isActive&&71===i&&(o.preventDefault(),a.toggle())},"beforeClose.fb":function(t,e){var n=e&&e.Thumbs;n&&n.isVisible&&!1!==n.opts.hideOnClose&&n.$grid.hide()}})}(document,jQuery),function(t,e){"use strict";function n(t){var e={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};return String(t).replace(/[&<>"'`=\/]/g,function(t){return e[t]})}e.extend(!0,e.fancybox.defaults,{btnTpl:{share:''},share:{url:function(t,e){return!t.currentHash&&"inline"!==e.type&&"html"!==e.type&&(e.origSrc||e.src)||window.location}, -tpl:''}}),e(t).on("click","[data-fancybox-share]",function(){var t,o,i=e.fancybox.getInstance(),a=i.current||null;a&&("function"===e.type(a.opts.share.url)&&(t=a.opts.share.url.apply(a,[i,a])),o=a.opts.share.tpl.replace(/\{\{media\}\}/g,"image"===a.type?encodeURIComponent(a.src):"").replace(/\{\{url\}\}/g,encodeURIComponent(t)).replace(/\{\{url_raw\}\}/g,n(t)).replace(/\{\{descr\}\}/g,i.$caption?encodeURIComponent(i.$caption.text()):""),e.fancybox.open({src:i.translate(i,o),type:"html",opts:{touch:!1,animationEffect:!1,afterLoad:function(t,e){i.$refs.container.one("beforeClose.fb",function(){t.close(null,0)}),e.$content.find(".fancybox-share__button").click(function(){return window.open(this.href,"Share","width=550, height=450"),!1})},mobile:{autoFocus:!1}}}))})}(document,jQuery),function(t,e,n){"use strict";function o(){var e=t.location.hash.substr(1),n=e.split("-"),o=n.length>1&&/^\+?\d+$/.test(n[n.length-1])?parseInt(n.pop(-1),10)||1:1,i=n.join("-");return{hash:e,index:o<1?1:o,gallery:i}}function i(t){""!==t.gallery&&n("[data-fancybox='"+n.escapeSelector(t.gallery)+"']").eq(t.index-1).focus().trigger("click.fb-start")}function a(t){var e,n;return!!t&&(e=t.current?t.current.opts:t.opts,""!==(n=e.hash||(e.$orig?e.$orig.data("fancybox")||e.$orig.data("fancybox-trigger"):""))&&n)}n.escapeSelector||(n.escapeSelector=function(t){return(t+"").replace(/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g,function(t,e){return e?"\0"===t?"�":t.slice(0,-1)+"\\"+t.charCodeAt(t.length-1).toString(16)+" ":"\\"+t})}),n(function(){!1!==n.fancybox.defaults.hash&&(n(e).on({"onInit.fb":function(t,e){var n,i;!1!==e.group[e.currIndex].opts.hash&&(n=o(),(i=a(e))&&n.gallery&&i==n.gallery&&(e.currIndex=n.index-1))},"beforeShow.fb":function(n,o,i,s){var r;i&&!1!==i.opts.hash&&(r=a(o))&&(o.currentHash=r+(o.group.length>1?"-"+(i.index+1):""),t.location.hash!=="#"+o.currentHash&&(s&&!o.origHash&&(o.origHash=t.location.hash),o.hashTimer&&clearTimeout(o.hashTimer),o.hashTimer=setTimeout(function(){"replaceState"in t.history?(t.history[s?"pushState":"replaceState"]({},e.title,t.location.pathname+t.location.search+"#"+o.currentHash),s&&(o.hasCreatedHistory=!0)):t.location.hash=o.currentHash,o.hashTimer=null},300)))},"beforeClose.fb":function(n,o,i){i&&!1!==i.opts.hash&&(clearTimeout(o.hashTimer),o.currentHash&&o.hasCreatedHistory?t.history.back():o.currentHash&&("replaceState"in t.history?t.history.replaceState({},e.title,t.location.pathname+t.location.search+(o.origHash||"")):t.location.hash=o.origHash),o.currentHash=null)}}),n(t).on("hashchange.fb",function(){var t=o(),e=null;n.each(n(".fancybox-container").get().reverse(),function(t,o){var i=n(o).data("FancyBox");if(i&&i.currentHash)return e=i,!1}),e?e.currentHash===t.gallery+"-"+t.index||1===t.index&&e.currentHash==t.gallery||(e.currentHash=null,e.close()):""!==t.gallery&&i(t)}),setTimeout(function(){n.fancybox.getInstance()||i(o())},50))})}(window,document,jQuery),function(t,e){"use strict";var n=(new Date).getTime();e(t).on({"onInit.fb":function(t,e,o){e.$refs.stage.on("mousewheel DOMMouseScroll wheel MozMousePixelScroll",function(t){var o=e.current,i=(new Date).getTime();e.group.length<2||!1===o.opts.wheel||"auto"===o.opts.wheel&&"image"!==o.type||(t.preventDefault(),t.stopPropagation(),o.$slide.hasClass("fancybox-animated")||(t=t.originalEvent||t,i-n<250||(n=i,e[(-t.deltaY||-t.deltaX||t.wheelDelta||-t.detail)<0?"next":"previous"]())))})}})}(document,jQuery); \ No newline at end of file +!(function(t, e, n, o){ + 'use strict'; function i(t, e){ var o; var i; var a; var s = []; var r = 0; t && t.isDefaultPrevented() || (t.preventDefault(), e = e || {}, t && t.data && (e = h(t.data.options, e)), o = e.$target || n(t.currentTarget).trigger('blur'), (a = n.fancybox.getInstance()) && a.$trigger && a.$trigger.is(o) || (e.selector ? s = n(e.selector) : (i = o.attr('data-fancybox') || '', i ? (s = t.data ? t.data.items : [], s = s.length ? s.filter('[data-fancybox="' + i + '"]') : n('[data-fancybox="' + i + '"]')) : s = [o]), r = n(s).index(o), r < 0 && (r = 0), a = n.fancybox.open(s, e, r), a.$trigger = o)); } if (t.console = t.console || { info: function(t){} }, n){ + if (n.fn.fancybox) return void console.info('fancyBox already initialized'); var a = { closeExisting: !1, loop: !1, gutter: 50, keyboard: !0, preventCaptionOverlap: !0, arrows: !0, infobar: !0, smallBtn: 'auto', toolbar: 'auto', buttons: ['zoom', 'slideShow', 'thumbs', 'close'], idleTime: 3, protect: !1, modal: !1, image: { preload: !1 }, ajax: { settings: { data: { fancybox: !0 } } }, iframe: { tpl: '', preload: !0, css: {}, attr: { scrolling: 'auto' } }, video: { tpl: '', format: '', autoStart: !0 }, defaultType: 'image', animationEffect: 'zoom', animationDuration: 366, zoomOpacity: 'auto', transitionEffect: 'fade', transitionDuration: 366, slideClass: '', baseClass: '', baseTpl: '', spinnerTpl: '
        ', errorTpl: '

        {{ERROR}}

        ', btnTpl: { download: '', zoom: '', close: '', arrowLeft: '', arrowRight: '', smallBtn: '' }, parentEl: 'body', hideScrollbar: !0, autoFocus: !0, backFocus: !0, trapFocus: !0, fullScreen: { autoStart: !1 }, touch: { vertical: !0, momentum: !0 }, hash: null, media: {}, slideShow: { autoStart: !1, speed: 3e3 }, thumbs: { autoStart: !1, hideOnClose: !0, parentEl: '.fancybox-container', axis: 'y' }, wheel: 'auto', onInit: n.noop, beforeLoad: n.noop, afterLoad: n.noop, beforeShow: n.noop, afterShow: n.noop, beforeClose: n.noop, afterClose: n.noop, onActivate: n.noop, onDeactivate: n.noop, clickContent: function(t, e){ return t.type === 'image' && 'zoom'; }, clickSlide: 'close', clickOutside: 'close', dblclickContent: !1, dblclickSlide: !1, dblclickOutside: !1, mobile: { preventCaptionOverlap: !1, idleTime: !1, clickContent: function(t, e){ return t.type === 'image' && 'toggleControls'; }, clickSlide: function(t, e){ return t.type === 'image' ? 'toggleControls' : 'close'; }, dblclickContent: function(t, e){ return t.type === 'image' && 'zoom'; }, dblclickSlide: function(t, e){ return t.type === 'image' && 'zoom'; } }, lang: 'en', i18n: { en: { CLOSE: 'Close', NEXT: 'Next', PREV: 'Previous', ERROR: 'The requested content cannot be loaded.
        Please try again later.', PLAY_START: 'Start slideshow', PLAY_STOP: 'Pause slideshow', FULL_SCREEN: 'Full screen', THUMBS: 'Thumbnails', DOWNLOAD: 'Download', SHARE: 'Share', ZOOM: 'Zoom' }, de: { CLOSE: 'Schließen', NEXT: 'Weiter', PREV: 'Zurück', ERROR: 'Die angeforderten Daten konnten nicht geladen werden.
        Bitte versuchen Sie es später nochmal.', PLAY_START: 'Diaschau starten', PLAY_STOP: 'Diaschau beenden', FULL_SCREEN: 'Vollbild', THUMBS: 'Vorschaubilder', DOWNLOAD: 'Herunterladen', SHARE: 'Teilen', ZOOM: 'Vergrößern' } } }; var s = n(t); var r = n(e); var c = 0; var l = function(t){ return t && t.hasOwnProperty && t instanceof n; }; var d = (function(){ return t.requestAnimationFrame || t.webkitRequestAnimationFrame || t.mozRequestAnimationFrame || t.oRequestAnimationFrame || function(e){ return t.setTimeout(e, 1e3 / 60); }; }()); var u = (function(){ return t.cancelAnimationFrame || t.webkitCancelAnimationFrame || t.mozCancelAnimationFrame || t.oCancelAnimationFrame || function(e){ t.clearTimeout(e); }; }()); var f = (function(){ var t; var n = e.createElement('fakeelement'); var o = { transition: 'transitionend', OTransition: 'oTransitionEnd', MozTransition: 'transitionend', WebkitTransition: 'webkitTransitionEnd' }; for (t in o) if (void 0 !== n.style[t]) return o[t]; return 'transitionend'; }()); var p = function(t){ return t && t.length && t[0].offsetHeight; }; var h = function(t, e){ var o = n.extend(!0, {}, t, e); return n.each(e, function(t, e){ n.isArray(e) && (o[t] = e); }), o; }; var g = function(t){ var o, i; return !(!t || t.ownerDocument !== e) && (n('.fancybox-container').css('pointer-events', 'none'), o = { x: t.getBoundingClientRect().left + t.offsetWidth / 2, y: t.getBoundingClientRect().top + t.offsetHeight / 2 }, i = e.elementFromPoint(o.x, o.y) === t, n('.fancybox-container').css('pointer-events', ''), i); }; var b = function(t, e, o){ var i = this; i.opts = h({ index: o }, n.fancybox.defaults), n.isPlainObject(e) && (i.opts = h(i.opts, e)), n.fancybox.isMobile && (i.opts = h(i.opts, i.opts.mobile)), i.id = i.opts.id || ++c, i.currIndex = parseInt(i.opts.index, 10) || 0, i.prevIndex = null, i.prevPos = null, i.currPos = 0, i.firstRun = !0, i.group = [], i.slides = {}, i.addContent(t), i.group.length && i.init(); }; n.extend(b.prototype, { + init: function(){ var o; var i; var a = this; var s = a.group[a.currIndex]; var r = s.opts; r.closeExisting && n.fancybox.close(!0), n('body').addClass('fancybox-active'), !n.fancybox.getInstance() && !1 !== r.hideScrollbar && !n.fancybox.isMobile && e.body.scrollHeight > t.innerHeight && (n('head').append(''), n('body').addClass('compensate-for-scrollbar')), i = '', n.each(r.buttons, function(t, e){ i += r.btnTpl[e] || ''; }), o = n(a.translate(a, r.baseTpl.replace('{{buttons}}', i).replace('{{arrows}}', r.btnTpl.arrowLeft + r.btnTpl.arrowRight))).attr('id', 'fancybox-container-' + a.id).addClass(r.baseClass).data('FancyBox', a).appendTo(r.parentEl), a.$refs = { container: o }, ['bg', 'inner', 'infobar', 'toolbar', 'stage', 'caption', 'navigation'].forEach(function(t){ a.$refs[t] = o.find('.fancybox-' + t); }), a.trigger('onInit'), a.activate(), a.jumpTo(a.currIndex); }, + translate: function(t, e){ var n = t.opts.i18n[t.opts.lang] || t.opts.i18n.en; return e.replace(/\{\{(\w+)\}\}/g, function(t, e){ return void 0 === n[e] ? t : n[e]; }); }, + addContent: function(t){ var e; var o = this; var i = n.makeArray(t); n.each(i, function(t, e){ var i; var a; var s; var r; var c; var l = {}; var d = {}; n.isPlainObject(e) ? (l = e, d = e.opts || e) : n.type(e) === 'object' && n(e).length ? (i = n(e), d = i.data() || {}, d = n.extend(!0, {}, d, d.options), d.$orig = i, l.src = o.opts.src || d.src || i.attr('href'), l.type || l.src || (l.type = 'inline', l.src = e)) : l = { type: 'html', src: e + '' }, l.opts = n.extend(!0, {}, o.opts, d), n.isArray(d.buttons) && (l.opts.buttons = d.buttons), n.fancybox.isMobile && l.opts.mobile && (l.opts = h(l.opts, l.opts.mobile)), a = l.type || l.opts.type, r = l.src || '', !a && r && ((s = r.match(/\.(mp4|mov|ogv|webm)((\?|#).*)?$/i)) ? (a = 'video', l.opts.video.format || (l.opts.video.format = 'video/' + (s[1] === 'ogv' ? 'ogg' : s[1]))) : r.match(/(^data:image\/[a-z0-9+\/=]*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg|ico)((\?|#).*)?$)/i) ? a = 'image' : r.match(/\.(pdf)((\?|#).*)?$/i) ? (a = 'iframe', l = n.extend(!0, l, { contentType: 'pdf', opts: { iframe: { preload: !1 } } })) : r.charAt(0) === '#' && (a = 'inline')), a ? l.type = a : o.trigger('objectNeedsType', l), l.contentType || (l.contentType = n.inArray(l.type, ['html', 'inline', 'ajax']) > -1 ? 'html' : l.type), l.index = o.group.length, l.opts.smallBtn == 'auto' && (l.opts.smallBtn = n.inArray(l.type, ['html', 'inline', 'ajax']) > -1), l.opts.toolbar === 'auto' && (l.opts.toolbar = !l.opts.smallBtn), l.$thumb = l.opts.$thumb || null, l.opts.$trigger && l.index === o.opts.index && (l.$thumb = l.opts.$trigger.find('img:first'), l.$thumb.length && (l.opts.$orig = l.opts.$trigger)), l.$thumb && l.$thumb.length || !l.opts.$orig || (l.$thumb = l.opts.$orig.find('img:first')), l.$thumb && !l.$thumb.length && (l.$thumb = null), l.thumb = l.opts.thumb || (l.$thumb ? l.$thumb[0].src : null), n.type(l.opts.caption) === 'function' && (l.opts.caption = l.opts.caption.apply(e, [o, l])), n.type(o.opts.caption) === 'function' && (l.opts.caption = o.opts.caption.apply(e, [o, l])), l.opts.caption instanceof n || (l.opts.caption = void 0 === l.opts.caption ? '' : l.opts.caption + ''), l.type === 'ajax' && (c = r.split(/\s+/, 2), c.length > 1 && (l.src = c.shift(), l.opts.filter = c.shift())), l.opts.modal && (l.opts = n.extend(!0, l.opts, { trapFocus: !0, infobar: 0, toolbar: 0, smallBtn: 0, keyboard: 0, slideShow: 0, fullScreen: 0, thumbs: 0, touch: 0, clickContent: !1, clickSlide: !1, clickOutside: !1, dblclickContent: !1, dblclickSlide: !1, dblclickOutside: !1 })), o.group.push(l); }), Object.keys(o.slides).length && (o.updateControls(), (e = o.Thumbs) && e.isActive && (e.create(), e.focus())); }, + addEvents: function(){ var e = this; e.removeEvents(), e.$refs.container.on('click.fb-close', '[data-fancybox-close]', function(t){ t.stopPropagation(), t.preventDefault(), e.close(t); }).on('touchstart.fb-prev click.fb-prev', '[data-fancybox-prev]', function(t){ t.stopPropagation(), t.preventDefault(), e.previous(); }).on('touchstart.fb-next click.fb-next', '[data-fancybox-next]', function(t){ t.stopPropagation(), t.preventDefault(), e.next(); }).on('click.fb', '[data-fancybox-zoom]', function(t){ e[e.isScaledDown() ? 'scaleToActual' : 'scaleToFit'](); }), s.on('orientationchange.fb resize.fb', function(t){ t && t.originalEvent && t.originalEvent.type === 'resize' ? (e.requestId && u(e.requestId), e.requestId = d(function(){ e.update(t); })) : (e.current && e.current.type === 'iframe' && e.$refs.stage.hide(), setTimeout(function(){ e.$refs.stage.show(), e.update(t); }, n.fancybox.isMobile ? 600 : 250)); }), r.on('keydown.fb', function(t){ var o = n.fancybox ? n.fancybox.getInstance() : null; var i = o.current; var a = t.keyCode || t.which; if (a == 9) return void (i.opts.trapFocus && e.focus(t)); if (!(!i.opts.keyboard || t.ctrlKey || t.altKey || t.shiftKey || n(t.target).is('input,textarea,video,audio,select'))) return a === 8 || a === 27 ? (t.preventDefault(), void e.close(t)) : a === 37 || a === 38 ? (t.preventDefault(), void e.previous()) : a === 39 || a === 40 ? (t.preventDefault(), void e.next()) : void e.trigger('afterKeydown', t, a); }), e.group[e.currIndex].opts.idleTime && (e.idleSecondsCounter = 0, r.on('mousemove.fb-idle mouseleave.fb-idle mousedown.fb-idle touchstart.fb-idle touchmove.fb-idle scroll.fb-idle keydown.fb-idle', function(t){ e.idleSecondsCounter = 0, e.isIdle && e.showControls(), e.isIdle = !1; }), e.idleInterval = t.setInterval(function(){ ++e.idleSecondsCounter >= e.group[e.currIndex].opts.idleTime && !e.isDragging && (e.isIdle = !0, e.idleSecondsCounter = 0, e.hideControls()); }, 1e3)); }, + removeEvents: function(){ var e = this; s.off('orientationchange.fb resize.fb'), r.off('keydown.fb .fb-idle'), this.$refs.container.off('.fb-close .fb-prev .fb-next'), e.idleInterval && (t.clearInterval(e.idleInterval), e.idleInterval = null); }, + previous: function(t){ return this.jumpTo(this.currPos - 1, t); }, + next: function(t){ return this.jumpTo(this.currPos + 1, t); }, + jumpTo: function(t, e){ var o; var i; var a; var s; var r; var c; var l; var d; var u; var f = this; var h = f.group.length; if (!(f.isDragging || f.isClosing || f.isAnimating && f.firstRun)){ if (t = parseInt(t, 10), !(a = f.current ? f.current.opts.loop : f.opts.loop) && (t < 0 || t >= h)) return !1; if (o = f.firstRun = !Object.keys(f.slides).length, r = f.current, f.prevIndex = f.currIndex, f.prevPos = f.currPos, s = f.createSlide(t), h > 1 && ((a || s.index < h - 1) && f.createSlide(t + 1), (a || s.index > 0) && f.createSlide(t - 1)), f.current = s, f.currIndex = s.index, f.currPos = s.pos, f.trigger('beforeShow', o), f.updateControls(), s.forcedDuration = void 0, n.isNumeric(e) ? s.forcedDuration = e : e = s.opts[o ? 'animationDuration' : 'transitionDuration'], e = parseInt(e, 10), i = f.isMoved(s), s.$slide.addClass('fancybox-slide--current'), o) return s.opts.animationEffect && e && f.$refs.container.css('transition-duration', e + 'ms'), f.$refs.container.addClass('fancybox-is-open').trigger('focus'), f.loadSlide(s), void f.preload('image'); c = n.fancybox.getTranslate(r.$slide), l = n.fancybox.getTranslate(f.$refs.stage), n.each(f.slides, function(t, e){ n.fancybox.stop(e.$slide, !0); }), r.pos !== s.pos && (r.isComplete = !1), r.$slide.removeClass('fancybox-slide--complete fancybox-slide--current'), i ? (u = c.left - (r.pos * c.width + r.pos * r.opts.gutter), n.each(f.slides, function(t, o){ o.$slide.removeClass('fancybox-animated').removeClass(function(t, e){ return (e.match(/(^|\s)fancybox-fx-\S+/g) || []).join(' '); }); var i = o.pos * c.width + o.pos * o.opts.gutter; n.fancybox.setTranslate(o.$slide, { top: 0, left: i - l.left + u }), o.pos !== s.pos && o.$slide.addClass('fancybox-slide--' + (o.pos > s.pos ? 'next' : 'previous')), p(o.$slide), n.fancybox.animate(o.$slide, { top: 0, left: (o.pos - s.pos) * c.width + (o.pos - s.pos) * o.opts.gutter }, e, function(){ o.$slide.css({ transform: '', opacity: '' }).removeClass('fancybox-slide--next fancybox-slide--previous'), o.pos === f.currPos && f.complete(); }); })) : e && s.opts.transitionEffect && (d = 'fancybox-animated fancybox-fx-' + s.opts.transitionEffect, r.$slide.addClass('fancybox-slide--' + (r.pos > s.pos ? 'next' : 'previous')), n.fancybox.animate(r.$slide, d, e, function(){ r.$slide.removeClass(d).removeClass('fancybox-slide--next fancybox-slide--previous'); }, !1)), s.isLoaded ? f.revealContent(s) : f.loadSlide(s), f.preload('image'); } }, + createSlide: function(t){ var e; var o; var i = this; return o = t % i.group.length, o = o < 0 ? i.group.length + o : o, !i.slides[t] && i.group[o] && (e = n('
        ').appendTo(i.$refs.stage), i.slides[t] = n.extend(!0, {}, i.group[o], { pos: t, $slide: e, isLoaded: !1 }), i.updateSlide(i.slides[t])), i.slides[t]; }, + scaleToActual: function(t, e, o){ var i; var a; var s; var r; var c; var l = this; var d = l.current; var u = d.$content; var f = n.fancybox.getTranslate(d.$slide).width; var p = n.fancybox.getTranslate(d.$slide).height; var h = d.width; var g = d.height; l.isAnimating || l.isMoved() || !u || d.type != 'image' || !d.isLoaded || d.hasError || (l.isAnimating = !0, n.fancybox.stop(u), t = void 0 === t ? 0.5 * f : t, e = void 0 === e ? 0.5 * p : e, i = n.fancybox.getTranslate(u), i.top -= n.fancybox.getTranslate(d.$slide).top, i.left -= n.fancybox.getTranslate(d.$slide).left, r = h / i.width, c = g / i.height, a = 0.5 * f - 0.5 * h, s = 0.5 * p - 0.5 * g, h > f && (a = i.left * r - (t * r - t), a > 0 && (a = 0), a < f - h && (a = f - h)), g > p && (s = i.top * c - (e * c - e), s > 0 && (s = 0), s < p - g && (s = p - g)), l.updateCursor(h, g), n.fancybox.animate(u, { top: s, left: a, scaleX: r, scaleY: c }, o || 366, function(){ l.isAnimating = !1; }), l.SlideShow && l.SlideShow.isActive && l.SlideShow.stop()); }, + scaleToFit: function(t){ var e; var o = this; var i = o.current; var a = i.$content; o.isAnimating || o.isMoved() || !a || i.type != 'image' || !i.isLoaded || i.hasError || (o.isAnimating = !0, n.fancybox.stop(a), e = o.getFitPos(i), o.updateCursor(e.width, e.height), n.fancybox.animate(a, { top: e.top, left: e.left, scaleX: e.width / a.width(), scaleY: e.height / a.height() }, t || 366, function(){ o.isAnimating = !1; })); }, + getFitPos: function(t){ var e; var o; var i; var a; var s = this; var r = t.$content; var c = t.$slide; var l = t.width || t.opts.width; var d = t.height || t.opts.height; var u = {}; return !!(t.isLoaded && r && r.length) && (e = n.fancybox.getTranslate(s.$refs.stage).width, o = n.fancybox.getTranslate(s.$refs.stage).height, e -= parseFloat(c.css('paddingLeft')) + parseFloat(c.css('paddingRight')) + parseFloat(r.css('marginLeft')) + parseFloat(r.css('marginRight')), o -= parseFloat(c.css('paddingTop')) + parseFloat(c.css('paddingBottom')) + parseFloat(r.css('marginTop')) + parseFloat(r.css('marginBottom')), l && d || (l = e, d = o), i = Math.min(1, e / l, o / d), l *= i, d *= i, l > e - 0.5 && (l = e), d > o - 0.5 && (d = o), t.type === 'image' ? (u.top = Math.floor(0.5 * (o - d)) + parseFloat(c.css('paddingTop')), u.left = Math.floor(0.5 * (e - l)) + parseFloat(c.css('paddingLeft'))) : t.contentType === 'video' && (a = t.opts.width && t.opts.height ? l / d : t.opts.ratio || 16 / 9, d > l / a ? d = l / a : l > d * a && (l = d * a)), u.width = l, u.height = d, u); }, + update: function(t){ var e = this; n.each(e.slides, function(n, o){ e.updateSlide(o, t); }); }, + updateSlide: function(t, e){ var o = this; var i = t && t.$content; var a = t.width || t.opts.width; var s = t.height || t.opts.height; var r = t.$slide; o.adjustCaption(t), i && (a || s || t.contentType === 'video') && !t.hasError && (n.fancybox.stop(i), n.fancybox.setTranslate(i, o.getFitPos(t)), t.pos === o.currPos && (o.isAnimating = !1, o.updateCursor())), o.adjustLayout(t), r.length && (r.trigger('refresh'), t.pos === o.currPos && o.$refs.toolbar.add(o.$refs.navigation.find('.fancybox-button--arrow_right')).toggleClass('compensate-for-scrollbar', r.get(0).scrollHeight > r.get(0).clientHeight)), o.trigger('onUpdate', t, e); }, + centerSlide: function(t){ var e = this; var o = e.current; var i = o.$slide; !e.isClosing && o && (i.siblings().css({ transform: '', opacity: '' }), i.parent().children().removeClass('fancybox-slide--previous fancybox-slide--next'), n.fancybox.animate(i, { top: 0, left: 0, opacity: 1 }, void 0 === t ? 0 : t, function(){ i.css({ transform: '', opacity: '' }), o.isComplete || e.complete(); }, !1)); }, + isMoved: function(t){ var e; var o; var i = t || this.current; return !!i && (o = n.fancybox.getTranslate(this.$refs.stage), e = n.fancybox.getTranslate(i.$slide), !i.$slide.hasClass('fancybox-animated') && (Math.abs(e.top - o.top) > 0.5 || Math.abs(e.left - o.left) > 0.5)); }, + updateCursor: function(t, e){ var o; var i; var a = this; var s = a.current; var r = a.$refs.container; s && !a.isClosing && a.Guestures && (r.removeClass('fancybox-is-zoomable fancybox-can-zoomIn fancybox-can-zoomOut fancybox-can-swipe fancybox-can-pan'), o = a.canPan(t, e), i = !!o || a.isZoomable(), r.toggleClass('fancybox-is-zoomable', i), n('[data-fancybox-zoom]').prop('disabled', !i), o ? r.addClass('fancybox-can-pan') : i && (s.opts.clickContent === 'zoom' || n.isFunction(s.opts.clickContent) && s.opts.clickContent(s) == 'zoom') ? r.addClass('fancybox-can-zoomIn') : s.opts.touch && (s.opts.touch.vertical || a.group.length > 1) && s.contentType !== 'video' && r.addClass('fancybox-can-swipe')); }, + isZoomable: function(){ var t; var e = this; var n = e.current; if (n && !e.isClosing && n.type === 'image' && !n.hasError){ if (!n.isLoaded) return !0; if ((t = e.getFitPos(n)) && (n.width > t.width || n.height > t.height)) return !0; } return !1; }, + isScaledDown: function(t, e){ var o = this; var i = !1; var a = o.current; var s = a.$content; return void 0 !== t && void 0 !== e ? i = t < a.width && e < a.height : s && (i = n.fancybox.getTranslate(s), i = i.width < a.width && i.height < a.height), i; }, + canPan: function(t, e){ var o = this; var i = o.current; var a = null; var s = !1; return i.type === 'image' && (i.isComplete || t && e) && !i.hasError && (s = o.getFitPos(i), void 0 !== t && void 0 !== e ? a = { width: t, height: e } : i.isComplete && (a = n.fancybox.getTranslate(i.$content)), a && s && (s = Math.abs(a.width - s.width) > 1.5 || Math.abs(a.height - s.height) > 1.5)), s; }, + loadSlide: function(t){ var e; var o; var i; var a = this; if (!t.isLoading && !t.isLoaded){ if (t.isLoading = !0, !1 === a.trigger('beforeLoad', t)) return t.isLoading = !1, !1; switch (e = t.type, o = t.$slide, o.off('refresh').trigger('onReset').addClass(t.opts.slideClass), e){ case 'image':a.setImage(t); break; case 'iframe':a.setIframe(t); break; case 'html':a.setContent(t, t.src || t.content); break; case 'video':a.setContent(t, t.opts.video.tpl.replace(/\{\{src\}\}/gi, t.src).replace('{{format}}', t.opts.videoFormat || t.opts.video.format || '').replace('{{poster}}', t.thumb || '')); break; case 'inline':n(t.src).length ? a.setContent(t, n(t.src)) : a.setError(t); break; case 'ajax':a.showLoading(t), i = n.ajax(n.extend({}, t.opts.ajax.settings, { url: t.src, success: function(e, n){ n === 'success' && a.setContent(t, e); }, error: function(e, n){ e && n !== 'abort' && a.setError(t); } })), o.one('onReset', function(){ i.abort(); }); break; default:a.setError(t); } return !0; } }, + setImage: function(t){ var o; var i = this; setTimeout(function(){ var e = t.$image; i.isClosing || !t.isLoading || e && e.length && e[0].complete || t.hasError || i.showLoading(t); }, 50), i.checkSrcset(t), t.$content = n('
        ').addClass('fancybox-is-hidden').appendTo(t.$slide.addClass('fancybox-slide--image')), !1 !== t.opts.preload && t.opts.width && t.opts.height && t.thumb && (t.width = t.opts.width, t.height = t.opts.height, o = e.createElement('img'), o.onerror = function(){ n(this).remove(), t.$ghost = null; }, o.onload = function(){ i.afterLoad(t); }, t.$ghost = n(o).addClass('fancybox-image').appendTo(t.$content).attr('src', t.thumb)), i.setBigImage(t); }, + checkSrcset: function(e){ var n; var o; var i; var a; var s = e.opts.srcset || e.opts.image.srcset; if (s){ i = t.devicePixelRatio || 1, a = t.innerWidth * i, o = s.split(',').map(function(t){ var e = {}; return t.trim().split(/\s+/).forEach(function(t, n){ var o = parseInt(t.substring(0, t.length - 1), 10); if (n === 0) return e.url = t; o && (e.value = o, e.postfix = t[t.length - 1]); }), e; }), o.sort(function(t, e){ return t.value - e.value; }); for (var r = 0; r < o.length; r++){ var c = o[r]; if (c.postfix === 'w' && c.value >= a || c.postfix === 'x' && c.value >= i){ n = c; break; } }!n && o.length && (n = o[o.length - 1]), n && (e.src = n.url, e.width && e.height && n.postfix == 'w' && (e.height = e.width / e.height * n.value, e.width = n.value), e.opts.srcset = s); } }, + setBigImage: function(t){ var o = this; var i = e.createElement('img'); var a = n(i); t.$image = a.one('error', function(){ o.setError(t); }).one('load', function(){ var e; t.$ghost || (o.resolveImageSlideSize(t, this.naturalWidth, this.naturalHeight), o.afterLoad(t)), o.isClosing || (t.opts.srcset && (e = t.opts.sizes, e && e !== 'auto' || (e = (t.width / t.height > 1 && s.width() / s.height() > 1 ? '100' : Math.round(t.width / t.height * 100)) + 'vw'), a.attr('sizes', e).attr('srcset', t.opts.srcset)), t.$ghost && setTimeout(function(){ t.$ghost && !o.isClosing && t.$ghost.hide(); }, Math.min(300, Math.max(1e3, t.height / 1600))), o.hideLoading(t)); }).addClass('fancybox-image').attr('src', t.src).appendTo(t.$content), (i.complete || i.readyState == 'complete') && a.naturalWidth && a.naturalHeight ? a.trigger('load') : i.error && a.trigger('error'); }, + resolveImageSlideSize: function(t, e, n){ var o = parseInt(t.opts.width, 10); var i = parseInt(t.opts.height, 10); t.width = e, t.height = n, o > 0 && (t.width = o, t.height = Math.floor(o * n / e)), i > 0 && (t.width = Math.floor(i * e / n), t.height = i); }, + setIframe: function(t){ var e; var o = this; var i = t.opts.iframe; var a = t.$slide; t.$content = n('
        ').css(i.css).appendTo(a), a.addClass('fancybox-slide--' + t.contentType), t.$iframe = e = n(i.tpl.replace(/\{rnd\}/g, (new Date()).getTime())).attr(i.attr).appendTo(t.$content), i.preload ? (o.showLoading(t), e.on('load.fb error.fb', function(e){ this.isReady = 1, t.$slide.trigger('refresh'), o.afterLoad(t); }), a.on('refresh.fb', function(){ var n; var o; var s = t.$content; var r = i.css.width; var c = i.css.height; if (e[0].isReady === 1){ try { n = e.contents(), o = n.find('body'); } catch (t){}o && o.length && o.children().length && (a.css('overflow', 'visible'), s.css({ width: '100%', 'max-width': '100%', height: '9999px' }), void 0 === r && (r = Math.ceil(Math.max(o[0].clientWidth, o.outerWidth(!0)))), s.css('width', r || '').css('max-width', ''), void 0 === c && (c = Math.ceil(Math.max(o[0].clientHeight, o.outerHeight(!0)))), s.css('height', c || ''), a.css('overflow', 'auto')), s.removeClass('fancybox-is-hidden'); } })) : o.afterLoad(t), e.attr('src', t.src), a.one('onReset', function(){ try { n(this).find('iframe').hide().unbind().attr('src', '//about:blank'); } catch (t){}n(this).off('refresh.fb').empty(), t.isLoaded = !1, t.isRevealed = !1; }); }, + setContent: function(t, e){ var o = this; o.isClosing || (o.hideLoading(t), t.$content && n.fancybox.stop(t.$content), t.$slide.empty(), l(e) && e.parent().length ? ((e.hasClass('fancybox-content') || e.parent().hasClass('fancybox-content')) && e.parents('.fancybox-slide').trigger('onReset'), t.$placeholder = n('
        ').hide().insertAfter(e), e.css('display', 'inline-block')) : t.hasError || (n.type(e) === 'string' && (e = n('
        ').append(n.trim(e)).contents()), t.opts.filter && (e = n('
        ').html(e).find(t.opts.filter))), t.$slide.one('onReset', function(){ n(this).find('video,audio').trigger('pause'), t.$placeholder && (t.$placeholder.after(e.removeClass('fancybox-content').hide()).remove(), t.$placeholder = null), t.$smallBtn && (t.$smallBtn.remove(), t.$smallBtn = null), t.hasError || (n(this).empty(), t.isLoaded = !1, t.isRevealed = !1); }), n(e).appendTo(t.$slide), n(e).is('video,audio') && (n(e).addClass('fancybox-video'), n(e).wrap('
        '), t.contentType = 'video', t.opts.width = t.opts.width || n(e).attr('width'), t.opts.height = t.opts.height || n(e).attr('height')), t.$content = t.$slide.children().filter('div,form,main,video,audio,article,.fancybox-content').first(), t.$content.siblings().hide(), t.$content.length || (t.$content = t.$slide.wrapInner('
        ').children().first()), t.$content.addClass('fancybox-content'), t.$slide.addClass('fancybox-slide--' + t.contentType), o.afterLoad(t)); }, + setError: function(t){ t.hasError = !0, t.$slide.trigger('onReset').removeClass('fancybox-slide--' + t.contentType).addClass('fancybox-slide--error'), t.contentType = 'html', this.setContent(t, this.translate(t, t.opts.errorTpl)), t.pos === this.currPos && (this.isAnimating = !1); }, + showLoading: function(t){ var e = this; (t = t || e.current) && !t.$spinner && (t.$spinner = n(e.translate(e, e.opts.spinnerTpl)).appendTo(t.$slide).hide().fadeIn('fast')); }, + hideLoading: function(t){ var e = this; (t = t || e.current) && t.$spinner && (t.$spinner.stop().remove(), delete t.$spinner); }, + afterLoad: function(t){ var e = this; e.isClosing || (t.isLoading = !1, t.isLoaded = !0, e.trigger('afterLoad', t), e.hideLoading(t), !t.opts.smallBtn || t.$smallBtn && t.$smallBtn.length || (t.$smallBtn = n(e.translate(t, t.opts.btnTpl.smallBtn)).appendTo(t.$content)), t.opts.protect && t.$content && !t.hasError && (t.$content.on('contextmenu.fb', function(t){ return t.button == 2 && t.preventDefault(), !0; }), t.type === 'image' && n('
        ').appendTo(t.$content)), e.adjustCaption(t), e.adjustLayout(t), t.pos === e.currPos && e.updateCursor(), e.revealContent(t)); }, + adjustCaption: function(t){ var e; var n = this; var o = t || n.current; var i = o.opts.caption; var a = o.opts.preventCaptionOverlap; var s = n.$refs.caption; var r = !1; s.toggleClass('fancybox-caption--separate', a), a && i && i.length && (o.pos !== n.currPos ? (e = s.clone().appendTo(s.parent()), e.children().eq(0).empty().html(i), r = e.outerHeight(!0), e.empty().remove()) : n.$caption && (r = n.$caption.outerHeight(!0)), o.$slide.css('padding-bottom', r || '')); }, + adjustLayout: function(t){ var e; var n; var o; var i; var a = this; var s = t || a.current; s.isLoaded && !0 !== s.opts.disableLayoutFix && (s.$content.css('margin-bottom', ''), s.$content.outerHeight() > s.$slide.height() + 0.5 && (o = s.$slide[0].style['padding-bottom'], i = s.$slide.css('padding-bottom'), parseFloat(i) > 0 && (e = s.$slide[0].scrollHeight, s.$slide.css('padding-bottom', 0), Math.abs(e - s.$slide[0].scrollHeight) < 1 && (n = i), s.$slide.css('padding-bottom', o))), s.$content.css('margin-bottom', n)); }, + revealContent: function(t){ var e; var o; var i; var a; var s = this; var r = t.$slide; var c = !1; var l = !1; var d = s.isMoved(t); var u = t.isRevealed; return t.isRevealed = !0, e = t.opts[s.firstRun ? 'animationEffect' : 'transitionEffect'], i = t.opts[s.firstRun ? 'animationDuration' : 'transitionDuration'], i = parseInt(void 0 === t.forcedDuration ? i : t.forcedDuration, 10), !d && t.pos === s.currPos && i || (e = !1), e === 'zoom' && (t.pos === s.currPos && i && t.type === 'image' && !t.hasError && (l = s.getThumbPos(t)) ? c = s.getFitPos(t) : e = 'fade'), e === 'zoom' ? (s.isAnimating = !0, c.scaleX = c.width / l.width, c.scaleY = c.height / l.height, a = t.opts.zoomOpacity, a == 'auto' && (a = Math.abs(t.width / t.height - l.width / l.height) > 0.1), a && (l.opacity = 0.1, c.opacity = 1), n.fancybox.setTranslate(t.$content.removeClass('fancybox-is-hidden'), l), p(t.$content), void n.fancybox.animate(t.$content, c, i, function(){ s.isAnimating = !1, s.complete(); })) : (s.updateSlide(t), e ? (n.fancybox.stop(r), o = 'fancybox-slide--' + (t.pos >= s.prevPos ? 'next' : 'previous') + ' fancybox-animated fancybox-fx-' + e, r.addClass(o).removeClass('fancybox-slide--current'), t.$content.removeClass('fancybox-is-hidden'), p(r), t.type !== 'image' && t.$content.hide().show(0), void n.fancybox.animate(r, 'fancybox-slide--current', i, function(){ r.removeClass(o).css({ transform: '', opacity: '' }), t.pos === s.currPos && s.complete(); }, !0)) : (t.$content.removeClass('fancybox-is-hidden'), u || !d || t.type !== 'image' || t.hasError || t.$content.hide().fadeIn('fast'), void (t.pos === s.currPos && s.complete()))); }, + getThumbPos: function(t){ var e; var o; var i; var a; var s; var r = !1; var c = t.$thumb; return !(!c || !g(c[0])) && (e = n.fancybox.getTranslate(c), o = parseFloat(c.css('border-top-width') || 0), i = parseFloat(c.css('border-right-width') || 0), a = parseFloat(c.css('border-bottom-width') || 0), s = parseFloat(c.css('border-left-width') || 0), r = { top: e.top + o, left: e.left + s, width: e.width - i - s, height: e.height - o - a, scaleX: 1, scaleY: 1 }, e.width > 0 && e.height > 0 && r); }, + complete: function(){ var t; var e = this; var o = e.current; var i = {}; !e.isMoved() && o.isLoaded && (o.isComplete || (o.isComplete = !0, o.$slide.siblings().trigger('onReset'), e.preload('inline'), p(o.$slide), o.$slide.addClass('fancybox-slide--complete'), n.each(e.slides, function(t, o){ o.pos >= e.currPos - 1 && o.pos <= e.currPos + 1 ? i[o.pos] = o : o && (n.fancybox.stop(o.$slide), o.$slide.off().remove()); }), e.slides = i), e.isAnimating = !1, e.updateCursor(), e.trigger('afterShow'), o.opts.video.autoStart && o.$slide.find('video,audio').filter(':visible:first').trigger('play').one('ended', function(){ Document.exitFullscreen ? Document.exitFullscreen() : this.webkitExitFullscreen && this.webkitExitFullscreen(), e.next(); }), o.opts.autoFocus && o.contentType === 'html' && (t = o.$content.find('input[autofocus]:enabled:visible:first'), t.length ? t.trigger('focus') : e.focus(null, !0)), o.$slide.scrollTop(0).scrollLeft(0)); }, + preload: function(t){ var e; var n; var o = this; o.group.length < 2 || (n = o.slides[o.currPos + 1], e = o.slides[o.currPos - 1], e && e.type === t && o.loadSlide(e), n && n.type === t && o.loadSlide(n)); }, + focus: function(t, o){ var i; var a; var s = this; var r = ['a[href]', 'area[href]', 'input:not([disabled]):not([type="hidden"]):not([aria-hidden])', 'select:not([disabled]):not([aria-hidden])', 'textarea:not([disabled]):not([aria-hidden])', 'button:not([disabled]):not([aria-hidden])', 'iframe', 'object', 'embed', 'video', 'audio', '[contenteditable]', '[tabindex]:not([tabindex^="-"])'].join(','); s.isClosing || (i = !t && s.current && s.current.isComplete ? s.current.$slide.find('*:visible' + (o ? ':not(.fancybox-close-small)' : '')) : s.$refs.container.find('*:visible'), i = i.filter(r).filter(function(){ return n(this).css('visibility') !== 'hidden' && !n(this).hasClass('disabled'); }), i.length ? (a = i.index(e.activeElement), t && t.shiftKey ? (a < 0 || a == 0) && (t.preventDefault(), i.eq(i.length - 1).trigger('focus')) : (a < 0 || a == i.length - 1) && (t && t.preventDefault(), i.eq(0).trigger('focus'))) : s.$refs.container.trigger('focus')); }, + activate: function(){ var t = this; n('.fancybox-container').each(function(){ var e = n(this).data('FancyBox'); e && e.id !== t.id && !e.isClosing && (e.trigger('onDeactivate'), e.removeEvents(), e.isVisible = !1); }), t.isVisible = !0, (t.current || t.isIdle) && (t.update(), t.updateControls()), t.trigger('onActivate'), t.addEvents(); }, + close: function(t, e){ + var o; var i; var a; var s; var r; var c; var l; var u = this; var f = u.current; var h = function(){ u.cleanUp(t); }; return !u.isClosing && (u.isClosing = !0, !1 === u.trigger('beforeClose', t) ? (u.isClosing = !1, d(function(){ u.update(); }), !1) : (u.removeEvents(), a = f.$content, o = f.opts.animationEffect, i = n.isNumeric(e) ? e : o ? f.opts.animationDuration : 0, f.$slide.removeClass('fancybox-slide--complete fancybox-slide--next fancybox-slide--previous fancybox-animated'), !0 !== t ? n.fancybox.stop(f.$slide) : o = !1, f.$slide.siblings().trigger('onReset').remove(), i && u.$refs.container.removeClass('fancybox-is-open').addClass('fancybox-is-closing').css('transition-duration', i + 'ms'), u.hideLoading(f), u.hideControls(!0), u.updateCursor(), o !== 'zoom' || a && i && f.type === 'image' && !u.isMoved() && !f.hasError && (l = u.getThumbPos(f)) || (o = 'fade'), o === 'zoom' ? (n.fancybox.stop(a), s = n.fancybox.getTranslate(a), c = { top: s.top, left: s.left, scaleX: s.width / l.width, scaleY: s.height / l.height, width: l.width, height: l.height }, r = f.opts.zoomOpacity, + r == 'auto' && (r = Math.abs(f.width / f.height - l.width / l.height) > 0.1), r && (l.opacity = 0), n.fancybox.setTranslate(a, c), p(a), n.fancybox.animate(a, l, i, h), !0) : (o && i ? n.fancybox.animate(f.$slide.addClass('fancybox-slide--previous').removeClass('fancybox-slide--current'), 'fancybox-animated fancybox-fx-' + o, i, h) : !0 === t ? setTimeout(h, i) : h(), !0))); + }, + cleanUp: function(e){ var o; var i; var a; var s = this; var r = s.current.opts.$orig; s.current.$slide.trigger('onReset'), s.$refs.container.empty().remove(), s.trigger('afterClose', e), s.current.opts.backFocus && (r && r.length && r.is(':visible') || (r = s.$trigger), r && r.length && (i = t.scrollX, a = t.scrollY, r.trigger('focus'), n('html, body').scrollTop(a).scrollLeft(i))), s.current = null, o = n.fancybox.getInstance(), o ? o.activate() : (n('body').removeClass('fancybox-active compensate-for-scrollbar'), n('#fancybox-style-noscroll').remove()); }, + trigger: function(t, e){ var o; var i = Array.prototype.slice.call(arguments, 1); var a = this; var s = e && e.opts ? e : a.current; if (s ? i.unshift(s) : s = a, i.unshift(a), n.isFunction(s.opts[t]) && (o = s.opts[t].apply(s, i)), !1 === o) return o; t !== 'afterClose' && a.$refs ? a.$refs.container.trigger(t + '.fb', i) : r.trigger(t + '.fb', i); }, + updateControls: function(){ var t = this; var o = t.current; var i = o.index; var a = t.$refs.container; var s = t.$refs.caption; var r = o.opts.caption; o.$slide.trigger('refresh'), r && r.length ? (t.$caption = s, s.children().eq(0).html(r)) : t.$caption = null, t.hasHiddenControls || t.isIdle || t.showControls(), a.find('[data-fancybox-count]').html(t.group.length), a.find('[data-fancybox-index]').html(i + 1), a.find('[data-fancybox-prev]').prop('disabled', !o.opts.loop && i <= 0), a.find('[data-fancybox-next]').prop('disabled', !o.opts.loop && i >= t.group.length - 1), o.type === 'image' ? a.find('[data-fancybox-zoom]').show().end().find('[data-fancybox-download]').attr('href', o.opts.image.src || o.src).show() : o.opts.toolbar && a.find('[data-fancybox-download],[data-fancybox-zoom]').hide(), n(e.activeElement).is(':hidden,[disabled]') && t.$refs.container.trigger('focus'); }, + hideControls: function(t){ var e = this; var n = ['infobar', 'toolbar', 'nav']; !t && e.current.opts.preventCaptionOverlap || n.push('caption'), this.$refs.container.removeClass(n.map(function(t){ return 'fancybox-show-' + t; }).join(' ')), this.hasHiddenControls = !0; }, + showControls: function(){ var t = this; var e = t.current ? t.current.opts : t.opts; var n = t.$refs.container; t.hasHiddenControls = !1, t.idleSecondsCounter = 0, n.toggleClass('fancybox-show-toolbar', !(!e.toolbar || !e.buttons)).toggleClass('fancybox-show-infobar', !!(e.infobar && t.group.length > 1)).toggleClass('fancybox-show-caption', !!t.$caption).toggleClass('fancybox-show-nav', !!(e.arrows && t.group.length > 1)).toggleClass('fancybox-is-modal', !!e.modal); }, + toggleControls: function(){ this.hasHiddenControls ? this.showControls() : this.hideControls(); }, + }), n.fancybox = { version: '3.5.7', defaults: a, getInstance: function(t){ var e = n('.fancybox-container:not(".fancybox-is-closing"):last').data('FancyBox'); var o = Array.prototype.slice.call(arguments, 1); return e instanceof b && (n.type(t) === 'string' ? e[t].apply(e, o) : n.type(t) === 'function' && t.apply(e, o), e); }, open: function(t, e, n){ return new b(t, e, n); }, close: function(t){ var e = this.getInstance(); e && (e.close(), !0 === t && this.close(t)); }, destroy: function(){ this.close(!0), r.add('body').off('click.fb-start', '**'); }, isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent), use3d: (function(){ var n = e.createElement('div'); return t.getComputedStyle && t.getComputedStyle(n) && t.getComputedStyle(n).getPropertyValue('transform') && !(e.documentMode && e.documentMode < 11); }()), getTranslate: function(t){ var e; return !(!t || !t.length) && (e = t[0].getBoundingClientRect(), { top: e.top || 0, left: e.left || 0, width: e.width, height: e.height, opacity: parseFloat(t.css('opacity')) }); }, setTranslate: function(t, e){ var n = ''; var o = {}; if (t && e) return void 0 === e.left && void 0 === e.top || (n = (void 0 === e.left ? t.position().left : e.left) + 'px, ' + (void 0 === e.top ? t.position().top : e.top) + 'px', n = this.use3d ? 'translate3d(' + n + ', 0px)' : 'translate(' + n + ')'), void 0 !== e.scaleX && void 0 !== e.scaleY ? n += ' scale(' + e.scaleX + ', ' + e.scaleY + ')' : void 0 !== e.scaleX && (n += ' scaleX(' + e.scaleX + ')'), n.length && (o.transform = n), void 0 !== e.opacity && (o.opacity = e.opacity), void 0 !== e.width && (o.width = e.width), void 0 !== e.height && (o.height = e.height), t.css(o); }, animate: function(t, e, o, i, a){ var s; var r = this; n.isFunction(o) && (i = o, o = null), r.stop(t), s = r.getTranslate(t), t.on(f, function(c){ (!c || !c.originalEvent || t.is(c.originalEvent.target) && c.originalEvent.propertyName != 'z-index') && (r.stop(t), n.isNumeric(o) && t.css('transition-duration', ''), n.isPlainObject(e) ? void 0 !== e.scaleX && void 0 !== e.scaleY && r.setTranslate(t, { top: e.top, left: e.left, width: s.width * e.scaleX, height: s.height * e.scaleY, scaleX: 1, scaleY: 1 }) : !0 !== a && t.removeClass(e), n.isFunction(i) && i(c)); }), n.isNumeric(o) && t.css('transition-duration', o + 'ms'), n.isPlainObject(e) ? (void 0 !== e.scaleX && void 0 !== e.scaleY && (delete e.width, delete e.height, t.parent().hasClass('fancybox-slide--image') && t.parent().addClass('fancybox-is-scaling')), n.fancybox.setTranslate(t, e)) : t.addClass(e), t.data('timer', setTimeout(function(){ t.trigger(f); }, o + 33)); }, stop: function(t, e){ t && t.length && (clearTimeout(t.data('timer')), e && t.trigger(f), t.off(f).css('transition-duration', ''), t.parent().removeClass('fancybox-is-scaling')); } }, n.fn.fancybox = function(t){ var e; return t = t || {}, e = t.selector || !1, e ? n('body').off('click.fb-start', e).on('click.fb-start', e, { options: t }, i) : this.off('click.fb-start').on('click.fb-start', { items: this, options: t }, i), this; }, r.on('click.fb-start', '[data-fancybox]', i), r.on('click.fb-start', '[data-fancybox-trigger]', function(t){ n('[data-fancybox="' + n(this).attr('data-fancybox-trigger') + '"]').eq(n(this).attr('data-fancybox-index') || 0).trigger('click.fb-start', { $trigger: n(this) }); }), (function(){ var t = null; r.on('mousedown mouseup focus blur', '.fancybox-button', function(e){ switch (e.type){ case 'mousedown':t = n(this); break; case 'mouseup':t = null; break; case 'focusin':n('.fancybox-button').removeClass('fancybox-focus'), n(this).is(t) || n(this).is('[disabled]') || n(this).addClass('fancybox-focus'); break; case 'focusout':n('.fancybox-button').removeClass('fancybox-focus'); } }); }()); + } +}(window, document, jQuery)), (function(t){ 'use strict'; var e = { youtube: { matcher: /(youtube\.com|youtu\.be|youtube\-nocookie\.com)\/(watch\?(.*&)?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*))(.*)/i, params: { autoplay: 1, autohide: 1, fs: 1, rel: 0, hd: 1, wmode: 'transparent', enablejsapi: 1, html5: 1 }, paramPlace: 8, type: 'iframe', url: 'https://www.youtube-nocookie.com/embed/$4', thumb: 'https://img.youtube.com/vi/$4/hqdefault.jpg' }, vimeo: { matcher: /^.+vimeo.com\/(.*\/)?([\d]+)(.*)?/, params: { autoplay: 1, hd: 1, show_title: 1, show_byline: 1, show_portrait: 0, fullscreen: 1 }, paramPlace: 3, type: 'iframe', url: '//player.vimeo.com/video/$2' }, instagram: { matcher: /(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i, type: 'image', url: '//$1/p/$2/media/?size=l' }, gmap_place: { matcher: /(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(((maps\/(place\/(.*)\/)?\@(.*),(\d+.?\d+?)z))|(\?ll=))(.*)?/i, type: 'iframe', url: function(t){ return '//maps.google.' + t[2] + '/?ll=' + (t[9] ? t[9] + '&z=' + Math.floor(t[10]) + (t[12] ? t[12].replace(/^\//, '&') : '') : t[12] + '').replace(/\?/, '&') + '&output=' + (t[12] && t[12].indexOf('layer=c') > 0 ? 'svembed' : 'embed'); } }, gmap_search: { matcher: /(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(maps\/search\/)(.*)/i, type: 'iframe', url: function(t){ return '//maps.google.' + t[2] + '/maps?q=' + t[5].replace('query=', 'q=').replace('api=1', '') + '&output=embed'; } } }; var n = function(e, n, o){ if (e) return o = o || '', t.type(o) === 'object' && (o = t.param(o, !0)), t.each(n, function(t, n){ e = e.replace('$' + t, n || ''); }), o.length && (e += (e.indexOf('?') > 0 ? '&' : '?') + o), e; }; t(document).on('objectNeedsType.fb', function(o, i, a){ var s; var r; var c; var l; var d; var u; var f; var p = a.src || ''; var h = !1; s = t.extend(!0, {}, e, a.opts.media), t.each(s, function(e, o){ if (c = p.match(o.matcher)){ if (h = o.type, f = e, u = {}, o.paramPlace && c[o.paramPlace]){ d = c[o.paramPlace], d[0] == '?' && (d = d.substring(1)), d = d.split('&'); for (var i = 0; i < d.length; ++i){ var s = d[i].split('=', 2); s.length == 2 && (u[s[0]] = decodeURIComponent(s[1].replace(/\+/g, ' '))); } } return l = t.extend(!0, {}, o.params, a.opts[e], u), p = t.type(o.url) === 'function' ? o.url.call(this, c, l, a) : n(o.url, c, l), r = t.type(o.thumb) === 'function' ? o.thumb.call(this, c, l, a) : n(o.thumb, c), e === 'youtube' ? p = p.replace(/&t=((\d+)m)?(\d+)s/, function(t, e, n, o){ return '&start=' + ((n ? 60 * parseInt(n, 10) : 0) + parseInt(o, 10)); }) : e === 'vimeo' && (p = p.replace('&%23', '#')), !1; } }), h ? (a.opts.thumb || a.opts.$thumb && a.opts.$thumb.length || (a.opts.thumb = r), h === 'iframe' && (a.opts = t.extend(!0, a.opts, { iframe: { preload: !1, attr: { scrolling: 'no' } } })), t.extend(a, { type: h, src: p, origSrc: a.src, contentSource: f, contentType: h === 'image' ? 'image' : f == 'gmap_place' || f == 'gmap_search' ? 'map' : 'video' })) : p && (a.type = a.opts.defaultType); }); var o = { youtube: { src: 'https://www.youtube.com/iframe_api', class: 'YT', loading: !1, loaded: !1 }, vimeo: { src: 'https://player.vimeo.com/api/player.js', class: 'Vimeo', loading: !1, loaded: !1 }, load: function(t){ var e; var n = this; if (this[t].loaded) return void setTimeout(function(){ n.done(t); }); this[t].loading || (this[t].loading = !0, e = document.createElement('script'), e.type = 'text/javascript', e.src = this[t].src, t === 'youtube' ? window.onYouTubeIframeAPIReady = function(){ n[t].loaded = !0, n.done(t); } : e.onload = function(){ n[t].loaded = !0, n.done(t); }, document.body.appendChild(e)); }, done: function(e){ var n, o, i; e === 'youtube' && delete window.onYouTubeIframeAPIReady, (n = t.fancybox.getInstance()) && (o = n.current.$content.find('iframe'), e === 'youtube' && void 0 !== YT && YT ? i = new YT.Player(o.attr('id'), { events: { onStateChange: function(t){ t.data == 0 && n.next(); } } }) : e === 'vimeo' && void 0 !== Vimeo && Vimeo && (i = new Vimeo.Player(o), i.on('ended', function(){ n.next(); }))); } }; t(document).on({ 'afterShow.fb': function(t, e, n){ e.group.length > 1 && (n.contentSource === 'youtube' || n.contentSource === 'vimeo') && o.load(n.contentSource); } }); }(jQuery)), (function(t, e, n){ 'use strict'; var o = (function(){ return t.requestAnimationFrame || t.webkitRequestAnimationFrame || t.mozRequestAnimationFrame || t.oRequestAnimationFrame || function(e){ return t.setTimeout(e, 1e3 / 60); }; }()); var i = (function(){ return t.cancelAnimationFrame || t.webkitCancelAnimationFrame || t.mozCancelAnimationFrame || t.oCancelAnimationFrame || function(e){ t.clearTimeout(e); }; }()); var a = function(e){ var n = []; e = e.originalEvent || e || t.e, e = e.touches && e.touches.length ? e.touches : e.changedTouches && e.changedTouches.length ? e.changedTouches : [e]; for (var o in e)e[o].pageX ? n.push({ x: e[o].pageX, y: e[o].pageY }) : e[o].clientX && n.push({ x: e[o].clientX, y: e[o].clientY }); return n; }; var s = function(t, e, n){ return e && t ? n === 'x' ? t.x - e.x : n === 'y' ? t.y - e.y : Math.sqrt(Math.pow(t.x - e.x, 2) + Math.pow(t.y - e.y, 2)) : 0; }; var r = function(t){ if (t.is('a,area,button,[role="button"],input,label,select,summary,textarea,video,audio,iframe') || n.isFunction(t.get(0).onclick) || t.data('selectable')) return !0; for (var e = 0, o = t[0].attributes, i = o.length; e < i; e++) if (o[e].nodeName.substr(0, 14) === 'data-fancybox-') return !0; return !1; }; var c = function(e){ var n = t.getComputedStyle(e)['overflow-y']; var o = t.getComputedStyle(e)['overflow-x']; var i = (n === 'scroll' || n === 'auto') && e.scrollHeight > e.clientHeight; var a = (o === 'scroll' || o === 'auto') && e.scrollWidth > e.clientWidth; return i || a; }; var l = function(t){ for (var e = !1; ;){ if (e = c(t.get(0))) break; if (t = t.parent(), !t.length || t.hasClass('fancybox-stage') || t.is('body')) break; } return e; }; var d = function(t){ var e = this; e.instance = t, e.$bg = t.$refs.bg, e.$stage = t.$refs.stage, e.$container = t.$refs.container, e.destroy(), e.$container.on('touchstart.fb.touch mousedown.fb.touch', n.proxy(e, 'ontouchstart')); }; d.prototype.destroy = function(){ var t = this; t.$container.off('.fb.touch'), n(e).off('.fb.touch'), t.requestId && (i(t.requestId), t.requestId = null), t.tapped && (clearTimeout(t.tapped), t.tapped = null); }, d.prototype.ontouchstart = function(o){ var i = this; var c = n(o.target); var d = i.instance; var u = d.current; var f = u.$slide; var p = u.$content; var h = o.type == 'touchstart'; if (h && i.$container.off('mousedown.fb.touch'), (!o.originalEvent || o.originalEvent.button != 2) && f.length && c.length && !r(c) && !r(c.parent()) && (c.is('img') || !(o.originalEvent.clientX > c[0].clientWidth + c.offset().left))){ if (!u || d.isAnimating || u.$slide.hasClass('fancybox-animated')) return o.stopPropagation(), void o.preventDefault(); i.realPoints = i.startPoints = a(o), i.startPoints.length && (u.touch && o.stopPropagation(), i.startEvent = o, i.canTap = !0, i.$target = c, i.$content = p, i.opts = u.opts.touch, i.isPanning = !1, i.isSwiping = !1, i.isZooming = !1, i.isScrolling = !1, i.canPan = d.canPan(), i.startTime = (new Date()).getTime(), i.distanceX = i.distanceY = i.distance = 0, i.canvasWidth = Math.round(f[0].clientWidth), i.canvasHeight = Math.round(f[0].clientHeight), i.contentLastPos = null, i.contentStartPos = n.fancybox.getTranslate(i.$content) || { top: 0, left: 0 }, i.sliderStartPos = n.fancybox.getTranslate(f), i.stagePos = n.fancybox.getTranslate(d.$refs.stage), i.sliderStartPos.top -= i.stagePos.top, i.sliderStartPos.left -= i.stagePos.left, i.contentStartPos.top -= i.stagePos.top, i.contentStartPos.left -= i.stagePos.left, n(e).off('.fb.touch').on(h ? 'touchend.fb.touch touchcancel.fb.touch' : 'mouseup.fb.touch mouseleave.fb.touch', n.proxy(i, 'ontouchend')).on(h ? 'touchmove.fb.touch' : 'mousemove.fb.touch', n.proxy(i, 'ontouchmove')), n.fancybox.isMobile && e.addEventListener('scroll', i.onscroll, !0), ((i.opts || i.canPan) && (c.is(i.$stage) || i.$stage.find(c).length) || (c.is('.fancybox-image') && o.preventDefault(), n.fancybox.isMobile && c.parents('.fancybox-caption').length)) && (i.isScrollable = l(c) || l(c.parent()), n.fancybox.isMobile && i.isScrollable || o.preventDefault(), (i.startPoints.length === 1 || u.hasError) && (i.canPan ? (n.fancybox.stop(i.$content), i.isPanning = !0) : i.isSwiping = !0, i.$container.addClass('fancybox-is-grabbing')), i.startPoints.length === 2 && u.type === 'image' && (u.isLoaded || u.$ghost) && (i.canTap = !1, i.isSwiping = !1, i.isPanning = !1, i.isZooming = !0, n.fancybox.stop(i.$content), i.centerPointStartX = 0.5 * (i.startPoints[0].x + i.startPoints[1].x) - n(t).scrollLeft(), i.centerPointStartY = 0.5 * (i.startPoints[0].y + i.startPoints[1].y) - n(t).scrollTop(), i.percentageOfImageAtPinchPointX = (i.centerPointStartX - i.contentStartPos.left) / i.contentStartPos.width, i.percentageOfImageAtPinchPointY = (i.centerPointStartY - i.contentStartPos.top) / i.contentStartPos.height, i.startDistanceBetweenFingers = s(i.startPoints[0], i.startPoints[1])))); } }, d.prototype.onscroll = function(t){ var n = this; n.isScrolling = !0, e.removeEventListener('scroll', n.onscroll, !0); }, d.prototype.ontouchmove = function(t){ var e = this; return void 0 !== t.originalEvent.buttons && t.originalEvent.buttons === 0 ? void e.ontouchend(t) : e.isScrolling ? void (e.canTap = !1) : (e.newPoints = a(t), void ((e.opts || e.canPan) && e.newPoints.length && e.newPoints.length && (e.isSwiping && !0 === e.isSwiping || t.preventDefault(), e.distanceX = s(e.newPoints[0], e.startPoints[0], 'x'), e.distanceY = s(e.newPoints[0], e.startPoints[0], 'y'), e.distance = s(e.newPoints[0], e.startPoints[0]), e.distance > 0 && (e.isSwiping ? e.onSwipe(t) : e.isPanning ? e.onPan() : e.isZooming && e.onZoom())))); }, d.prototype.onSwipe = function(e){ var a; var s = this; var r = s.instance; var c = s.isSwiping; var l = s.sliderStartPos.left || 0; if (!0 !== c)c == 'x' && (s.distanceX > 0 && (s.instance.group.length < 2 || s.instance.current.index === 0 && !s.instance.current.opts.loop) ? l += Math.pow(s.distanceX, 0.8) : s.distanceX < 0 && (s.instance.group.length < 2 || s.instance.current.index === s.instance.group.length - 1 && !s.instance.current.opts.loop) ? l -= Math.pow(-s.distanceX, 0.8) : l += s.distanceX), s.sliderLastPos = { top: c == 'x' ? 0 : s.sliderStartPos.top + s.distanceY, left: l }, s.requestId && (i(s.requestId), s.requestId = null), s.requestId = o(function(){ s.sliderLastPos && (n.each(s.instance.slides, function(t, e){ var o = e.pos - s.instance.currPos; n.fancybox.setTranslate(e.$slide, { top: s.sliderLastPos.top, left: s.sliderLastPos.left + o * s.canvasWidth + o * e.opts.gutter }); }), s.$container.addClass('fancybox-is-sliding')); }); else if (Math.abs(s.distance) > 10){ if (s.canTap = !1, r.group.length < 2 && s.opts.vertical ? s.isSwiping = 'y' : r.isDragging || !1 === s.opts.vertical || s.opts.vertical === 'auto' && n(t).width() > 800 ? s.isSwiping = 'x' : (a = Math.abs(180 * Math.atan2(s.distanceY, s.distanceX) / Math.PI), s.isSwiping = a > 45 && a < 135 ? 'y' : 'x'), s.isSwiping === 'y' && n.fancybox.isMobile && s.isScrollable) return void (s.isScrolling = !0); r.isDragging = s.isSwiping, s.startPoints = s.newPoints, n.each(r.slides, function(t, e){ var o, i; n.fancybox.stop(e.$slide), o = n.fancybox.getTranslate(e.$slide), i = n.fancybox.getTranslate(r.$refs.stage), e.$slide.css({ transform: '', opacity: '', 'transition-duration': '' }).removeClass('fancybox-animated').removeClass(function(t, e){ return (e.match(/(^|\s)fancybox-fx-\S+/g) || []).join(' '); }), e.pos === r.current.pos && (s.sliderStartPos.top = o.top - i.top, s.sliderStartPos.left = o.left - i.left), n.fancybox.setTranslate(e.$slide, { top: o.top - i.top, left: o.left - i.left }); }), r.SlideShow && r.SlideShow.isActive && r.SlideShow.stop(); } }, d.prototype.onPan = function(){ var t = this; if (s(t.newPoints[0], t.realPoints[0]) < (n.fancybox.isMobile ? 10 : 5)) return void (t.startPoints = t.newPoints); t.canTap = !1, t.contentLastPos = t.limitMovement(), t.requestId && i(t.requestId), t.requestId = o(function(){ n.fancybox.setTranslate(t.$content, t.contentLastPos); }); }, d.prototype.limitMovement = function(){ var t; var e; var n; var o; var i; var a; var s = this; var r = s.canvasWidth; var c = s.canvasHeight; var l = s.distanceX; var d = s.distanceY; var u = s.contentStartPos; var f = u.left; var p = u.top; var h = u.width; var g = u.height; return i = h > r ? f + l : f, a = p + d, t = Math.max(0, 0.5 * r - 0.5 * h), e = Math.max(0, 0.5 * c - 0.5 * g), n = Math.min(r - h, 0.5 * r - 0.5 * h), o = Math.min(c - g, 0.5 * c - 0.5 * g), l > 0 && i > t && (i = t - 1 + Math.pow(-t + f + l, 0.8) || 0), l < 0 && i < n && (i = n + 1 - Math.pow(n - f - l, 0.8) || 0), d > 0 && a > e && (a = e - 1 + Math.pow(-e + p + d, 0.8) || 0), d < 0 && a < o && (a = o + 1 - Math.pow(o - p - d, 0.8) || 0), { top: a, left: i }; }, d.prototype.limitPosition = function(t, e, n, o){ var i = this; var a = i.canvasWidth; var s = i.canvasHeight; return n > a ? (t = t > 0 ? 0 : t, t = t < a - n ? a - n : t) : t = Math.max(0, a / 2 - n / 2), o > s ? (e = e > 0 ? 0 : e, e = e < s - o ? s - o : e) : e = Math.max(0, s / 2 - o / 2), { top: e, left: t }; }, d.prototype.onZoom = function(){ var e = this; var a = e.contentStartPos; var r = a.width; var c = a.height; var l = a.left; var d = a.top; var u = s(e.newPoints[0], e.newPoints[1]); var f = u / e.startDistanceBetweenFingers; var p = Math.floor(r * f); var h = Math.floor(c * f); var g = (r - p) * e.percentageOfImageAtPinchPointX; var b = (c - h) * e.percentageOfImageAtPinchPointY; var m = (e.newPoints[0].x + e.newPoints[1].x) / 2 - n(t).scrollLeft(); var v = (e.newPoints[0].y + e.newPoints[1].y) / 2 - n(t).scrollTop(); var y = m - e.centerPointStartX; var x = v - e.centerPointStartY; var w = l + (g + y); var $ = d + (b + x); var S = { top: $, left: w, scaleX: f, scaleY: f }; e.canTap = !1, e.newWidth = p, e.newHeight = h, e.contentLastPos = S, e.requestId && i(e.requestId), e.requestId = o(function(){ n.fancybox.setTranslate(e.$content, e.contentLastPos); }); }, d.prototype.ontouchend = function(t){ var o = this; var s = o.isSwiping; var r = o.isPanning; var c = o.isZooming; var l = o.isScrolling; if (o.endPoints = a(t), o.dMs = Math.max((new Date()).getTime() - o.startTime, 1), o.$container.removeClass('fancybox-is-grabbing'), n(e).off('.fb.touch'), e.removeEventListener('scroll', o.onscroll, !0), o.requestId && (i(o.requestId), o.requestId = null), o.isSwiping = !1, o.isPanning = !1, o.isZooming = !1, o.isScrolling = !1, o.instance.isDragging = !1, o.canTap) return o.onTap(t); o.speed = 100, o.velocityX = o.distanceX / o.dMs * 0.5, o.velocityY = o.distanceY / o.dMs * 0.5, r ? o.endPanning() : c ? o.endZooming() : o.endSwiping(s, l); }, d.prototype.endSwiping = function(t, e){ var o = this; var i = !1; var a = o.instance.group.length; var s = Math.abs(o.distanceX); var r = t == 'x' && a > 1 && (o.dMs > 130 && s > 10 || s > 50); o.sliderLastPos = null, t == 'y' && !e && Math.abs(o.distanceY) > 50 ? (n.fancybox.animate(o.instance.current.$slide, { top: o.sliderStartPos.top + o.distanceY + 150 * o.velocityY, opacity: 0 }, 200), i = o.instance.close(!0, 250)) : r && o.distanceX > 0 ? i = o.instance.previous(300) : r && o.distanceX < 0 && (i = o.instance.next(300)), !1 !== i || t != 'x' && t != 'y' || o.instance.centerSlide(200), o.$container.removeClass('fancybox-is-sliding'); }, d.prototype.endPanning = function(){ var t; var e; var o; var i = this; i.contentLastPos && (!1 === i.opts.momentum || i.dMs > 350 ? (t = i.contentLastPos.left, e = i.contentLastPos.top) : (t = i.contentLastPos.left + 500 * i.velocityX, e = i.contentLastPos.top + 500 * i.velocityY), o = i.limitPosition(t, e, i.contentStartPos.width, i.contentStartPos.height), o.width = i.contentStartPos.width, o.height = i.contentStartPos.height, n.fancybox.animate(i.$content, o, 366)); }, d.prototype.endZooming = function(){ var t; var e; var o; var i; var a = this; var s = a.instance.current; var r = a.newWidth; var c = a.newHeight; a.contentLastPos && (t = a.contentLastPos.left, e = a.contentLastPos.top, i = { top: e, left: t, width: r, height: c, scaleX: 1, scaleY: 1 }, n.fancybox.setTranslate(a.$content, i), r < a.canvasWidth && c < a.canvasHeight ? a.instance.scaleToFit(150) : r > s.width || c > s.height ? a.instance.scaleToActual(a.centerPointStartX, a.centerPointStartY, 150) : (o = a.limitPosition(t, e, r, c), n.fancybox.animate(a.$content, o, 150))); }, d.prototype.onTap = function(e){ var o; var i = this; var s = n(e.target); var r = i.instance; var c = r.current; var l = e && a(e) || i.startPoints; var d = l[0] ? l[0].x - n(t).scrollLeft() - i.stagePos.left : 0; var u = l[0] ? l[0].y - n(t).scrollTop() - i.stagePos.top : 0; var f = function(t){ var o = c.opts[t]; if (n.isFunction(o) && (o = o.apply(r, [c, e])), o) switch (o){ case 'close':r.close(i.startEvent); break; case 'toggleControls':r.toggleControls(); break; case 'next':r.next(); break; case 'nextOrClose':r.group.length > 1 ? r.next() : r.close(i.startEvent); break; case 'zoom':c.type == 'image' && (c.isLoaded || c.$ghost) && (r.canPan() ? r.scaleToFit() : r.isScaledDown() ? r.scaleToActual(d, u) : r.group.length < 2 && r.close(i.startEvent)); } }; if ((!e.originalEvent || e.originalEvent.button != 2) && (s.is('img') || !(d > s[0].clientWidth + s.offset().left))){ if (s.is('.fancybox-bg,.fancybox-inner,.fancybox-outer,.fancybox-container'))o = 'Outside'; else if (s.is('.fancybox-slide'))o = 'Slide'; else { if (!r.current.$content || !r.current.$content.find(s).addBack().filter(s).length) return; o = 'Content'; } if (i.tapped){ if (clearTimeout(i.tapped), i.tapped = null, Math.abs(d - i.tapX) > 50 || Math.abs(u - i.tapY) > 50) return this; f('dblclick' + o); } else i.tapX = d, i.tapY = u, c.opts['dblclick' + o] && c.opts['dblclick' + o] !== c.opts['click' + o] ? i.tapped = setTimeout(function(){ i.tapped = null, r.isAnimating || f('click' + o); }, 500) : f('click' + o); return this; } }, n(e).on('onActivate.fb', function(t, e){ e && !e.Guestures && (e.Guestures = new d(e)); }).on('beforeClose.fb', function(t, e){ e && e.Guestures && e.Guestures.destroy(); }); }(window, document, jQuery)), (function(t, e){ 'use strict'; e.extend(!0, e.fancybox.defaults, { btnTpl: { slideShow: '' }, slideShow: { autoStart: !1, speed: 3e3, progress: !0 } }); var n = function(t){ this.instance = t, this.init(); }; e.extend(n.prototype, { timer: null, isActive: !1, $button: null, init: function(){ var t = this; var n = t.instance; var o = n.group[n.currIndex].opts.slideShow; t.$button = n.$refs.toolbar.find('[data-fancybox-play]').on('click', function(){ t.toggle(); }), n.group.length < 2 || !o ? t.$button.hide() : o.progress && (t.$progress = e('
        ').appendTo(n.$refs.inner)); }, set: function(t){ var n = this; var o = n.instance; var i = o.current; i && (!0 === t || i.opts.loop || o.currIndex < o.group.length - 1) ? n.isActive && i.contentType !== 'video' && (n.$progress && e.fancybox.animate(n.$progress.show(), { scaleX: 1 }, i.opts.slideShow.speed), n.timer = setTimeout(function(){ o.current.opts.loop || o.current.index != o.group.length - 1 ? o.next() : o.jumpTo(0); }, i.opts.slideShow.speed)) : (n.stop(), o.idleSecondsCounter = 0, o.showControls()); }, clear: function(){ var t = this; clearTimeout(t.timer), t.timer = null, t.$progress && t.$progress.removeAttr('style').hide(); }, start: function(){ var t = this; var e = t.instance.current; e && (t.$button.attr('title', (e.opts.i18n[e.opts.lang] || e.opts.i18n.en).PLAY_STOP).removeClass('fancybox-button--play').addClass('fancybox-button--pause'), t.isActive = !0, e.isComplete && t.set(!0), t.instance.trigger('onSlideShowChange', !0)); }, stop: function(){ var t = this; var e = t.instance.current; t.clear(), t.$button.attr('title', (e.opts.i18n[e.opts.lang] || e.opts.i18n.en).PLAY_START).removeClass('fancybox-button--pause').addClass('fancybox-button--play'), t.isActive = !1, t.instance.trigger('onSlideShowChange', !1), t.$progress && t.$progress.removeAttr('style').hide(); }, toggle: function(){ var t = this; t.isActive ? t.stop() : t.start(); } }), e(t).on({ 'onInit.fb': function(t, e){ e && !e.SlideShow && (e.SlideShow = new n(e)); }, 'beforeShow.fb': function(t, e, n, o){ var i = e && e.SlideShow; o ? i && n.opts.slideShow.autoStart && i.start() : i && i.isActive && i.clear(); }, 'afterShow.fb': function(t, e, n){ var o = e && e.SlideShow; o && o.isActive && o.set(); }, 'afterKeydown.fb': function(n, o, i, a, s){ var r = o && o.SlideShow; !r || !i.opts.slideShow || s !== 80 && s !== 32 || e(t.activeElement).is('button,a,input') || (a.preventDefault(), r.toggle()); }, 'beforeClose.fb onDeactivate.fb': function(t, e){ var n = e && e.SlideShow; n && n.stop(); } }), e(t).on('visibilitychange', function(){ var n = e.fancybox.getInstance(); var o = n && n.SlideShow; o && o.isActive && (t.hidden ? o.clear() : o.set()); }); }(document, jQuery)), (function(t, e){ 'use strict'; var n = (function(){ for (var e = [['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'], ['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror'], ['webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror'], ['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'], ['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']], n = {}, o = 0; o < e.length; o++){ var i = e[o]; if (i && i[1] in t){ for (var a = 0; a < i.length; a++)n[e[0][a]] = i[a]; return n; } } return !1; }()); if (n){ var o = { request: function(e){ e = e || t.documentElement, e[n.requestFullscreen](e.ALLOW_KEYBOARD_INPUT); }, exit: function(){ t[n.exitFullscreen](); }, toggle: function(e){ e = e || t.documentElement, this.isFullscreen() ? this.exit() : this.request(e); }, isFullscreen: function(){ return Boolean(t[n.fullscreenElement]); }, enabled: function(){ return Boolean(t[n.fullscreenEnabled]); } }; e.extend(!0, e.fancybox.defaults, { btnTpl: { fullScreen: '' }, fullScreen: { autoStart: !1 } }), e(t).on(n.fullscreenchange, function(){ var t = o.isFullscreen(); var n = e.fancybox.getInstance(); n && (n.current && n.current.type === 'image' && n.isAnimating && (n.isAnimating = !1, n.update(!0, !0, 0), n.isComplete || n.complete()), n.trigger('onFullscreenChange', t), n.$refs.container.toggleClass('fancybox-is-fullscreen', t), n.$refs.toolbar.find('[data-fancybox-fullscreen]').toggleClass('fancybox-button--fsenter', !t).toggleClass('fancybox-button--fsexit', t)); }); }e(t).on({ 'onInit.fb': function(t, e){ var i; if (!n) return void e.$refs.toolbar.find('[data-fancybox-fullscreen]').remove(); e && e.group[e.currIndex].opts.fullScreen ? (i = e.$refs.container, i.on('click.fb-fullscreen', '[data-fancybox-fullscreen]', function(t){ t.stopPropagation(), t.preventDefault(), o.toggle(); }), e.opts.fullScreen && !0 === e.opts.fullScreen.autoStart && o.request(), e.FullScreen = o) : e && e.$refs.toolbar.find('[data-fancybox-fullscreen]').hide(); }, 'afterKeydown.fb': function(t, e, n, o, i){ e && e.FullScreen && i === 70 && (o.preventDefault(), e.FullScreen.toggle()); }, 'beforeClose.fb': function(t, e){ e && e.FullScreen && e.$refs.container.hasClass('fancybox-is-fullscreen') && o.exit(); } }); }(document, jQuery)), (function(t, e){ 'use strict'; var n = 'fancybox-thumbs'; e.fancybox.defaults = e.extend(!0, { btnTpl: { thumbs: '' }, thumbs: { autoStart: !1, hideOnClose: !0, parentEl: '.fancybox-container', axis: 'y' } }, e.fancybox.defaults); var o = function(t){ this.init(t); }; e.extend(o.prototype, { $button: null, $grid: null, $list: null, isVisible: !1, isActive: !1, init: function(t){ var e = this; var n = t.group; var o = 0; e.instance = t, e.opts = n[t.currIndex].opts.thumbs, t.Thumbs = e, e.$button = t.$refs.toolbar.find('[data-fancybox-thumbs]'); for (var i = 0, a = n.length; i < a && (n[i].thumb && o++, !(o > 1)); i++);o > 1 && e.opts ? (e.$button.removeAttr('style').on('click', function(){ e.toggle(); }), e.isActive = !0) : e.$button.hide(); }, create: function(){ var t; var o = this; var i = o.instance; var a = o.opts.parentEl; var s = []; o.$grid || (o.$grid = e('
        ').appendTo(i.$refs.container.find(a).addBack().filter(a)), o.$grid.on('click', 'a', function(){ i.jumpTo(e(this).attr('data-index')); })), o.$list || (o.$list = e('
        ').appendTo(o.$grid)), e.each(i.group, function(e, n){ t = n.thumb, t || n.type !== 'image' || (t = n.src), s.push(''); }), o.$list[0].innerHTML = s.join(''), o.opts.axis === 'x' && o.$list.width(parseInt(o.$grid.css('padding-right'), 10) + i.group.length * o.$list.children().eq(0).outerWidth(!0)); }, focus: function(t){ var e; var n; var o = this; var i = o.$list; var a = o.$grid; o.instance.current && (e = i.children().removeClass('fancybox-thumbs-active').filter('[data-index="' + o.instance.current.index + '"]').addClass('fancybox-thumbs-active'), n = e.position(), o.opts.axis === 'y' && (n.top < 0 || n.top > i.height() - e.outerHeight()) ? i.stop().animate({ scrollTop: i.scrollTop() + n.top }, t) : o.opts.axis === 'x' && (n.left < a.scrollLeft() || n.left > a.scrollLeft() + (a.width() - e.outerWidth())) && i.parent().stop().animate({ scrollLeft: n.left }, t)); }, update: function(){ var t = this; t.instance.$refs.container.toggleClass('fancybox-show-thumbs', this.isVisible), t.isVisible ? (t.$grid || t.create(), t.instance.trigger('onThumbsShow'), t.focus(0)) : t.$grid && t.instance.trigger('onThumbsHide'), t.instance.update(); }, hide: function(){ this.isVisible = !1, this.update(); }, show: function(){ this.isVisible = !0, this.update(); }, toggle: function(){ this.isVisible = !this.isVisible, this.update(); } }), e(t).on({ 'onInit.fb': function(t, e){ var n; e && !e.Thumbs && (n = new o(e), n.isActive && !0 === n.opts.autoStart && n.show()); }, 'beforeShow.fb': function(t, e, n, o){ var i = e && e.Thumbs; i && i.isVisible && i.focus(o ? 0 : 250); }, 'afterKeydown.fb': function(t, e, n, o, i){ var a = e && e.Thumbs; a && a.isActive && i === 71 && (o.preventDefault(), a.toggle()); }, 'beforeClose.fb': function(t, e){ var n = e && e.Thumbs; n && n.isVisible && !1 !== n.opts.hideOnClose && n.$grid.hide(); } }); }(document, jQuery)), (function(t, e){ + 'use strict'; function n(t){ var e = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''', '/': '/', '`': '`', '=': '=' }; return String(t).replace(/[&<>"'`=\/]/g, function(t){ return e[t]; }); }e.extend(!0, e.fancybox.defaults, { + btnTpl: { share: '' }, + share: { + url: function(t, e){ return !t.currentHash && e.type !== 'inline' && e.type !== 'html' && (e.origSrc || e.src) || window.location; }, + tpl: '', + }, + }), e(t).on('click', '[data-fancybox-share]', function(){ var t; var o; var i = e.fancybox.getInstance(); var a = i.current || null; a && (e.type(a.opts.share.url) === 'function' && (t = a.opts.share.url.apply(a, [i, a])), o = a.opts.share.tpl.replace(/\{\{media\}\}/g, a.type === 'image' ? encodeURIComponent(a.src) : '').replace(/\{\{url\}\}/g, encodeURIComponent(t)).replace(/\{\{url_raw\}\}/g, n(t)).replace(/\{\{descr\}\}/g, i.$caption ? encodeURIComponent(i.$caption.text()) : ''), e.fancybox.open({ src: i.translate(i, o), type: 'html', opts: { touch: !1, animationEffect: !1, afterLoad: function(t, e){ i.$refs.container.one('beforeClose.fb', function(){ t.close(null, 0); }), e.$content.find('.fancybox-share__button').click(function(){ return window.open(this.href, 'Share', 'width=550, height=450'), !1; }); }, mobile: { autoFocus: !1 } } })); }); +}(document, jQuery)), (function(t, e, n){ 'use strict'; function o(){ var e = t.location.hash.substr(1); var n = e.split('-'); var o = n.length > 1 && /^\+?\d+$/.test(n[n.length - 1]) ? parseInt(n.pop(-1), 10) || 1 : 1; var i = n.join('-'); return { hash: e, index: o < 1 ? 1 : o, gallery: i }; } function i(t){ t.gallery !== '' && n("[data-fancybox='" + n.escapeSelector(t.gallery) + "']").eq(t.index - 1).focus().trigger('click.fb-start'); } function a(t){ var e, n; return !!t && (e = t.current ? t.current.opts : t.opts, (n = e.hash || (e.$orig ? e.$orig.data('fancybox') || e.$orig.data('fancybox-trigger') : '')) !== '' && n); }n.escapeSelector || (n.escapeSelector = function(t){ return (t + '').replace(/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g, function(t, e){ return e ? t === '\0' ? '�' : t.slice(0, -1) + '\\' + t.charCodeAt(t.length - 1).toString(16) + ' ' : '\\' + t; }); }), n(function(){ !1 !== n.fancybox.defaults.hash && (n(e).on({ 'onInit.fb': function(t, e){ var n, i; !1 !== e.group[e.currIndex].opts.hash && (n = o(), (i = a(e)) && n.gallery && i == n.gallery && (e.currIndex = n.index - 1)); }, 'beforeShow.fb': function(n, o, i, s){ var r; i && !1 !== i.opts.hash && (r = a(o)) && (o.currentHash = r + (o.group.length > 1 ? '-' + (i.index + 1) : ''), t.location.hash !== '#' + o.currentHash && (s && !o.origHash && (o.origHash = t.location.hash), o.hashTimer && clearTimeout(o.hashTimer), o.hashTimer = setTimeout(function(){ 'replaceState' in t.history ? (t.history[s ? 'pushState' : 'replaceState']({}, e.title, t.location.pathname + t.location.search + '#' + o.currentHash), s && (o.hasCreatedHistory = !0)) : t.location.hash = o.currentHash, o.hashTimer = null; }, 300))); }, 'beforeClose.fb': function(n, o, i){ i && !1 !== i.opts.hash && (clearTimeout(o.hashTimer), o.currentHash && o.hasCreatedHistory ? t.history.back() : o.currentHash && ('replaceState' in t.history ? t.history.replaceState({}, e.title, t.location.pathname + t.location.search + (o.origHash || '')) : t.location.hash = o.origHash), o.currentHash = null); } }), n(t).on('hashchange.fb', function(){ var t = o(); var e = null; n.each(n('.fancybox-container').get().reverse(), function(t, o){ var i = n(o).data('FancyBox'); if (i && i.currentHash) return e = i, !1; }), e ? e.currentHash === t.gallery + '-' + t.index || t.index === 1 && e.currentHash == t.gallery || (e.currentHash = null, e.close()) : t.gallery !== '' && i(t); }), setTimeout(function(){ n.fancybox.getInstance() || i(o()); }, 50)); }); }(window, document, jQuery)), (function(t, e){ 'use strict'; var n = (new Date()).getTime(); e(t).on({ 'onInit.fb': function(t, e, o){ e.$refs.stage.on('mousewheel DOMMouseScroll wheel MozMousePixelScroll', function(t){ var o = e.current; var i = (new Date()).getTime(); e.group.length < 2 || !1 === o.opts.wheel || o.opts.wheel === 'auto' && o.type !== 'image' || (t.preventDefault(), t.stopPropagation(), o.$slide.hasClass('fancybox-animated') || (t = t.originalEvent || t, i - n < 250 || (n = i, e[(-t.deltaY || -t.deltaX || t.wheelDelta || -t.detail) < 0 ? 'next' : 'previous']()))); }); } }); }(document, jQuery)); diff --git a/src/assets/_project/lib/ext/generate-id.js b/src/assets/_project/lib/ext/generate-id.js index f91e34870..607c3fbd0 100644 --- a/src/assets/_project/lib/ext/generate-id.js +++ b/src/assets/_project/lib/ext/generate-id.js @@ -6,10 +6,9 @@ * Licensed under the MIT license. */ -(function( $ ) { +(function($) { 'use strict'; - /** * Assigns a unique value to `@id` unless hasAttribute( 'id' ) is true * @@ -17,32 +16,26 @@ * * @return jquery object (chaining supported) */ - $.fn.generateId = function( preferredId ) { - + $.fn.generateId = function(preferredId) { var i = 1; - if ( ! preferredId ) { + if (!preferredId) { preferredId = 'id'; } else { - preferredId = $.trim( preferredId.toLowerCase().replace( /[^a-z0-9_]+/g, ' ' )).replace( /\s+/g, '-' ); + preferredId = $.trim(preferredId.toLowerCase().replace(/[^a-z0-9_]+/g, ' ')).replace(/\s+/g, '-'); } return this.each(function() { - var id; - if ( ! this.getAttribute( 'id' )) { - + if (!this.getAttribute('id')) { id = preferredId; - while ( document.getElementById( id )) { - id = preferredId + String( i ); + while (document.getElementById(id)) { + id = preferredId + String(i); i++; } - this.setAttribute( 'id', id ); + this.setAttribute('id', id); } }); - }; - - -}( jQuery )); +}(jQuery)); diff --git a/src/assets/_project/lib/ext/jquery.browser.js b/src/assets/_project/lib/ext/jquery.browser.js index 8307daebf..e443f533f 100644 --- a/src/assets/_project/lib/ext/jquery.browser.js +++ b/src/assets/_project/lib/ext/jquery.browser.js @@ -28,146 +28,146 @@ factory(window.jQuery); } }(function(jQuery) { - "use strict"; + 'use strict'; - function uaMatch( ua ) { + function uaMatch(ua) { // If an UA is not provided, default to the current browser UA. - if ( ua === undefined ) { + if (ua === undefined) { ua = window.navigator.userAgent; } ua = ua.toLowerCase(); - var match = /(edge)\/([\w.]+)/.exec( ua ) || - /(opr)[\/]([\w.]+)/.exec( ua ) || - /(chrome)[ \/]([\w.]+)/.exec( ua ) || - /(iemobile)[\/]([\w.]+)/.exec( ua ) || - /(version)(applewebkit)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec( ua ) || - /(webkit)[ \/]([\w.]+).*(version)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec( ua ) || - /(webkit)[ \/]([\w.]+)/.exec( ua ) || - /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || - /(msie) ([\w.]+)/.exec( ua ) || - ua.indexOf("trident") >= 0 && /(rv)(?::| )([\w.]+)/.exec( ua ) || - ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || + var match = /(edge)\/([\w.]+)/.exec(ua) || + /(opr)[\/]([\w.]+)/.exec(ua) || + /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(iemobile)[\/]([\w.]+)/.exec(ua) || + /(version)(applewebkit)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+).*(version)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf('trident') >= 0 && /(rv)(?::| )([\w.]+)/.exec(ua) || + ua.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || []; - var platform_match = /(ipad)/.exec( ua ) || - /(ipod)/.exec( ua ) || - /(windows phone)/.exec( ua ) || - /(iphone)/.exec( ua ) || - /(kindle)/.exec( ua ) || - /(silk)/.exec( ua ) || - /(android)/.exec( ua ) || - /(win)/.exec( ua ) || - /(mac)/.exec( ua ) || - /(linux)/.exec( ua ) || - /(cros)/.exec( ua ) || - /(playbook)/.exec( ua ) || - /(bb)/.exec( ua ) || - /(blackberry)/.exec( ua ) || + var platform_match = /(ipad)/.exec(ua) || + /(ipod)/.exec(ua) || + /(windows phone)/.exec(ua) || + /(iphone)/.exec(ua) || + /(kindle)/.exec(ua) || + /(silk)/.exec(ua) || + /(android)/.exec(ua) || + /(win)/.exec(ua) || + /(mac)/.exec(ua) || + /(linux)/.exec(ua) || + /(cros)/.exec(ua) || + /(playbook)/.exec(ua) || + /(bb)/.exec(ua) || + /(blackberry)/.exec(ua) || []; - var browser = {}, - matched = { - browser: match[ 5 ] || match[ 3 ] || match[ 1 ] || "", - version: match[ 2 ] || match[ 4 ] || "0", - versionNumber: match[ 4 ] || match[ 2 ] || "0", - platform: platform_match[ 0 ] || "" - }; + var browser = {}; + var matched = { + browser: match[5] || match[3] || match[1] || '', + version: match[2] || match[4] || '0', + versionNumber: match[4] || match[2] || '0', + platform: platform_match[0] || '', + }; - if ( matched.browser ) { - browser[ matched.browser ] = true; + if (matched.browser) { + browser[matched.browser] = true; browser.version = matched.version; browser.versionNumber = parseInt(matched.versionNumber, 10); } - if ( matched.platform ) { - browser[ matched.platform ] = true; + if (matched.platform) { + browser[matched.platform] = true; } // These are all considered mobile platforms, meaning they run a mobile browser - if ( browser.android || browser.bb || browser.blackberry || browser.ipad || browser.iphone || - browser.ipod || browser.kindle || browser.playbook || browser.silk || browser[ "windows phone" ]) { + if (browser.android || browser.bb || browser.blackberry || browser.ipad || browser.iphone || + browser.ipod || browser.kindle || browser.playbook || browser.silk || browser['windows phone']) { browser.mobile = true; } // These are all considered desktop platforms, meaning they run a desktop browser - if ( browser.cros || browser.mac || browser.linux || browser.win ) { + if (browser.cros || browser.mac || browser.linux || browser.win) { browser.desktop = true; } // Chrome, Opera 15+ and Safari are webkit based browsers - if ( browser.chrome || browser.opr || browser.safari ) { + if (browser.chrome || browser.opr || browser.safari) { browser.webkit = true; } // IE11 has a new token so we will assign it msie to avoid breaking changes - if ( browser.rv || browser.iemobile) { - var ie = "msie"; + if (browser.rv || browser.iemobile) { + var ie = 'msie'; matched.browser = ie; browser[ie] = true; } // Edge is officially known as Microsoft Edge, so rewrite the key to match - if ( browser.edge ) { + if (browser.edge) { delete browser.edge; - var msedge = "msedge"; + var msedge = 'msedge'; matched.browser = msedge; browser[msedge] = true; } // Blackberry browsers are marked as Safari on BlackBerry - if ( browser.safari && browser.blackberry ) { - var blackberry = "blackberry"; + if (browser.safari && browser.blackberry) { + var blackberry = 'blackberry'; matched.browser = blackberry; browser[blackberry] = true; } // Playbook browsers are marked as Safari on Playbook - if ( browser.safari && browser.playbook ) { - var playbook = "playbook"; + if (browser.safari && browser.playbook) { + var playbook = 'playbook'; matched.browser = playbook; browser[playbook] = true; } // BB10 is a newer OS version of BlackBerry - if ( browser.bb ) { - var bb = "blackberry"; + if (browser.bb) { + var bb = 'blackberry'; matched.browser = bb; browser[bb] = true; } // Opera 15+ are identified as opr - if ( browser.opr ) { - var opera = "opera"; + if (browser.opr) { + var opera = 'opera'; matched.browser = opera; browser[opera] = true; } // Stock Android browsers are marked as Safari on Android. - if ( browser.safari && browser.android ) { - var android = "android"; + if (browser.safari && browser.android) { + var android = 'android'; matched.browser = android; browser[android] = true; } // Kindle browsers are marked as Safari on Kindle - if ( browser.safari && browser.kindle ) { - var kindle = "kindle"; + if (browser.safari && browser.kindle) { + var kindle = 'kindle'; matched.browser = kindle; browser[kindle] = true; } // Kindle Silk browsers are marked as Safari on Kindle - if ( browser.safari && browser.silk ) { - var silk = "silk"; + if (browser.safari && browser.silk) { + var silk = 'silk'; matched.browser = silk; browser[silk] = true; @@ -181,11 +181,11 @@ // Run the matching process, also assign the function to the returned object // for manual, jQuery-free use if desired - window.jQBrowser = uaMatch( window.navigator.userAgent ); + window.jQBrowser = uaMatch(window.navigator.userAgent); window.jQBrowser.uaMatch = uaMatch; // Only assign to jQuery.browser if jQuery is loaded - if ( jQuery ) { + if (jQuery) { jQuery.browser = window.jQBrowser; } diff --git a/src/assets/_project/lib/ext/jquery.history.js b/src/assets/_project/lib/ext/jquery.history.js index 9af975d6f..47aa65cf8 100644 --- a/src/assets/_project/lib/ext/jquery.history.js +++ b/src/assets/_project/lib/ext/jquery.history.js @@ -8,14 +8,12 @@ See http://www.JSON.org/js.html - This code should be minified before deployment. See http://javascript.crockford.com/jsmin.html USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO NOT CONTROL. - This file creates a global JSON object containing two methods: stringify and parse. @@ -89,7 +87,6 @@ text = JSON.stringify(['e', {pluribus: 'unum'}]); // text is '["e",{"pluribus":"unum"}]' - text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' @@ -99,7 +96,6 @@ }); // text is '["Date(---current time---)"]' - JSON.parse(text, reviver) This method parses a JSON text to produce an object or array. It can throw a SyntaxError exception. @@ -141,7 +137,6 @@ return value; }); - This is a reference implementation. You are free to copy, modify, or redistribute. */ @@ -155,334 +150,318 @@ test, toJSON, toString, valueOf */ - // Create a JSON object only if one does not already exist. We create the // methods in a closure to avoid creating global variables. if (typeof JSON !== 'object') { - JSON = {}; + JSON = {}; } (function () { - 'use strict'; - - function f(n) { - // Format integers to have at least two digits. - return n < 10 ? '0' + n : n; - } - - if (typeof Date.prototype.toJSON !== 'function') { + 'use strict'; - Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } - return isFinite(this.valueOf()) - ? this.getUTCFullYear() + '-' + + if (typeof Date.prototype.toJSON !== 'function') { + Date.prototype.toJSON = function (key) { + return isFinite(this.valueOf()) + ? this.getUTCFullYear() + '-' + f(this.getUTCMonth() + 1) + '-' + - f(this.getUTCDate()) + 'T' + - f(this.getUTCHours()) + ':' + - f(this.getUTCMinutes()) + ':' + - f(this.getUTCSeconds()) + 'Z' - : null; - }; - - String.prototype.toJSON = - Number.prototype.toJSON = + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' + : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = Boolean.prototype.toJSON = function (key) { - return this.valueOf(); + return this.valueOf(); }; - } - - var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - gap, - indent, - meta = { // table of character substitutions - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '"' : '\\"', - '\\': '\\\\' - }, - rep; - - - function quote(string) { - -// If the string contains no control characters, no quote characters, and no -// backslash characters, then we can safely slap some quotes around it. -// Otherwise we must also replace the offending characters with safe escape -// sequences. - - escapable.lastIndex = 0; - return escapable.test(string) ? '"' + string.replace(escapable, function (a) { - var c = meta[a]; - return typeof c === 'string' - ? c - : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }) + '"' : '"' + string + '"'; - } - - - function str(key, holder) { - -// Produce a string from holder[key]. - - var i, // The loop counter. - k, // The member key. - v, // The member value. - length, - mind = gap, - partial, - value = holder[key]; - -// If the value has a toJSON method, call it to obtain a replacement value. - - if (value && typeof value === 'object' && + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + var escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + var gap; + var indent; + var meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"': '\\"', + '\\': '\\\\', + }; + var rep; + + function quote(string) { + // If the string contains no control characters, no quote characters, and no + // backslash characters, then we can safely slap some quotes around it. + // Otherwise we must also replace the offending characters with safe escape + // sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' + ? c + : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + function str(key, holder) { + // Produce a string from holder[key]. + + var i; // The loop counter. + var k; // The member key. + var v; // The member value. + var length; + var mind = gap; + var partial; + var value = holder[key]; + + // If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && typeof value.toJSON === 'function') { - value = value.toJSON(key); - } + value = value.toJSON(key); + } -// If we were called with a replacer function, then call the replacer to -// obtain a replacement value. + // If we were called with a replacer function, then call the replacer to + // obtain a replacement value. - if (typeof rep === 'function') { - value = rep.call(holder, key, value); - } - -// What happens next depends on the value's type. + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } - switch (typeof value) { - case 'string': - return quote(value); + // What happens next depends on the value's type. - case 'number': + switch (typeof value) { + case 'string': + return quote(value); -// JSON numbers must be finite. Encode non-finite numbers as null. + case 'number': - return isFinite(value) ? String(value) : 'null'; + // JSON numbers must be finite. Encode non-finite numbers as null. - case 'boolean': - case 'null': + return isFinite(value) ? String(value) : 'null'; -// If the value is a boolean or null, convert it to a string. Note: -// typeof null does not produce 'null'. The case is included here in -// the remote chance that this gets fixed someday. + case 'boolean': + case 'null': - return String(value); + // If the value is a boolean or null, convert it to a string. Note: + // typeof null does not produce 'null'. The case is included here in + // the remote chance that this gets fixed someday. -// If the type is 'object', we might be dealing with an object or an array or -// null. + return String(value); - case 'object': + // If the type is 'object', we might be dealing with an object or an array or + // null. -// Due to a specification blunder in ECMAScript, typeof null is 'object', -// so watch out for that case. + case 'object': - if (!value) { - return 'null'; - } + // Due to a specification blunder in ECMAScript, typeof null is 'object', + // so watch out for that case. -// Make an array to hold the partial results of stringifying this object value. + if (!value) { + return 'null'; + } - gap += indent; - partial = []; + // Make an array to hold the partial results of stringifying this object value. -// Is the value an array? + gap += indent; + partial = []; - if (Object.prototype.toString.apply(value) === '[object Array]') { + // Is the value an array? -// The value is an array. Stringify every element. Use null as a placeholder -// for non-JSON values. + if (Object.prototype.toString.apply(value) === '[object Array]') { + // The value is an array. Stringify every element. Use null as a placeholder + // for non-JSON values. - length = value.length; - for (i = 0; i < length; i += 1) { - partial[i] = str(i, value) || 'null'; - } - -// Join all of the elements together, separated with commas, and wrap them in -// brackets. + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } - v = partial.length === 0 - ? '[]' - : gap - ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' - : '[' + partial.join(',') + ']'; - gap = mind; - return v; + // Join all of the elements together, separated with commas, and wrap them in + // brackets. + + v = partial.length === 0 + ? '[]' + : gap + ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' + : '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + + // If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === 'string') { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); } - -// If the replacer is an array, use it to select the members to be stringified. - - if (rep && typeof rep === 'object') { - length = rep.length; - for (i = 0; i < length; i += 1) { - if (typeof rep[i] === 'string') { - k = rep[i]; - v = str(k, value); - if (v) { - partial.push(quote(k) + (gap ? ': ' : ':') + v); - } - } - } - } else { - -// Otherwise, iterate through all of the keys in the object. - - for (k in value) { - if (Object.prototype.hasOwnProperty.call(value, k)) { - v = str(k, value); - if (v) { - partial.push(quote(k) + (gap ? ': ' : ':') + v); - } - } - } + } + } + } else { + // Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); } - -// Join all of the member texts together, separated with commas, -// and wrap them in braces. - - v = partial.length === 0 - ? '{}' - : gap - ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' - : '{' + partial.join(',') + '}'; - gap = mind; - return v; + } } + } + + // Join all of the member texts together, separated with commas, + // and wrap them in braces. + + v = partial.length === 0 + ? '{}' + : gap + ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' + : '{' + partial.join(',') + '}'; + gap = mind; + return v; } + } -// If the JSON object does not yet have a stringify method, give it one. + // If the JSON object does not yet have a stringify method, give it one. - if (typeof JSON.stringify !== 'function') { - JSON.stringify = function (value, replacer, space) { + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + // The stringify method takes a value and an optional replacer, and an optional + // space parameter, and returns a JSON text. The replacer can be a function + // that can replace values, or an array of strings that will select the keys. + // A default replacer method can be provided. Use of the space parameter can + // produce text that is more easily readable. -// The stringify method takes a value and an optional replacer, and an optional -// space parameter, and returns a JSON text. The replacer can be a function -// that can replace values, or an array of strings that will select the keys. -// A default replacer method can be provided. Use of the space parameter can -// produce text that is more easily readable. + var i; + gap = ''; + indent = ''; - var i; - gap = ''; - indent = ''; + // If the space parameter is a number, make an indent string containing that + // many spaces. -// If the space parameter is a number, make an indent string containing that -// many spaces. - - if (typeof space === 'number') { - for (i = 0; i < space; i += 1) { - indent += ' '; - } - -// If the space parameter is a string, it will be used as the indent string. + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } - } else if (typeof space === 'string') { - indent = space; - } + // If the space parameter is a string, it will be used as the indent string. + } else if (typeof space === 'string') { + indent = space; + } -// If there is a replacer, it must be a function or an array. -// Otherwise, throw an error. + // If there is a replacer, it must be a function or an array. + // Otherwise, throw an error. - rep = replacer; - if (replacer && typeof replacer !== 'function' && + rep = replacer; + if (replacer && typeof replacer !== 'function' && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) { - throw new Error('JSON.stringify'); + throw new Error('JSON.stringify'); + } + + // Make a fake root object containing our value under the key of ''. + // Return the result of stringifying the value. + + return str('', { '': value }); + }; + } + + // If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + // The parse method takes a text and an optional reviver function, and returns + // a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + // The walk method is used to recursively walk the resulting structure so + // that modifications can be made. + + var k; var v; var value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } } - -// Make a fake root object containing our value under the key of ''. -// Return the result of stringifying the value. - - return str('', {'': value}); - }; - } - - -// If the JSON object does not yet have a parse method, give it one. - - if (typeof JSON.parse !== 'function') { - JSON.parse = function (text, reviver) { - -// The parse method takes a text and an optional reviver function, and returns -// a JavaScript value if the text is a valid JSON text. - - var j; - - function walk(holder, key) { - -// The walk method is used to recursively walk the resulting structure so -// that modifications can be made. - - var k, v, value = holder[key]; - if (value && typeof value === 'object') { - for (k in value) { - if (Object.prototype.hasOwnProperty.call(value, k)) { - v = walk(value, k); - if (v !== undefined) { - value[k] = v; - } else { - delete value[k]; - } - } - } - } - return reviver.call(holder, key, value); - } - - -// Parsing happens in four stages. In the first stage, we replace certain -// Unicode characters with escape sequences. JavaScript handles many characters -// incorrectly, either silently deleting them, or treating them as line endings. - - text = String(text); - cx.lastIndex = 0; - if (cx.test(text)) { - text = text.replace(cx, function (a) { - return '\\u' + + } + } + return reviver.call(holder, key, value); + } + + // Parsing happens in four stages. In the first stage, we replace certain + // Unicode characters with escape sequences. JavaScript handles many characters + // incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }); - } - -// In the second stage, we run the text against regular expressions that look -// for non-JSON patterns. We are especially concerned with '()' and 'new' -// because they can cause invocation, and '=' because it can cause mutation. -// But just to be safe, we want to reject all unexpected forms. - -// We split the second stage into 4 regexp operations in order to work around -// crippling inefficiencies in IE's and Safari's regexp engines. First we -// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we -// replace all simple value tokens with ']' characters. Third, we delete all -// open brackets that follow a colon or comma or that begin the text. Finally, -// we look to see that the remaining characters are only whitespace or ']' or -// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. - - if (/^[\],:{}\s]*$/ - .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') - .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') - .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { - -// In the third stage we use the eval function to compile the text into a -// JavaScript structure. The '{' operator is subject to a syntactic ambiguity -// in JavaScript: it can begin a block or an object literal. We wrap the text -// in parens to eliminate the ambiguity. - - j = eval('(' + text + ')'); - -// In the optional fourth stage, we recursively walk the new structure, passing -// each name/value pair to a reviver function for possible transformation. - - return typeof reviver === 'function' - ? walk({'': j}, '') - : j; - } - -// If the text is not JSON parseable, then a SyntaxError is thrown. - - throw new SyntaxError('JSON.parse'); - }; - } + }); + } + + // In the second stage, we run the text against regular expressions that look + // for non-JSON patterns. We are especially concerned with '()' and 'new' + // because they can cause invocation, and '=' because it can cause mutation. + // But just to be safe, we want to reject all unexpected forms. + + // We split the second stage into 4 regexp operations in order to work around + // crippling inefficiencies in IE's and Safari's regexp engines. First we + // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we + // replace all simple value tokens with ']' characters. Third, we delete all + // open brackets that follow a colon or comma or that begin the text. Finally, + // we look to see that the remaining characters are only whitespace or ']' or + // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ + .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') + .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + // In the third stage we use the eval function to compile the text into a + // JavaScript structure. The '{' operator is subject to a syntactic ambiguity + // in JavaScript: it can begin a block or an object literal. We wrap the text + // in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + + // In the optional fourth stage, we recursively walk the new structure, passing + // each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' + ? walk({ '': j }, '') + : j; + } + + // If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } }());/** * History.js jQuery Adapter * @author Benjamin Arthur Lupton @@ -491,73 +470,72 @@ if (typeof JSON !== 'object') { */ // Closure -(function(window,undefined){ - "use strict"; - - // Localise Globals - var - History = window.History = window.History||{}, - jQuery = window.jQuery; - - // Check Existence - if ( typeof History.Adapter !== 'undefined' ) { - throw new Error('History.js Adapter has already been loaded...'); - } - - // Add the Adapter - History.Adapter = { - /** +(function(window, undefined){ + 'use strict'; + + // Localise Globals + var + History = window.History = window.History || {}; + var jQuery = window.jQuery; + + // Check Existence + if (typeof History.Adapter !== 'undefined') { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Add the Adapter + History.Adapter = { + /** * History.Adapter.bind(el,event,callback) * @param {Element|string} el * @param {string} event - custom and standard events * @param {function} callback * @return {void} */ - bind: function(el,event,callback){ - jQuery(el).bind(event,callback); - }, + bind: function(el, event, callback){ + jQuery(el).bind(event, callback); + }, - /** + /** * History.Adapter.trigger(el,event) * @param {Element|string} el * @param {string} event - custom and standard events * @param {Object=} extra - a object of extra event data (optional) * @return {void} */ - trigger: function(el,event,extra){ - jQuery(el).trigger(event,extra); - }, + trigger: function(el, event, extra){ + jQuery(el).trigger(event, extra); + }, - /** + /** * History.Adapter.extractEventData(key,event,extra) * @param {string} key - key for the event data to extract * @param {string} event - custom and standard events * @param {Object=} extra - a object of extra event data (optional) * @return {mixed} */ - extractEventData: function(key,event,extra){ - // jQuery Native then jQuery Custom - var result = (event && event.originalEvent && event.originalEvent[key]) || (extra && extra[key]) || undefined; + extractEventData: function(key, event, extra){ + // jQuery Native then jQuery Custom + var result = (event && event.originalEvent && event.originalEvent[key]) || (extra && extra[key]) || undefined; - // Return - return result; - }, + // Return + return result; + }, - /** + /** * History.Adapter.onDomLoad(callback) * @param {function} callback * @return {void} */ - onDomLoad: function(callback) { - jQuery(callback); - } - }; - - // Try and Initialise History - if ( typeof History.init !== 'undefined' ) { - History.init(); - } + onDomLoad: function(callback) { + jQuery(callback); + }, + }; + // Try and Initialise History + if (typeof History.init !== 'undefined') { + History.init(); + } })(window); /** @@ -568,235 +546,228 @@ if (typeof JSON !== 'object') { * @license New BSD License */ -(function(window,undefined){ - "use strict"; - - // ======================================================================== - // Initialise - - // Localise Globals - var - document = window.document, // Make sure we are using the correct document - setTimeout = window.setTimeout||setTimeout, - clearTimeout = window.clearTimeout||clearTimeout, - setInterval = window.setInterval||setInterval, - History = window.History = window.History||{}; // Public History Object - - // Check Existence - if ( typeof History.initHtml4 !== 'undefined' ) { - throw new Error('History.js HTML4 Support has already been loaded...'); - } - - - // ======================================================================== - // Initialise HTML4 Support - - // Initialise HTML4 Support - History.initHtml4 = function(){ - // Initialise - if ( typeof History.initHtml4.initialized !== 'undefined' ) { - // Already Loaded - return false; - } - else { - History.initHtml4.initialized = true; - } - +(function(window, undefined){ + 'use strict'; + + // ======================================================================== + // Initialise + + // Localise Globals + var + document = window.document; // Make sure we are using the correct document + var setTimeout = window.setTimeout || setTimeout; + var clearTimeout = window.clearTimeout || clearTimeout; + var setInterval = window.setInterval || setInterval; + var History = window.History = window.History || {}; // Public History Object + + // Check Existence + if (typeof History.initHtml4 !== 'undefined') { + throw new Error('History.js HTML4 Support has already been loaded...'); + } + + // ======================================================================== + // Initialise HTML4 Support + + // Initialise HTML4 Support + History.initHtml4 = function(){ + // Initialise + if (typeof History.initHtml4.initialized !== 'undefined') { + // Already Loaded + return false; + } else { + History.initHtml4.initialized = true; + } - // ==================================================================== - // Properties + // ==================================================================== + // Properties - /** + /** * History.enabled * Is History enabled? */ - History.enabled = true; - + History.enabled = true; - // ==================================================================== - // Hash Storage + // ==================================================================== + // Hash Storage - /** + /** * History.savedHashes * Store the hashes in an array */ - History.savedHashes = []; + History.savedHashes = []; - /** + /** * History.isLastHash(newHash) * Checks if the hash is the last hash * @param {string} newHash * @return {boolean} true */ - History.isLastHash = function(newHash){ - // Prepare - var oldHash = History.getHashByIndex(), - isLast; + History.isLastHash = function(newHash){ + // Prepare + var oldHash = History.getHashByIndex(); + var isLast; - // Check - isLast = newHash === oldHash; + // Check + isLast = newHash === oldHash; - // Return isLast - return isLast; - }; + // Return isLast + return isLast; + }; - /** + /** * History.isHashEqual(newHash, oldHash) * Checks to see if two hashes are functionally equal * @param {string} newHash * @param {string} oldHash * @return {boolean} true */ - History.isHashEqual = function(newHash, oldHash){ - newHash = encodeURIComponent(newHash).replace(/%25/g, "%"); - oldHash = encodeURIComponent(oldHash).replace(/%25/g, "%"); - return newHash === oldHash; - }; + History.isHashEqual = function(newHash, oldHash){ + newHash = encodeURIComponent(newHash).replace(/%25/g, '%'); + oldHash = encodeURIComponent(oldHash).replace(/%25/g, '%'); + return newHash === oldHash; + }; - /** + /** * History.saveHash(newHash) * Push a Hash * @param {string} newHash * @return {boolean} true */ - History.saveHash = function(newHash){ - // Check Hash - if ( History.isLastHash(newHash) ) { - return false; - } + History.saveHash = function(newHash){ + // Check Hash + if (History.isLastHash(newHash)) { + return false; + } - // Push the Hash - History.savedHashes.push(newHash); + // Push the Hash + History.savedHashes.push(newHash); - // Return true - return true; - }; + // Return true + return true; + }; - /** + /** * History.getHashByIndex() * Gets a hash by the index * @param {integer} index * @return {string} */ - History.getHashByIndex = function(index){ - // Prepare - var hash = null; - - // Handle - if ( typeof index === 'undefined' ) { - // Get the last inserted - hash = History.savedHashes[History.savedHashes.length-1]; - } - else if ( index < 0 ) { - // Get from the end - hash = History.savedHashes[History.savedHashes.length+index]; - } - else { - // Get from the beginning - hash = History.savedHashes[index]; - } - - // Return hash - return hash; - }; - - - // ==================================================================== - // Discarded States - - /** + History.getHashByIndex = function(index){ + // Prepare + var hash = null; + + // Handle + if (typeof index === 'undefined') { + // Get the last inserted + hash = History.savedHashes[History.savedHashes.length - 1]; + } else if (index < 0) { + // Get from the end + hash = History.savedHashes[History.savedHashes.length + index]; + } else { + // Get from the beginning + hash = History.savedHashes[index]; + } + + // Return hash + return hash; + }; + + // ==================================================================== + // Discarded States + + /** * History.discardedHashes * A hashed array of discarded hashes */ - History.discardedHashes = {}; + History.discardedHashes = {}; - /** + /** * History.discardedStates * A hashed array of discarded states */ - History.discardedStates = {}; + History.discardedStates = {}; - /** + /** * History.discardState(State) * Discards the state by ignoring it through History * @param {object} State * @return {true} */ - History.discardState = function(discardedState,forwardState,backState){ - //History.debug('History.discardState', arguments); - // Prepare - var discardedStateHash = History.getHashByState(discardedState), - discardObject; + History.discardState = function(discardedState, forwardState, backState){ + //History.debug('History.discardState', arguments); + // Prepare + var discardedStateHash = History.getHashByState(discardedState); + var discardObject; - // Create Discard Object - discardObject = { - 'discardedState': discardedState, - 'backState': backState, - 'forwardState': forwardState - }; + // Create Discard Object + discardObject = { + discardedState: discardedState, + backState: backState, + forwardState: forwardState, + }; - // Add to DiscardedStates - History.discardedStates[discardedStateHash] = discardObject; + // Add to DiscardedStates + History.discardedStates[discardedStateHash] = discardObject; - // Return true - return true; - }; + // Return true + return true; + }; - /** + /** * History.discardHash(hash) * Discards the hash by ignoring it through History * @param {string} hash * @return {true} */ - History.discardHash = function(discardedHash,forwardState,backState){ - //History.debug('History.discardState', arguments); - // Create Discard Object - var discardObject = { - 'discardedHash': discardedHash, - 'backState': backState, - 'forwardState': forwardState - }; + History.discardHash = function(discardedHash, forwardState, backState){ + //History.debug('History.discardState', arguments); + // Create Discard Object + var discardObject = { + discardedHash: discardedHash, + backState: backState, + forwardState: forwardState, + }; - // Add to discardedHash - History.discardedHashes[discardedHash] = discardObject; + // Add to discardedHash + History.discardedHashes[discardedHash] = discardObject; - // Return true - return true; - }; + // Return true + return true; + }; - /** + /** * History.discardedState(State) * Checks to see if the state is discarded * @param {object} State * @return {bool} */ - History.discardedState = function(State){ - // Prepare - var StateHash = History.getHashByState(State), - discarded; + History.discardedState = function(State){ + // Prepare + var StateHash = History.getHashByState(State); + var discarded; - // Check - discarded = History.discardedStates[StateHash]||false; + // Check + discarded = History.discardedStates[StateHash] || false; - // Return true - return discarded; - }; + // Return true + return discarded; + }; - /** + /** * History.discardedHash(hash) * Checks to see if the state is discarded * @param {string} State * @return {bool} */ - History.discardedHash = function(hash){ - // Check - var discarded = History.discardedHashes[hash]||false; + History.discardedHash = function(hash){ + // Check + var discarded = History.discardedHashes[hash] || false; - // Return true - return discarded; - }; + // Return true + return discarded; + }; - /** + /** * History.recycleState(State) * Allows a discarded state to be used again * @param {object} data @@ -804,260 +775,255 @@ if (typeof JSON !== 'object') { * @param {string} url * @return {true} */ - History.recycleState = function(State){ - //History.debug('History.recycleState', arguments); - // Prepare - var StateHash = History.getHashByState(State); - - // Remove from DiscardedStates - if ( History.discardedState(State) ) { - delete History.discardedStates[StateHash]; - } + History.recycleState = function(State){ + //History.debug('History.recycleState', arguments); + // Prepare + var StateHash = History.getHashByState(State); - // Return true - return true; - }; + // Remove from DiscardedStates + if (History.discardedState(State)) { + delete History.discardedStates[StateHash]; + } + // Return true + return true; + }; - // ==================================================================== - // HTML4 HashChange Support + // ==================================================================== + // HTML4 HashChange Support - if ( History.emulated.hashChange ) { - /* + if (History.emulated.hashChange) { + /* * We must emulate the HTML4 HashChange Support by manually checking for hash changes */ - /** + /** * History.hashChangeInit() * Init the HashChange Emulation */ - History.hashChangeInit = function(){ - // Define our Checker Function - History.checkerFunction = null; - - // Define some variables that will help in our checker function - var lastDocumentHash = '', - iframeId, iframe, - lastIframeHash, checkerRunning, - startedWithHash = Boolean(History.getHash()); - - // Handle depending on the browser - if ( History.isInternetExplorer() ) { - // IE6 and IE7 - // We need to use an iframe to emulate the back and forward buttons - - // Create iFrame - iframeId = 'historyjs-iframe'; - iframe = document.createElement('iframe'); - - // Adjust iFarme - // IE 6 requires iframe to have a src on HTTPS pages, otherwise it will throw a - // "This page contains both secure and nonsecure items" warning. - iframe.setAttribute('id', iframeId); - iframe.setAttribute('src', '#'); - iframe.style.display = 'none'; - - // Append iFrame - document.body.appendChild(iframe); - - // Create initial history entry - iframe.contentWindow.document.open(); - iframe.contentWindow.document.close(); - - // Define some variables that will help in our checker function - lastIframeHash = ''; - checkerRunning = false; - - // Define the checker function - History.checkerFunction = function(){ - // Check Running - if ( checkerRunning ) { - return false; - } - - // Update Running - checkerRunning = true; - - // Fetch - var - documentHash = History.getHash(), - iframeHash = History.getHash(iframe.contentWindow.document); - - // The Document Hash has changed (application caused) - if ( documentHash !== lastDocumentHash ) { - // Equalise - lastDocumentHash = documentHash; - - // Create a history entry in the iframe - if ( iframeHash !== documentHash ) { - //History.debug('hashchange.checker: iframe hash change', 'documentHash (new):', documentHash, 'iframeHash (old):', iframeHash); - - // Equalise - lastIframeHash = iframeHash = documentHash; - - // Create History Entry - iframe.contentWindow.document.open(); - iframe.contentWindow.document.close(); - - // Update the iframe's hash - iframe.contentWindow.document.location.hash = History.escapeHash(documentHash); - } - - // Trigger Hashchange Event - History.Adapter.trigger(window,'hashchange'); - } - - // The iFrame Hash has changed (back button caused) - else if ( iframeHash !== lastIframeHash ) { - //History.debug('hashchange.checker: iframe hash out of sync', 'iframeHash (new):', iframeHash, 'documentHash (old):', documentHash); - - // Equalise - lastIframeHash = iframeHash; - - // If there is no iframe hash that means we're at the original - // iframe state. - // And if there was a hash on the original request, the original - // iframe state was replaced instantly, so skip this state and take - // the user back to where they came from. - if (startedWithHash && iframeHash === '') { - History.back(); - } - else { - // Update the Hash - History.setHash(iframeHash,false); - } - } - - // Reset Running - checkerRunning = false; - - // Return true - return true; - }; - } - else { - // We are not IE - // Firefox 1 or 2, Opera - - // Define the checker function - History.checkerFunction = function(){ - // Prepare - var documentHash = History.getHash()||''; - - // The Document Hash has changed (application caused) - if ( documentHash !== lastDocumentHash ) { - // Equalise - lastDocumentHash = documentHash; - - // Trigger Hashchange Event - History.Adapter.trigger(window,'hashchange'); - } - - // Return true - return true; - }; - } - - // Apply the checker function - History.intervalList.push(setInterval(History.checkerFunction, History.options.hashChangeInterval)); - - // Done - return true; - }; // History.hashChangeInit - - // Bind hashChangeInit - History.Adapter.onDomLoad(History.hashChangeInit); - - } // History.emulated.hashChange - - - // ==================================================================== - // HTML5 State Support - - // Non-Native pushState Implementation - if ( History.emulated.pushState ) { - /* + History.hashChangeInit = function(){ + // Define our Checker Function + History.checkerFunction = null; + + // Define some variables that will help in our checker function + var lastDocumentHash = ''; + var iframeId; var iframe; + var lastIframeHash; var checkerRunning; + var startedWithHash = Boolean(History.getHash()); + + // Handle depending on the browser + if (History.isInternetExplorer()) { + // IE6 and IE7 + // We need to use an iframe to emulate the back and forward buttons + + // Create iFrame + iframeId = 'historyjs-iframe'; + iframe = document.createElement('iframe'); + + // Adjust iFarme + // IE 6 requires iframe to have a src on HTTPS pages, otherwise it will throw a + // "This page contains both secure and nonsecure items" warning. + iframe.setAttribute('id', iframeId); + iframe.setAttribute('src', '#'); + iframe.style.display = 'none'; + + // Append iFrame + document.body.appendChild(iframe); + + // Create initial history entry + iframe.contentWindow.document.open(); + iframe.contentWindow.document.close(); + + // Define some variables that will help in our checker function + lastIframeHash = ''; + checkerRunning = false; + + // Define the checker function + History.checkerFunction = function(){ + // Check Running + if (checkerRunning) { + return false; + } + + // Update Running + checkerRunning = true; + + // Fetch + var + documentHash = History.getHash(); + var iframeHash = History.getHash(iframe.contentWindow.document); + + // The Document Hash has changed (application caused) + if (documentHash !== lastDocumentHash) { + // Equalise + lastDocumentHash = documentHash; + + // Create a history entry in the iframe + if (iframeHash !== documentHash) { + //History.debug('hashchange.checker: iframe hash change', 'documentHash (new):', documentHash, 'iframeHash (old):', iframeHash); + + // Equalise + lastIframeHash = iframeHash = documentHash; + + // Create History Entry + iframe.contentWindow.document.open(); + iframe.contentWindow.document.close(); + + // Update the iframe's hash + iframe.contentWindow.document.location.hash = History.escapeHash(documentHash); + } + + // Trigger Hashchange Event + History.Adapter.trigger(window, 'hashchange'); + } + + // The iFrame Hash has changed (back button caused) + else if (iframeHash !== lastIframeHash) { + //History.debug('hashchange.checker: iframe hash out of sync', 'iframeHash (new):', iframeHash, 'documentHash (old):', documentHash); + + // Equalise + lastIframeHash = iframeHash; + + // If there is no iframe hash that means we're at the original + // iframe state. + // And if there was a hash on the original request, the original + // iframe state was replaced instantly, so skip this state and take + // the user back to where they came from. + if (startedWithHash && iframeHash === '') { + History.back(); + } else { + // Update the Hash + History.setHash(iframeHash, false); + } + } + + // Reset Running + checkerRunning = false; + + // Return true + return true; + }; + } else { + // We are not IE + // Firefox 1 or 2, Opera + + // Define the checker function + History.checkerFunction = function(){ + // Prepare + var documentHash = History.getHash() || ''; + + // The Document Hash has changed (application caused) + if (documentHash !== lastDocumentHash) { + // Equalise + lastDocumentHash = documentHash; + + // Trigger Hashchange Event + History.Adapter.trigger(window, 'hashchange'); + } + + // Return true + return true; + }; + } + + // Apply the checker function + History.intervalList.push(setInterval(History.checkerFunction, History.options.hashChangeInterval)); + + // Done + return true; + }; // History.hashChangeInit + + // Bind hashChangeInit + History.Adapter.onDomLoad(History.hashChangeInit); + } // History.emulated.hashChange + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if (History.emulated.pushState) { + /* * We must emulate the HTML5 State Management by using HTML4 HashChange */ - /** + /** * History.onHashChange(event) * Trigger HTML5's window.onpopstate via HTML4 HashChange Support */ - History.onHashChange = function(event){ - //History.debug('History.onHashChange', arguments); - - // Prepare - var currentUrl = ((event && event.newURL) || History.getLocationHref()), - currentHash = History.getHashByUrl(currentUrl), - currentState = null, - currentStateHash = null, - currentStateHashExits = null, - discardObject; - - // Check if we are the same state - if ( History.isLastHash(currentHash) ) { - // There has been no change (just the page's hash has finally propagated) - //History.debug('History.onHashChange: no change'); - History.busy(false); - return false; - } - - // Reset the double check - History.doubleCheckComplete(); - - // Store our location for use in detecting back/forward direction - History.saveHash(currentHash); - - // Expand Hash - if ( currentHash && History.isTraditionalAnchor(currentHash) ) { - //History.debug('History.onHashChange: traditional anchor', currentHash); - // Traditional Anchor Hash - History.Adapter.trigger(window,'anchorchange'); - History.busy(false); - return false; - } - - // Create State - currentState = History.extractState(History.getFullUrl(currentHash||History.getLocationHref()),true); - - // Check if we are the same state - if ( History.isLastSavedState(currentState) ) { - //History.debug('History.onHashChange: no change'); - // There has been no change (just the page's hash has finally propagated) - History.busy(false); - return false; - } - - // Create the state Hash - currentStateHash = History.getHashByState(currentState); - - // Check if we are DiscardedState - discardObject = History.discardedState(currentState); - if ( discardObject ) { - // Ignore this state as it has been discarded and go back to the state before it - if ( History.getHashByIndex(-2) === History.getHashByState(discardObject.forwardState) ) { - // We are going backwards - //History.debug('History.onHashChange: go backwards'); - History.back(false); - } else { - // We are going forwards - //History.debug('History.onHashChange: go forwards'); - History.forward(false); - } - return false; - } - - // Push the new HTML5 State - //History.debug('History.onHashChange: success hashchange'); - History.pushState(currentState.data,currentState.title,encodeURI(currentState.url),false); - - // End onHashChange closure - return true; - }; - History.Adapter.bind(window,'hashchange',History.onHashChange); - - /** + History.onHashChange = function(event){ + //History.debug('History.onHashChange', arguments); + + // Prepare + var currentUrl = ((event && event.newURL) || History.getLocationHref()); + var currentHash = History.getHashByUrl(currentUrl); + var currentState = null; + var currentStateHash = null; + var currentStateHashExits = null; + var discardObject; + + // Check if we are the same state + if (History.isLastHash(currentHash)) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onHashChange: no change'); + History.busy(false); + return false; + } + + // Reset the double check + History.doubleCheckComplete(); + + // Store our location for use in detecting back/forward direction + History.saveHash(currentHash); + + // Expand Hash + if (currentHash && History.isTraditionalAnchor(currentHash)) { + //History.debug('History.onHashChange: traditional anchor', currentHash); + // Traditional Anchor Hash + History.Adapter.trigger(window, 'anchorchange'); + History.busy(false); + return false; + } + + // Create State + currentState = History.extractState(History.getFullUrl(currentHash || History.getLocationHref()), true); + + // Check if we are the same state + if (History.isLastSavedState(currentState)) { + //History.debug('History.onHashChange: no change'); + // There has been no change (just the page's hash has finally propagated) + History.busy(false); + return false; + } + + // Create the state Hash + currentStateHash = History.getHashByState(currentState); + + // Check if we are DiscardedState + discardObject = History.discardedState(currentState); + if (discardObject) { + // Ignore this state as it has been discarded and go back to the state before it + if (History.getHashByIndex(-2) === History.getHashByState(discardObject.forwardState)) { + // We are going backwards + //History.debug('History.onHashChange: go backwards'); + History.back(false); + } else { + // We are going forwards + //History.debug('History.onHashChange: go forwards'); + History.forward(false); + } + return false; + } + + // Push the new HTML5 State + //History.debug('History.onHashChange: success hashchange'); + History.pushState(currentState.data, currentState.title, encodeURI(currentState.url), false); + + // End onHashChange closure + return true; + }; + History.Adapter.bind(window, 'hashchange', History.onHashChange); + + /** * History.pushState(data,title,url) * Add a new State to the history object, become it, and trigger onpopstate * We have to trigger for HTML4 compatibility @@ -1066,79 +1032,78 @@ if (typeof JSON !== 'object') { * @param {string} url * @return {true} */ - History.pushState = function(data,title,url,queue){ - //History.debug('History.pushState: called', arguments); - - // We assume that the URL passed in is URI-encoded, but this makes - // sure that it's fully URI encoded; any '%'s that are encoded are - // converted back into '%'s - url = encodeURI(url).replace(/%25/g, "%"); - - // Check the State - if ( History.getHashByUrl(url) ) { - throw new Error('History.js does not support states with fragment-identifiers (hashes/anchors).'); - } - - // Handle Queueing - if ( queue !== false && History.busy() ) { - // Wait + Push to Queue - //History.debug('History.pushState: we must wait', arguments); - History.pushQueue({ - scope: History, - callback: History.pushState, - args: arguments, - queue: queue - }); - return false; - } - - // Make Busy - History.busy(true); - - // Fetch the State Object - var newState = History.createStateObject(data,title,url), - newStateHash = History.getHashByState(newState), - oldState = History.getState(false), - oldStateHash = History.getHashByState(oldState), - html4Hash = History.getHash(), - wasExpected = History.expectedStateId == newState.id; - - // Store the newState - History.storeState(newState); - History.expectedStateId = newState.id; - - // Recycle the State - History.recycleState(newState); - - // Force update of the title - History.setTitle(newState); - - // Check if we are the same State - if ( newStateHash === oldStateHash ) { - //History.debug('History.pushState: no change', newStateHash); - History.busy(false); - return false; - } - - // Update HTML5 State - History.saveState(newState); - - // Fire HTML5 Event - if(!wasExpected) - History.Adapter.trigger(window,'statechange'); - - // Update HTML4 Hash - if ( !History.isHashEqual(newStateHash, html4Hash) && !History.isHashEqual(newStateHash, History.getShortUrl(History.getLocationHref())) ) { - History.setHash(newStateHash,false); - } - - History.busy(false); - - // End pushState closure - return true; - }; - - /** + History.pushState = function(data, title, url, queue){ + //History.debug('History.pushState: called', arguments); + + // We assume that the URL passed in is URI-encoded, but this makes + // sure that it's fully URI encoded; any '%'s that are encoded are + // converted back into '%'s + url = encodeURI(url).replace(/%25/g, '%'); + + // Check the State + if (History.getHashByUrl(url)) { + throw new Error('History.js does not support states with fragment-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if (queue !== false && History.busy()) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue, + }); + return false; + } + + // Make Busy + History.busy(true); + + // Fetch the State Object + var newState = History.createStateObject(data, title, url); + var newStateHash = History.getHashByState(newState); + var oldState = History.getState(false); + var oldStateHash = History.getHashByState(oldState); + var html4Hash = History.getHash(); + var wasExpected = History.expectedStateId == newState.id; + + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Recycle the State + History.recycleState(newState); + + // Force update of the title + History.setTitle(newState); + + // Check if we are the same State + if (newStateHash === oldStateHash) { + //History.debug('History.pushState: no change', newStateHash); + History.busy(false); + return false; + } + + // Update HTML5 State + History.saveState(newState); + + // Fire HTML5 Event + if (!wasExpected) { History.Adapter.trigger(window, 'statechange'); } + + // Update HTML4 Hash + if (!History.isHashEqual(newStateHash, html4Hash) && !History.isHashEqual(newStateHash, History.getShortUrl(History.getLocationHref()))) { + History.setHash(newStateHash, false); + } + + History.busy(false); + + // End pushState closure + return true; + }; + + /** * History.replaceState(data,title,url) * Replace the State and trigger onpopstate * We have to trigger for HTML4 compatibility @@ -1147,103 +1112,96 @@ if (typeof JSON !== 'object') { * @param {string} url * @return {true} */ - History.replaceState = function(data,title,url,queue){ - //History.debug('History.replaceState: called', arguments); - - // We assume that the URL passed in is URI-encoded, but this makes - // sure that it's fully URI encoded; any '%'s that are encoded are - // converted back into '%'s - url = encodeURI(url).replace(/%25/g, "%"); - - // Check the State - if ( History.getHashByUrl(url) ) { - throw new Error('History.js does not support states with fragment-identifiers (hashes/anchors).'); - } - - // Handle Queueing - if ( queue !== false && History.busy() ) { - // Wait + Push to Queue - //History.debug('History.replaceState: we must wait', arguments); - History.pushQueue({ - scope: History, - callback: History.replaceState, - args: arguments, - queue: queue - }); - return false; - } - - // Make Busy - History.busy(true); - - // Fetch the State Objects - var newState = History.createStateObject(data,title,url), - newStateHash = History.getHashByState(newState), - oldState = History.getState(false), - oldStateHash = History.getHashByState(oldState), - previousState = History.getStateByIndex(-2); - - // Discard Old State - History.discardState(oldState,newState,previousState); - - // If the url hasn't changed, just store and save the state - // and fire a statechange event to be consistent with the - // html 5 api - if ( newStateHash === oldStateHash ) { - // Store the newState - History.storeState(newState); - History.expectedStateId = newState.id; - - // Recycle the State - History.recycleState(newState); - - // Force update of the title - History.setTitle(newState); - - // Update HTML5 State - History.saveState(newState); - - // Fire HTML5 Event - //History.debug('History.pushState: trigger popstate'); - History.Adapter.trigger(window,'statechange'); - History.busy(false); - } - else { - // Alias to PushState - History.pushState(newState.data,newState.title,newState.url,false); - } - - // End replaceState closure - return true; - }; - - } // History.emulated.pushState - - - - // ==================================================================== - // Initialise - - // Non-Native pushState Implementation - if ( History.emulated.pushState ) { - /** - * Ensure initial state is handled correctly - */ - if ( History.getHash() && !History.emulated.hashChange ) { - History.Adapter.onDomLoad(function(){ - History.Adapter.trigger(window,'hashchange'); - }); - } + History.replaceState = function(data, title, url, queue){ + //History.debug('History.replaceState: called', arguments); - } // History.emulated.pushState + // We assume that the URL passed in is URI-encoded, but this makes + // sure that it's fully URI encoded; any '%'s that are encoded are + // converted back into '%'s + url = encodeURI(url).replace(/%25/g, '%'); - }; // History.initHtml4 + // Check the State + if (History.getHashByUrl(url)) { + throw new Error('History.js does not support states with fragment-identifiers (hashes/anchors).'); + } - // Try to Initialise History - if ( typeof History.init !== 'undefined' ) { - History.init(); - } + // Handle Queueing + if (queue !== false && History.busy()) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue, + }); + return false; + } + + // Make Busy + History.busy(true); + + // Fetch the State Objects + var newState = History.createStateObject(data, title, url); + var newStateHash = History.getHashByState(newState); + var oldState = History.getState(false); + var oldStateHash = History.getHashByState(oldState); + var previousState = History.getStateByIndex(-2); + + // Discard Old State + History.discardState(oldState, newState, previousState); + + // If the url hasn't changed, just store and save the state + // and fire a statechange event to be consistent with the + // html 5 api + if (newStateHash === oldStateHash) { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Recycle the State + History.recycleState(newState); + + // Force update of the title + History.setTitle(newState); + + // Update HTML5 State + History.saveState(newState); + + // Fire HTML5 Event + //History.debug('History.pushState: trigger popstate'); + History.Adapter.trigger(window, 'statechange'); + History.busy(false); + } else { + // Alias to PushState + History.pushState(newState.data, newState.title, newState.url, false); + } + // End replaceState closure + return true; + }; + } // History.emulated.pushState + + // ==================================================================== + // Initialise + + // Non-Native pushState Implementation + if (History.emulated.pushState) { + /** + * Ensure initial state is handled correctly + */ + if (History.getHash() && !History.emulated.hashChange) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window, 'hashchange'); + }); + } + } // History.emulated.pushState + }; // History.initHtml4 + + // Try to Initialise History + if (typeof History.init !== 'undefined') { + History.init(); + } })(window); /** * History.js Core @@ -1252,250 +1210,241 @@ if (typeof JSON !== 'object') { * @license New BSD License */ -(function(window,undefined){ - "use strict"; - - // ======================================================================== - // Initialise - - // Localise Globals - var - console = window.console||undefined, // Prevent a JSLint complain - document = window.document, // Make sure we are using the correct document - navigator = window.navigator, // Make sure we are using the correct navigator - sessionStorage = false, // sessionStorage - setTimeout = window.setTimeout, - clearTimeout = window.clearTimeout, - setInterval = window.setInterval, - clearInterval = window.clearInterval, - JSON = window.JSON, - alert = window.alert, - History = window.History = window.History||{}, // Public History Object - history = window.history; // Old History Object - - try { - sessionStorage = window.sessionStorage; // This will throw an exception in some browsers when cookies/localStorage are explicitly disabled (i.e. Chrome) - sessionStorage.setItem('TEST', '1'); - sessionStorage.removeItem('TEST'); - } catch(e) { - sessionStorage = false; - } - - // MooTools Compatibility - JSON.stringify = JSON.stringify||JSON.encode; - JSON.parse = JSON.parse||JSON.decode; - - // Check Existence - if ( typeof History.init !== 'undefined' ) { - throw new Error('History.js Core has already been loaded...'); - } - - // Initialise History - History.init = function(options){ - // Check Load Status of Adapter - if ( typeof History.Adapter === 'undefined' ) { - return false; - } - - // Check Load Status of Core - if ( typeof History.initCore !== 'undefined' ) { - History.initCore(); - } - - // Check Load Status of HTML4 Support - if ( typeof History.initHtml4 !== 'undefined' ) { - History.initHtml4(); - } - - // Return true - return true; - }; - - - // ======================================================================== - // Initialise Core - - // Initialise Core - History.initCore = function(options){ - // Initialise - if ( typeof History.initCore.initialized !== 'undefined' ) { - // Already Loaded - return false; - } - else { - History.initCore.initialized = true; - } - - - // ==================================================================== - // Options - - /** +(function(window, undefined){ + 'use strict'; + + // ======================================================================== + // Initialise + + // Localise Globals + var + console = window.console || undefined; // Prevent a JSLint complain + var document = window.document; // Make sure we are using the correct document + var navigator = window.navigator; // Make sure we are using the correct navigator + var sessionStorage = false; // sessionStorage + var setTimeout = window.setTimeout; + var clearTimeout = window.clearTimeout; + var setInterval = window.setInterval; + var clearInterval = window.clearInterval; + var JSON = window.JSON; + var alert = window.alert; + var History = window.History = window.History || {}; // Public History Object + var history = window.history; // Old History Object + + try { + sessionStorage = window.sessionStorage; // This will throw an exception in some browsers when cookies/localStorage are explicitly disabled (i.e. Chrome) + sessionStorage.setItem('TEST', '1'); + sessionStorage.removeItem('TEST'); + } catch (e) { + sessionStorage = false; + } + + // MooTools Compatibility + JSON.stringify = JSON.stringify || JSON.encode; + JSON.parse = JSON.parse || JSON.decode; + + // Check Existence + if (typeof History.init !== 'undefined') { + throw new Error('History.js Core has already been loaded...'); + } + + // Initialise History + History.init = function(options){ + // Check Load Status of Adapter + if (typeof History.Adapter === 'undefined') { + return false; + } + + // Check Load Status of Core + if (typeof History.initCore !== 'undefined') { + History.initCore(); + } + + // Check Load Status of HTML4 Support + if (typeof History.initHtml4 !== 'undefined') { + History.initHtml4(); + } + + // Return true + return true; + }; + + // ======================================================================== + // Initialise Core + + // Initialise Core + History.initCore = function(options){ + // Initialise + if (typeof History.initCore.initialized !== 'undefined') { + // Already Loaded + return false; + } else { + History.initCore.initialized = true; + } + + // ==================================================================== + // Options + + /** * History.options * Configurable options */ - History.options = History.options||{}; + History.options = History.options || {}; - /** + /** * History.options.hashChangeInterval * How long should the interval be before hashchange checks */ - History.options.hashChangeInterval = History.options.hashChangeInterval || 100; + History.options.hashChangeInterval = History.options.hashChangeInterval || 100; - /** + /** * History.options.safariPollInterval * How long should the interval be before safari poll checks */ - History.options.safariPollInterval = History.options.safariPollInterval || 500; + History.options.safariPollInterval = History.options.safariPollInterval || 500; - /** + /** * History.options.doubleCheckInterval * How long should the interval be before we perform a double check */ - History.options.doubleCheckInterval = History.options.doubleCheckInterval || 500; + History.options.doubleCheckInterval = History.options.doubleCheckInterval || 500; - /** + /** * History.options.disableSuid * Force History not to append suid */ - History.options.disableSuid = History.options.disableSuid || false; + History.options.disableSuid = History.options.disableSuid || false; - /** + /** * History.options.storeInterval * How long should we wait between store calls */ - History.options.storeInterval = History.options.storeInterval || 1000; + History.options.storeInterval = History.options.storeInterval || 1000; - /** + /** * History.options.busyDelay * How long should we wait between busy events */ - History.options.busyDelay = History.options.busyDelay || 250; + History.options.busyDelay = History.options.busyDelay || 250; - /** + /** * History.options.debug * If true will enable debug messages to be logged */ - History.options.debug = History.options.debug || false; + History.options.debug = History.options.debug || false; - /** + /** * History.options.initialTitle * What is the title of the initial state */ - History.options.initialTitle = History.options.initialTitle || document.title; + History.options.initialTitle = History.options.initialTitle || document.title; - /** + /** * History.options.html4Mode * If true, will force HTMl4 mode (hashtags) */ - History.options.html4Mode = History.options.html4Mode || false; + History.options.html4Mode = History.options.html4Mode || false; - /** + /** * History.options.delayInit * Want to override default options and call init manually. */ - History.options.delayInit = History.options.delayInit || false; + History.options.delayInit = History.options.delayInit || false; + // ==================================================================== + // Interval record - // ==================================================================== - // Interval record - - /** + /** * History.intervalList * List of intervals set, to be cleared when document is unloaded. */ - History.intervalList = []; + History.intervalList = []; - /** + /** * History.clearAllIntervals * Clears all setInterval instances. */ - History.clearAllIntervals = function(){ - var i, il = History.intervalList; - if (typeof il !== "undefined" && il !== null) { - for (i = 0; i < il.length; i++) { - clearInterval(il[i]); - } - History.intervalList = null; - } - }; - + History.clearAllIntervals = function(){ + var i; var il = History.intervalList; + if (typeof il !== 'undefined' && il !== null) { + for (i = 0; i < il.length; i++) { + clearInterval(il[i]); + } + History.intervalList = null; + } + }; - // ==================================================================== - // Debug + // ==================================================================== + // Debug - /** + /** * History.debug(message,...) * Logs the passed arguments if debug enabled */ - History.debug = function(){ - if ( (History.options.debug||false) ) { - History.log.apply(History,arguments); - } - }; + History.debug = function(){ + if ((History.options.debug || false)) { + History.log.apply(History, arguments); + } + }; - /** + /** * History.log(message,...) * Logs the passed arguments */ - History.log = function(){ - // Prepare - var - consoleExists = !(typeof console === 'undefined' || typeof console.log === 'undefined' || typeof console.log.apply === 'undefined'), - textarea = document.getElementById('log'), - message, - i,n, - args,arg + History.log = function(){ + // Prepare + var + consoleExists = !(typeof console === 'undefined' || typeof console.log === 'undefined' || typeof console.log.apply === 'undefined'); + var textarea = document.getElementById('log'); + var message; + var i; var n; + var args; var arg ; - // Write to Console - if ( consoleExists ) { - args = Array.prototype.slice.call(arguments); - message = args.shift(); - if ( typeof console.debug !== 'undefined' ) { - console.debug.apply(console,[message,args]); - } - else { - console.log.apply(console,[message,args]); - } - } - else { - message = ("\n"+arguments[0]+"\n"); - } - - // Write to log - for ( i=1,n=arguments.length; i * @author James Padolsey */ - History.getInternetExplorerMajorVersion = function(){ - var result = History.getInternetExplorerMajorVersion.cached = + History.getInternetExplorerMajorVersion = function(){ + var result = History.getInternetExplorerMajorVersion.cached = (typeof History.getInternetExplorerMajorVersion.cached !== 'undefined') - ? History.getInternetExplorerMajorVersion.cached - : (function(){ - var v = 3, - div = document.createElement('div'), - all = div.getElementsByTagName('i'); - while ( (div.innerHTML = '') && all[0] ) {} - return (v > 4) ? v : false; - })() + ? History.getInternetExplorerMajorVersion.cached + : (function(){ + var v = 3; + var div = document.createElement('div'); + var all = div.getElementsByTagName('i'); + while ((div.innerHTML = '') && all[0]) {} + return (v > 4) ? v : false; + })() ; - return result; - }; + return result; + }; - /** + /** * History.isInternetExplorer() * Are we using Internet Explorer? * @return {boolean} * @license Public Domain * @author Benjamin Arthur Lupton */ - History.isInternetExplorer = function(){ - var result = + History.isInternetExplorer = function(){ + var result = History.isInternetExplorer.cached = (typeof History.isInternetExplorer.cached !== 'undefined') - ? History.isInternetExplorer.cached - : Boolean(History.getInternetExplorerMajorVersion()) + ? History.isInternetExplorer.cached + : Boolean(History.getInternetExplorerMajorVersion()) ; - return result; - }; + return result; + }; - /** + /** * History.emulated * Which features require emulating? */ - if (History.options.html4Mode) { - History.emulated = { - pushState : true, - hashChange: true - }; - } - - else { - - History.emulated = { - pushState: !Boolean( - window.history && window.history.pushState && window.history.replaceState - && !( - (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent) /* disable for versions of iOS before version 4.3 (8F190) */ - || (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent) /* disable for the mercury iOS browser, or at least older versions of the webkit engine */ - ) - ), - hashChange: Boolean( - !(('onhashchange' in window) || ('onhashchange' in document)) - || - (History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8) - ) - }; - } - - /** + if (History.options.html4Mode) { + History.emulated = { + pushState: true, + hashChange: true, + }; + } else { + History.emulated = { + pushState: !Boolean( + window.history && window.history.pushState && window.history.replaceState && + !( + (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent) || /* disable for versions of iOS before version 4.3 (8F190) */ + (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent) /* disable for the mercury iOS browser, or at least older versions of the webkit engine */ + ), + ), + hashChange: Boolean( + !(('onhashchange' in window) || ('onhashchange' in document)) || + (History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8), + ), + }; + } + + /** * History.enabled * Is History enabled? */ - History.enabled = !History.emulated.pushState; + History.enabled = !History.emulated.pushState; - /** + /** * History.bugs * Which bugs are present */ - History.bugs = { - /** + History.bugs = { + /** * Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a `replaceState` call * https://bugs.webkit.org/show_bug.cgi?id=56249 */ - setHash: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + setHash: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), - /** + /** * Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions * https://bugs.webkit.org/show_bug.cgi?id=42940 */ - safariPoll: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + safariPoll: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), - /** + /** * MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function) */ - ieDoubleCheck: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8), + ieDoubleCheck: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8), - /** + /** * MSIE 6 requires the entire hash to be encoded for the hashes to trigger the onHashChange event */ - hashEscape: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 7) - }; + hashEscape: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 7), + }; - /** + /** * History.isEmptyObject(obj) * Checks to see if the Object is Empty * @param {Object} obj * @return {boolean} */ - History.isEmptyObject = function(obj) { - for ( var name in obj ) { - if ( obj.hasOwnProperty(name) ) { - return false; - } - } - return true; - }; + History.isEmptyObject = function(obj) { + for (var name in obj) { + if (obj.hasOwnProperty(name)) { + return false; + } + } + return true; + }; - /** + /** * History.cloneObject(obj) * Clones a object and eliminate all references to the original contexts * @param {Object} obj * @return {Object} */ - History.cloneObject = function(obj) { - var hash,newObj; - if ( obj ) { - hash = JSON.stringify(obj); - newObj = JSON.parse(hash); - } - else { - newObj = {}; - } - return newObj; - }; - - - // ==================================================================== - // URL Helpers - - /** + History.cloneObject = function(obj) { + var hash, newObj; + if (obj) { + hash = JSON.stringify(obj); + newObj = JSON.parse(hash); + } else { + newObj = {}; + } + return newObj; + }; + + // ==================================================================== + // URL Helpers + + /** * History.getRootUrl() * Turns "http://mysite.com/dir/page.html?asd" into "http://mysite.com" * @return {String} rootUrl */ - History.getRootUrl = function(){ - // Create - var rootUrl = document.location.protocol+'//'+(document.location.hostname||document.location.host); - if ( document.location.port||false ) { - rootUrl += ':'+document.location.port; - } - rootUrl += '/'; + History.getRootUrl = function(){ + // Create + var rootUrl = document.location.protocol + '//' + (document.location.hostname || document.location.host); + if (document.location.port || false) { + rootUrl += ':' + document.location.port; + } + rootUrl += '/'; - // Return - return rootUrl; - }; + // Return + return rootUrl; + }; - /** + /** * History.getBaseHref() * Fetches the `href` attribute of the `` element if it exists * @return {String} baseHref */ - History.getBaseHref = function(){ - // Create - var - baseElements = document.getElementsByTagName('base'), - baseElement = null, - baseHref = ''; - - // Test for Base Element - if ( baseElements.length === 1 ) { - // Prepare for Base Element - baseElement = baseElements[0]; - baseHref = baseElement.href.replace(/[^\/]+$/,''); - } - - // Adjust trailing slash - baseHref = baseHref.replace(/\/+$/,''); - if ( baseHref ) baseHref += '/'; - - // Return - return baseHref; - }; - - /** + History.getBaseHref = function(){ + // Create + var + baseElements = document.getElementsByTagName('base'); + var baseElement = null; + var baseHref = ''; + + // Test for Base Element + if (baseElements.length === 1) { + // Prepare for Base Element + baseElement = baseElements[0]; + baseHref = baseElement.href.replace(/[^\/]+$/, ''); + } + + // Adjust trailing slash + baseHref = baseHref.replace(/\/+$/, ''); + if (baseHref) baseHref += '/'; + + // Return + return baseHref; + }; + + /** * History.getBaseUrl() * Fetches the baseHref or basePageUrl or rootUrl (whichever one exists first) * @return {String} baseUrl */ - History.getBaseUrl = function(){ - // Create - var baseUrl = History.getBaseHref()||History.getBasePageUrl()||History.getRootUrl(); + History.getBaseUrl = function(){ + // Create + var baseUrl = History.getBaseHref() || History.getBasePageUrl() || History.getRootUrl(); - // Return - return baseUrl; - }; + // Return + return baseUrl; + }; - /** + /** * History.getPageUrl() * Fetches the URL of the current page * @return {String} pageUrl */ - History.getPageUrl = function(){ - // Fetch - var - State = History.getState(false,false), - stateUrl = (State||{}).url||History.getLocationHref(), - pageUrl; + History.getPageUrl = function(){ + // Fetch + var + State = History.getState(false, false); + var stateUrl = (State || {}).url || History.getLocationHref(); + var pageUrl; - // Create - pageUrl = stateUrl.replace(/\/+$/,'').replace(/[^\/]+$/,function(part,index,string){ - return (/\./).test(part) ? part : part+'/'; - }); + // Create + pageUrl = stateUrl.replace(/\/+$/, '').replace(/[^\/]+$/, function(part, index, string){ + return (/\./).test(part) ? part : part + '/'; + }); - // Return - return pageUrl; - }; + // Return + return pageUrl; + }; - /** + /** * History.getBasePageUrl() * Fetches the Url of the directory of the current page * @return {String} basePageUrl */ - History.getBasePageUrl = function(){ - // Create - var basePageUrl = (History.getLocationHref()).replace(/[#\?].*/,'').replace(/[^\/]+$/,function(part,index,string){ - return (/[^\/]$/).test(part) ? '' : part; - }).replace(/\/+$/,'')+'/'; + History.getBasePageUrl = function(){ + // Create + var basePageUrl = (History.getLocationHref()).replace(/[#\?].*/, '').replace(/[^\/]+$/, function(part, index, string){ + return (/[^\/]$/).test(part) ? '' : part; + }).replace(/\/+$/, '') + '/'; - // Return - return basePageUrl; - }; + // Return + return basePageUrl; + }; - /** + /** * History.getFullUrl(url) * Ensures that we have an absolute URL and not a relative URL * @param {string} url * @param {Boolean} allowBaseHref * @return {string} fullUrl */ - History.getFullUrl = function(url,allowBaseHref){ - // Prepare - var fullUrl = url, firstChar = url.substring(0,1); - allowBaseHref = (typeof allowBaseHref === 'undefined') ? true : allowBaseHref; - - // Check - if ( /[a-z]+\:\/\//.test(url) ) { - // Full URL - } - else if ( firstChar === '/' ) { - // Root URL - fullUrl = History.getRootUrl()+url.replace(/^\/+/,''); - } - else if ( firstChar === '#' ) { - // Anchor URL - fullUrl = History.getPageUrl().replace(/#.*/,'')+url; - } - else if ( firstChar === '?' ) { - // Query URL - fullUrl = History.getPageUrl().replace(/[\?#].*/,'')+url; - } - else { - // Relative URL - if ( allowBaseHref ) { - fullUrl = History.getBaseUrl()+url.replace(/^(\.\/)+/,''); - } else { - fullUrl = History.getBasePageUrl()+url.replace(/^(\.\/)+/,''); - } - // We have an if condition above as we do not want hashes - // which are relative to the baseHref in our URLs - // as if the baseHref changes, then all our bookmarks - // would now point to different locations - // whereas the basePageUrl will always stay the same - } - - // Return - return fullUrl.replace(/\#$/,''); - }; - - /** + History.getFullUrl = function(url, allowBaseHref){ + // Prepare + var fullUrl = url; var firstChar = url.substring(0, 1); + allowBaseHref = (typeof allowBaseHref === 'undefined') ? true : allowBaseHref; + + // Check + if (/[a-z]+\:\/\//.test(url)) { + // Full URL + } else if (firstChar === '/') { + // Root URL + fullUrl = History.getRootUrl() + url.replace(/^\/+/, ''); + } else if (firstChar === '#') { + // Anchor URL + fullUrl = History.getPageUrl().replace(/#.*/, '') + url; + } else if (firstChar === '?') { + // Query URL + fullUrl = History.getPageUrl().replace(/[\?#].*/, '') + url; + } else { + // Relative URL + if (allowBaseHref) { + fullUrl = History.getBaseUrl() + url.replace(/^(\.\/)+/, ''); + } else { + fullUrl = History.getBasePageUrl() + url.replace(/^(\.\/)+/, ''); + } + // We have an if condition above as we do not want hashes + // which are relative to the baseHref in our URLs + // as if the baseHref changes, then all our bookmarks + // would now point to different locations + // whereas the basePageUrl will always stay the same + } + + // Return + return fullUrl.replace(/\#$/, ''); + }; + + /** * History.getShortUrl(url) * Ensures that we have a relative URL and not a absolute URL * @param {string} url * @return {string} url */ - History.getShortUrl = function(url){ - // Prepare - var shortUrl = url, baseUrl = History.getBaseUrl(), rootUrl = History.getRootUrl(); + History.getShortUrl = function(url){ + // Prepare + var shortUrl = url; var baseUrl = History.getBaseUrl(); var rootUrl = History.getRootUrl(); - // Trim baseUrl - if ( History.emulated.pushState ) { - // We are in a if statement as when pushState is not emulated - // The actual url these short urls are relative to can change - // So within the same session, we the url may end up somewhere different - shortUrl = shortUrl.replace(baseUrl,''); - } + // Trim baseUrl + if (History.emulated.pushState) { + // We are in a if statement as when pushState is not emulated + // The actual url these short urls are relative to can change + // So within the same session, we the url may end up somewhere different + shortUrl = shortUrl.replace(baseUrl, ''); + } - // Trim rootUrl - shortUrl = shortUrl.replace(rootUrl,'/'); + // Trim rootUrl + shortUrl = shortUrl.replace(rootUrl, '/'); - // Ensure we can still detect it as a state - if ( History.isTraditionalAnchor(shortUrl) ) { - shortUrl = './'+shortUrl; - } + // Ensure we can still detect it as a state + if (History.isTraditionalAnchor(shortUrl)) { + shortUrl = './' + shortUrl; + } - // Clean It - shortUrl = shortUrl.replace(/^(\.\/)+/g,'./').replace(/\#$/,''); + // Clean It + shortUrl = shortUrl.replace(/^(\.\/)+/g, './').replace(/\#$/, ''); - // Return - return shortUrl; - }; + // Return + return shortUrl; + }; - /** + /** * History.getLocationHref(document) * Returns a normalized version of document.location.href * accounting for browser inconsistencies, etc. @@ -1818,223 +1757,215 @@ if (typeof JSON !== 'object') { * @param {object} document * @return {string} url */ - History.getLocationHref = function(doc) { - doc = doc || document; + History.getLocationHref = function(doc) { + doc = doc || document; - // most of the time, this will be true - if (doc.URL === doc.location.href) - return doc.location.href; + // most of the time, this will be true + if (doc.URL === doc.location.href) { return doc.location.href; } - // some versions of webkit URI-decode document.location.href - // but they leave document.URL in an encoded state - if (doc.location.href === decodeURIComponent(doc.URL)) - return doc.URL; + // some versions of webkit URI-decode document.location.href + // but they leave document.URL in an encoded state + if (doc.location.href === decodeURIComponent(doc.URL)) { return doc.URL; } - // FF 3.6 only updates document.URL when a page is reloaded - // document.location.href is updated correctly - if (doc.location.hash && decodeURIComponent(doc.location.href.replace(/^[^#]+/, "")) === doc.location.hash) - return doc.location.href; + // FF 3.6 only updates document.URL when a page is reloaded + // document.location.href is updated correctly + if (doc.location.hash && decodeURIComponent(doc.location.href.replace(/^[^#]+/, '')) === doc.location.hash) { return doc.location.href; } - if (doc.URL.indexOf('#') == -1 && doc.location.href.indexOf('#') != -1) - return doc.location.href; - - return doc.URL || doc.location.href; - }; + if (doc.URL.indexOf('#') == -1 && doc.location.href.indexOf('#') != -1) { return doc.location.href; } + return doc.URL || doc.location.href; + }; - // ==================================================================== - // State Storage + // ==================================================================== + // State Storage - /** + /** * History.store * The store for all session specific data */ - History.store = {}; + History.store = {}; - /** + /** * History.idToState * 1-1: State ID to State Object */ - History.idToState = History.idToState||{}; + History.idToState = History.idToState || {}; - /** + /** * History.stateToId * 1-1: State String to State ID */ - History.stateToId = History.stateToId||{}; + History.stateToId = History.stateToId || {}; - /** + /** * History.urlToId * 1-1: State URL to State ID */ - History.urlToId = History.urlToId||{}; + History.urlToId = History.urlToId || {}; - /** + /** * History.storedStates * Store the states in an array */ - History.storedStates = History.storedStates||[]; + History.storedStates = History.storedStates || []; - /** + /** * History.savedStates * Saved the states in an array */ - History.savedStates = History.savedStates||[]; + History.savedStates = History.savedStates || []; - /** + /** * History.noramlizeStore() * Noramlize the store by adding necessary values */ - History.normalizeStore = function(){ - History.store.idToState = History.store.idToState||{}; - History.store.urlToId = History.store.urlToId||{}; - History.store.stateToId = History.store.stateToId||{}; - }; + History.normalizeStore = function(){ + History.store.idToState = History.store.idToState || {}; + History.store.urlToId = History.store.urlToId || {}; + History.store.stateToId = History.store.stateToId || {}; + }; - /** + /** * History.getState() * Get an object containing the data, title and url of the current state * @param {Boolean} friendly * @param {Boolean} create * @return {Object} State */ - History.getState = function(friendly,create){ - // Prepare - if ( typeof friendly === 'undefined' ) { friendly = true; } - if ( typeof create === 'undefined' ) { create = true; } + History.getState = function(friendly, create){ + // Prepare + if (typeof friendly === 'undefined') { friendly = true; } + if (typeof create === 'undefined') { create = true; } - // Fetch - var State = History.getLastSavedState(); + // Fetch + var State = History.getLastSavedState(); - // Create - if ( !State && create ) { - State = History.createStateObject(); - } + // Create + if (!State && create) { + State = History.createStateObject(); + } - // Adjust - if ( friendly ) { - State = History.cloneObject(State); - State.url = State.cleanUrl||State.url; - } + // Adjust + if (friendly) { + State = History.cloneObject(State); + State.url = State.cleanUrl || State.url; + } - // Return - return State; - }; + // Return + return State; + }; - /** + /** * History.getIdByState(State) * Gets a ID for a State * @param {State} newState * @return {String} id */ - History.getIdByState = function(newState){ - - // Fetch ID - var id = History.extractId(newState.url), - str; - - if ( !id ) { - // Find ID via State String - str = History.getStateString(newState); - if ( typeof History.stateToId[str] !== 'undefined' ) { - id = History.stateToId[str]; - } - else if ( typeof History.store.stateToId[str] !== 'undefined' ) { - id = History.store.stateToId[str]; - } - else { - // Generate a new ID - while ( true ) { - id = (new Date()).getTime() + String(Math.random()).replace(/\D/g,''); - if ( typeof History.idToState[id] === 'undefined' && typeof History.store.idToState[id] === 'undefined' ) { - break; - } - } - - // Apply the new State to the ID - History.stateToId[str] = id; - History.idToState[id] = newState; - } - } - - // Return ID - return id; - }; - - /** + History.getIdByState = function(newState){ + // Fetch ID + var id = History.extractId(newState.url); + var str; + + if (!id) { + // Find ID via State String + str = History.getStateString(newState); + if (typeof History.stateToId[str] !== 'undefined') { + id = History.stateToId[str]; + } else if (typeof History.store.stateToId[str] !== 'undefined') { + id = History.store.stateToId[str]; + } else { + // Generate a new ID + while (true) { + id = (new Date()).getTime() + String(Math.random()).replace(/\D/g, ''); + if (typeof History.idToState[id] === 'undefined' && typeof History.store.idToState[id] === 'undefined') { + break; + } + } + + // Apply the new State to the ID + History.stateToId[str] = id; + History.idToState[id] = newState; + } + } + + // Return ID + return id; + }; + + /** * History.normalizeState(State) * Expands a State Object * @param {object} State * @return {object} */ - History.normalizeState = function(oldState){ - // Variables - var newState, dataNotEmpty; - - // Prepare - if ( !oldState || (typeof oldState !== 'object') ) { - oldState = {}; - } - - // Check - if ( typeof oldState.normalized !== 'undefined' ) { - return oldState; - } - - // Adjust - if ( !oldState.data || (typeof oldState.data !== 'object') ) { - oldState.data = {}; - } - - // ---------------------------------------------------------------- - - // Create - newState = {}; - newState.normalized = true; - newState.title = oldState.title||''; - newState.url = History.getFullUrl(oldState.url?oldState.url:(History.getLocationHref())); - newState.hash = History.getShortUrl(newState.url); - newState.data = History.cloneObject(oldState.data); - - // Fetch ID - newState.id = History.getIdByState(newState); - - // ---------------------------------------------------------------- - - // Clean the URL - newState.cleanUrl = newState.url.replace(/\??\&_suid.*/,''); - newState.url = newState.cleanUrl; - - // Check to see if we have more than just a url - dataNotEmpty = !History.isEmptyObject(newState.data); - - // Apply - if ( (newState.title || dataNotEmpty) && History.options.disableSuid !== true ) { - // Add ID to Hash - newState.hash = History.getShortUrl(newState.url).replace(/\??\&_suid.*/,''); - if ( !/\?/.test(newState.hash) ) { - newState.hash += '?'; - } - newState.hash += '&_suid='+newState.id; - } + History.normalizeState = function(oldState){ + // Variables + var newState, dataNotEmpty; + + // Prepare + if (!oldState || (typeof oldState !== 'object')) { + oldState = {}; + } + + // Check + if (typeof oldState.normalized !== 'undefined') { + return oldState; + } + + // Adjust + if (!oldState.data || (typeof oldState.data !== 'object')) { + oldState.data = {}; + } + + // ---------------------------------------------------------------- + + // Create + newState = {}; + newState.normalized = true; + newState.title = oldState.title || ''; + newState.url = History.getFullUrl(oldState.url ? oldState.url : (History.getLocationHref())); + newState.hash = History.getShortUrl(newState.url); + newState.data = History.cloneObject(oldState.data); + + // Fetch ID + newState.id = History.getIdByState(newState); + + // ---------------------------------------------------------------- + + // Clean the URL + newState.cleanUrl = newState.url.replace(/\??\&_suid.*/, ''); + newState.url = newState.cleanUrl; + + // Check to see if we have more than just a url + dataNotEmpty = !History.isEmptyObject(newState.data); + + // Apply + if ((newState.title || dataNotEmpty) && History.options.disableSuid !== true) { + // Add ID to Hash + newState.hash = History.getShortUrl(newState.url).replace(/\??\&_suid.*/, ''); + if (!/\?/.test(newState.hash)) { + newState.hash += '?'; + } + newState.hash += '&_suid=' + newState.id; + } - // Create the Hashed URL - newState.hashedUrl = History.getFullUrl(newState.hash); + // Create the Hashed URL + newState.hashedUrl = History.getFullUrl(newState.hash); - // ---------------------------------------------------------------- + // ---------------------------------------------------------------- - // Update the URL if we have a duplicate - if ( (History.emulated.pushState || History.bugs.safariPoll) && History.hasUrlDuplicate(newState) ) { - newState.url = newState.hashedUrl; - } + // Update the URL if we have a duplicate + if ((History.emulated.pushState || History.bugs.safariPoll) && History.hasUrlDuplicate(newState)) { + newState.url = newState.hashedUrl; + } - // ---------------------------------------------------------------- + // ---------------------------------------------------------------- - // Return - return newState; - }; + // Return + return newState; + }; - /** + /** * History.createStateObject(data,title,url) * Creates a object based on the data, title and url state params * @param {object} data @@ -2042,976 +1973,956 @@ if (typeof JSON !== 'object') { * @param {string} url * @return {object} */ - History.createStateObject = function(data,title,url){ - // Hashify - var State = { - 'data': data, - 'title': title, - 'url': url - }; + History.createStateObject = function(data, title, url){ + // Hashify + var State = { + data: data, + title: title, + url: url, + }; - // Expand the State - State = History.normalizeState(State); + // Expand the State + State = History.normalizeState(State); - // Return object - return State; - }; + // Return object + return State; + }; - /** + /** * History.getStateById(id) * Get a state by it's UID * @param {String} id */ - History.getStateById = function(id){ - // Prepare - id = String(id); + History.getStateById = function(id){ + // Prepare + id = String(id); - // Retrieve - var State = History.idToState[id] || History.store.idToState[id] || undefined; + // Retrieve + var State = History.idToState[id] || History.store.idToState[id] || undefined; - // Return State - return State; - }; + // Return State + return State; + }; - /** + /** * Get a State's String * @param {State} passedState */ - History.getStateString = function(passedState){ - // Prepare - var State, cleanedState, str; + History.getStateString = function(passedState){ + // Prepare + var State, cleanedState, str; - // Fetch - State = History.normalizeState(passedState); + // Fetch + State = History.normalizeState(passedState); - // Clean - cleanedState = { - data: State.data, - title: passedState.title, - url: passedState.url - }; + // Clean + cleanedState = { + data: State.data, + title: passedState.title, + url: passedState.url, + }; - // Fetch - str = JSON.stringify(cleanedState); + // Fetch + str = JSON.stringify(cleanedState); - // Return - return str; - }; + // Return + return str; + }; - /** + /** * Get a State's ID * @param {State} passedState * @return {String} id */ - History.getStateId = function(passedState){ - // Prepare - var State, id; + History.getStateId = function(passedState){ + // Prepare + var State, id; - // Fetch - State = History.normalizeState(passedState); + // Fetch + State = History.normalizeState(passedState); - // Fetch - id = State.id; + // Fetch + id = State.id; - // Return - return id; - }; + // Return + return id; + }; - /** + /** * History.getHashByState(State) * Creates a Hash for the State Object * @param {State} passedState * @return {String} hash */ - History.getHashByState = function(passedState){ - // Prepare - var State, hash; + History.getHashByState = function(passedState){ + // Prepare + var State, hash; - // Fetch - State = History.normalizeState(passedState); + // Fetch + State = History.normalizeState(passedState); - // Hash - hash = State.hash; + // Hash + hash = State.hash; - // Return - return hash; - }; + // Return + return hash; + }; - /** + /** * History.extractId(url_or_hash) * Get a State ID by it's URL or Hash * @param {string} url_or_hash * @return {string} id */ - History.extractId = function ( url_or_hash ) { - // Prepare - var id,parts,url, tmp; - - // Extract - - // If the URL has a #, use the id from before the # - if (url_or_hash.indexOf('#') != -1) - { - tmp = url_or_hash.split("#")[0]; - } - else - { - tmp = url_or_hash; - } - - parts = /(.*)\&_suid=([0-9]+)$/.exec(tmp); - url = parts ? (parts[1]||url_or_hash) : url_or_hash; - id = parts ? String(parts[2]||'') : ''; - - // Return - return id||false; - }; - - /** + History.extractId = function (url_or_hash) { + // Prepare + var id, parts, url, tmp; + + // Extract + + // If the URL has a #, use the id from before the # + if (url_or_hash.indexOf('#') != -1) { + tmp = url_or_hash.split('#')[0]; + } else { + tmp = url_or_hash; + } + + parts = /(.*)\&_suid=([0-9]+)$/.exec(tmp); + url = parts ? (parts[1] || url_or_hash) : url_or_hash; + id = parts ? String(parts[2] || '') : ''; + + // Return + return id || false; + }; + + /** * History.isTraditionalAnchor * Checks to see if the url is a traditional anchor or not * @param {String} url_or_hash * @return {Boolean} */ - History.isTraditionalAnchor = function(url_or_hash){ - // Check - var isTraditional = !(/[\/\?\.]/.test(url_or_hash)); + History.isTraditionalAnchor = function(url_or_hash){ + // Check + var isTraditional = !(/[\/\?\.]/.test(url_or_hash)); - // Return - return isTraditional; - }; + // Return + return isTraditional; + }; - /** + /** * History.extractState * Get a State by it's URL or Hash * @param {String} url_or_hash * @return {State|null} */ - History.extractState = function(url_or_hash,create){ - // Prepare - var State = null, id, url; - create = create||false; - - // Fetch SUID - id = History.extractId(url_or_hash); - if ( id ) { - State = History.getStateById(id); - } - - // Fetch SUID returned no State - if ( !State ) { - // Fetch URL - url = History.getFullUrl(url_or_hash); - - // Check URL - id = History.getIdByUrl(url)||false; - if ( id ) { - State = History.getStateById(id); - } - - // Create State - if ( !State && create && !History.isTraditionalAnchor(url_or_hash) ) { - State = History.createStateObject(null,null,url); - } - } - - // Return - return State; - }; - - /** + History.extractState = function(url_or_hash, create){ + // Prepare + var State = null; var id; var url; + create = create || false; + + // Fetch SUID + id = History.extractId(url_or_hash); + if (id) { + State = History.getStateById(id); + } + + // Fetch SUID returned no State + if (!State) { + // Fetch URL + url = History.getFullUrl(url_or_hash); + + // Check URL + id = History.getIdByUrl(url) || false; + if (id) { + State = History.getStateById(id); + } + + // Create State + if (!State && create && !History.isTraditionalAnchor(url_or_hash)) { + State = History.createStateObject(null, null, url); + } + } + + // Return + return State; + }; + + /** * History.getIdByUrl() * Get a State ID by a State URL */ - History.getIdByUrl = function(url){ - // Fetch - var id = History.urlToId[url] || History.store.urlToId[url] || undefined; + History.getIdByUrl = function(url){ + // Fetch + var id = History.urlToId[url] || History.store.urlToId[url] || undefined; - // Return - return id; - }; + // Return + return id; + }; - /** + /** * History.getLastSavedState() * Get an object containing the data, title and url of the current state * @return {Object} State */ - History.getLastSavedState = function(){ - return History.savedStates[History.savedStates.length-1]||undefined; - }; + History.getLastSavedState = function(){ + return History.savedStates[History.savedStates.length - 1] || undefined; + }; - /** + /** * History.getLastStoredState() * Get an object containing the data, title and url of the current state * @return {Object} State */ - History.getLastStoredState = function(){ - return History.storedStates[History.storedStates.length-1]||undefined; - }; + History.getLastStoredState = function(){ + return History.storedStates[History.storedStates.length - 1] || undefined; + }; - /** + /** * History.hasUrlDuplicate * Checks if a Url will have a url conflict * @param {Object} newState * @return {Boolean} hasDuplicate */ - History.hasUrlDuplicate = function(newState) { - // Prepare - var hasDuplicate = false, - oldState; + History.hasUrlDuplicate = function(newState) { + // Prepare + var hasDuplicate = false; + var oldState; - // Fetch - oldState = History.extractState(newState.url); + // Fetch + oldState = History.extractState(newState.url); - // Check - hasDuplicate = oldState && oldState.id !== newState.id; + // Check + hasDuplicate = oldState && oldState.id !== newState.id; - // Return - return hasDuplicate; - }; + // Return + return hasDuplicate; + }; - /** + /** * History.storeState * Store a State * @param {Object} newState * @return {Object} newState */ - History.storeState = function(newState){ - // Store the State - History.urlToId[newState.url] = newState.id; + History.storeState = function(newState){ + // Store the State + History.urlToId[newState.url] = newState.id; - // Push the State - History.storedStates.push(History.cloneObject(newState)); + // Push the State + History.storedStates.push(History.cloneObject(newState)); - // Return newState - return newState; - }; + // Return newState + return newState; + }; - /** + /** * History.isLastSavedState(newState) * Tests to see if the state is the last state * @param {Object} newState * @return {boolean} isLast */ - History.isLastSavedState = function(newState){ - // Prepare - var isLast = false, - newId, oldState, oldId; + History.isLastSavedState = function(newState){ + // Prepare + var isLast = false; + var newId; var oldState; var oldId; - // Check - if ( History.savedStates.length ) { - newId = newState.id; - oldState = History.getLastSavedState(); - oldId = oldState.id; + // Check + if (History.savedStates.length) { + newId = newState.id; + oldState = History.getLastSavedState(); + oldId = oldState.id; - // Check - isLast = (newId === oldId); - } + // Check + isLast = (newId === oldId); + } - // Return - return isLast; - }; + // Return + return isLast; + }; - /** + /** * History.saveState * Push a State * @param {Object} newState * @return {boolean} changed */ - History.saveState = function(newState){ - // Check Hash - if ( History.isLastSavedState(newState) ) { - return false; - } + History.saveState = function(newState){ + // Check Hash + if (History.isLastSavedState(newState)) { + return false; + } - // Push the State - History.savedStates.push(History.cloneObject(newState)); + // Push the State + History.savedStates.push(History.cloneObject(newState)); - // Return true - return true; - }; + // Return true + return true; + }; - /** + /** * History.getStateByIndex() * Gets a state by the index * @param {integer} index * @return {Object} */ - History.getStateByIndex = function(index){ - // Prepare - var State = null; - - // Handle - if ( typeof index === 'undefined' ) { - // Get the last inserted - State = History.savedStates[History.savedStates.length-1]; - } - else if ( index < 0 ) { - // Get from the end - State = History.savedStates[History.savedStates.length+index]; - } - else { - // Get from the beginning - State = History.savedStates[index]; - } - - // Return State - return State; - }; - - /** + History.getStateByIndex = function(index){ + // Prepare + var State = null; + + // Handle + if (typeof index === 'undefined') { + // Get the last inserted + State = History.savedStates[History.savedStates.length - 1]; + } else if (index < 0) { + // Get from the end + State = History.savedStates[History.savedStates.length + index]; + } else { + // Get from the beginning + State = History.savedStates[index]; + } + + // Return State + return State; + }; + + /** * History.getCurrentIndex() * Gets the current index * @return (integer) */ - History.getCurrentIndex = function(){ - // Prepare - var index = null; - - // No states saved - if(History.savedStates.length < 1) { - index = 0; - } - else { - index = History.savedStates.length-1; - } - return index; - }; - - // ==================================================================== - // Hash Helpers - - /** + History.getCurrentIndex = function(){ + // Prepare + var index = null; + + // No states saved + if (History.savedStates.length < 1) { + index = 0; + } else { + index = History.savedStates.length - 1; + } + return index; + }; + + // ==================================================================== + // Hash Helpers + + /** * History.getHash() * @param {Location=} location * Gets the current document hash * Note: unlike location.hash, this is guaranteed to return the escaped hash in all browsers * @return {string} */ - History.getHash = function(doc){ - var url = History.getLocationHref(doc), - hash; - hash = History.getHashByUrl(url); - return hash; - }; + History.getHash = function(doc){ + var url = History.getLocationHref(doc); + var hash; + hash = History.getHashByUrl(url); + return hash; + }; - /** + /** * History.unescapeHash() * normalize and Unescape a Hash * @param {String} hash * @return {string} */ - History.unescapeHash = function(hash){ - // Prepare - var result = History.normalizeHash(hash); + History.unescapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); - // Unescape hash - result = decodeURIComponent(result); + // Unescape hash + result = decodeURIComponent(result); - // Return result - return result; - }; + // Return result + return result; + }; - /** + /** * History.normalizeHash() * normalize a hash across browsers * @return {string} */ - History.normalizeHash = function(hash){ - // Prepare - var result = hash.replace(/[^#]*#/,'').replace(/#.*/, ''); + History.normalizeHash = function(hash){ + // Prepare + var result = hash.replace(/[^#]*#/, '').replace(/#.*/, ''); - // Return result - return result; - }; + // Return result + return result; + }; - /** + /** * History.setHash(hash) * Sets the document hash * @param {string} hash * @return {History} */ - History.setHash = function(hash,queue){ - // Prepare - var State, pageUrl; - - // Handle Queueing - if ( queue !== false && History.busy() ) { - // Wait + Push to Queue - //History.debug('History.setHash: we must wait', arguments); - History.pushQueue({ - scope: History, - callback: History.setHash, - args: arguments, - queue: queue - }); - return false; - } - - // Log - //History.debug('History.setHash: called',hash); - - // Make Busy + Continue - History.busy(true); - - // Check if hash is a state - State = History.extractState(hash,true); - if ( State && !History.emulated.pushState ) { - // Hash is a state so skip the setHash - //History.debug('History.setHash: Hash is a state so skipping the hash set with a direct pushState call',arguments); - - // PushState - History.pushState(State.data,State.title,State.url,false); - } - else if ( History.getHash() !== hash ) { - // Hash is a proper hash, so apply it - - // Handle browser bugs - if ( History.bugs.setHash ) { - // Fix Safari Bug https://bugs.webkit.org/show_bug.cgi?id=56249 - - // Fetch the base page - pageUrl = History.getPageUrl(); - - // Safari hash apply - History.pushState(null,null,pageUrl+'#'+hash,false); - } - else { - // Normal hash apply - document.location.hash = hash; - } - } - - // Chain - return History; - }; - - /** + History.setHash = function(hash, queue){ + // Prepare + var State, pageUrl; + + // Handle Queueing + if (queue !== false && History.busy()) { + // Wait + Push to Queue + //History.debug('History.setHash: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.setHash, + args: arguments, + queue: queue, + }); + return false; + } + + // Log + //History.debug('History.setHash: called',hash); + + // Make Busy + Continue + History.busy(true); + + // Check if hash is a state + State = History.extractState(hash, true); + if (State && !History.emulated.pushState) { + // Hash is a state so skip the setHash + //History.debug('History.setHash: Hash is a state so skipping the hash set with a direct pushState call',arguments); + + // PushState + History.pushState(State.data, State.title, State.url, false); + } else if (History.getHash() !== hash) { + // Hash is a proper hash, so apply it + + // Handle browser bugs + if (History.bugs.setHash) { + // Fix Safari Bug https://bugs.webkit.org/show_bug.cgi?id=56249 + + // Fetch the base page + pageUrl = History.getPageUrl(); + + // Safari hash apply + History.pushState(null, null, pageUrl + '#' + hash, false); + } else { + // Normal hash apply + document.location.hash = hash; + } + } + + // Chain + return History; + }; + + /** * History.escape() * normalize and Escape a Hash * @return {string} */ - History.escapeHash = function(hash){ - // Prepare - var result = History.normalizeHash(hash); + History.escapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); - // Escape hash - result = window.encodeURIComponent(result); + // Escape hash + result = window.encodeURIComponent(result); - // IE6 Escape Bug - if ( !History.bugs.hashEscape ) { - // Restore common parts - result = result - .replace(/\%21/g,'!') - .replace(/\%26/g,'&') - .replace(/\%3D/g,'=') - .replace(/\%3F/g,'?'); - } + // IE6 Escape Bug + if (!History.bugs.hashEscape) { + // Restore common parts + result = result + .replace(/\%21/g, '!') + .replace(/\%26/g, '&') + .replace(/\%3D/g, '=') + .replace(/\%3F/g, '?'); + } - // Return result - return result; - }; + // Return result + return result; + }; - /** + /** * History.getHashByUrl(url) * Extracts the Hash from a URL * @param {string} url * @return {string} url */ - History.getHashByUrl = function(url){ - // Extract the hash - var hash = String(url) - .replace(/([^#]*)#?([^#]*)#?(.*)/, '$2') + History.getHashByUrl = function(url){ + // Extract the hash + var hash = String(url) + .replace(/([^#]*)#?([^#]*)#?(.*)/, '$2') ; - // Unescape hash - hash = History.unescapeHash(hash); + // Unescape hash + hash = History.unescapeHash(hash); - // Return hash - return hash; - }; + // Return hash + return hash; + }; - /** + /** * History.setTitle(title) * Applies the title to the document * @param {State} newState * @return {Boolean} */ - History.setTitle = function(newState){ - // Prepare - var title = newState.title, - firstState; - - // Initial - if ( !title ) { - firstState = History.getStateByIndex(0); - if ( firstState && firstState.url === newState.url ) { - title = firstState.title||History.options.initialTitle; - } - } + History.setTitle = function(newState){ + // Prepare + var title = newState.title; + var firstState; - // Apply - try { - document.getElementsByTagName('title')[0].innerHTML = title.replace('<','<').replace('>','>').replace(' & ',' & '); - } - catch ( Exception ) { } - document.title = title; + // Initial + if (!title) { + firstState = History.getStateByIndex(0); + if (firstState && firstState.url === newState.url) { + title = firstState.title || History.options.initialTitle; + } + } - // Chain - return History; - }; + // Apply + try { + document.getElementsByTagName('title')[0].innerHTML = title.replace('<', '<').replace('>', '>').replace(' & ', ' & '); + } catch (Exception) { } + document.title = title; + // Chain + return History; + }; - // ==================================================================== - // Queueing + // ==================================================================== + // Queueing - /** + /** * History.queues * The list of queues to use * First In, First Out */ - History.queues = []; + History.queues = []; - /** + /** * History.busy(value) * @param {boolean} value [optional] * @return {boolean} busy */ - History.busy = function(value){ - // Apply - if ( typeof value !== 'undefined' ) { - //History.debug('History.busy: changing ['+(History.busy.flag||false)+'] to ['+(value||false)+']', History.queues.length); - History.busy.flag = value; - } - // Default - else if ( typeof History.busy.flag === 'undefined' ) { - History.busy.flag = false; - } - - // Queue - if ( !History.busy.flag ) { - // Execute the next item in the queue - clearTimeout(History.busy.timeout); - var fireNext = function(){ - var i, queue, item; - if ( History.busy.flag ) return; - for ( i=History.queues.length-1; i >= 0; --i ) { - queue = History.queues[i]; - if ( queue.length === 0 ) continue; - item = queue.shift(); - History.fireQueueItem(item); - History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); - } - }; - History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); - } - - // Return - return History.busy.flag; - }; - - /** + History.busy = function(value){ + // Apply + if (typeof value !== 'undefined') { + //History.debug('History.busy: changing ['+(History.busy.flag||false)+'] to ['+(value||false)+']', History.queues.length); + History.busy.flag = value; + } + // Default + else if (typeof History.busy.flag === 'undefined') { + History.busy.flag = false; + } + + // Queue + if (!History.busy.flag) { + // Execute the next item in the queue + clearTimeout(History.busy.timeout); + var fireNext = function(){ + var i, queue, item; + if (History.busy.flag) return; + for (i = History.queues.length - 1; i >= 0; --i) { + queue = History.queues[i]; + if (queue.length === 0) continue; + item = queue.shift(); + History.fireQueueItem(item); + History.busy.timeout = setTimeout(fireNext, History.options.busyDelay); + } + }; + History.busy.timeout = setTimeout(fireNext, History.options.busyDelay); + } + + // Return + return History.busy.flag; + }; + + /** * History.busy.flag */ - History.busy.flag = false; + History.busy.flag = false; - /** + /** * History.fireQueueItem(item) * Fire a Queue Item * @param {Object} item * @return {Mixed} result */ - History.fireQueueItem = function(item){ - return item.callback.apply(item.scope||History,item.args||[]); - }; + History.fireQueueItem = function(item){ + return item.callback.apply(item.scope || History, item.args || []); + }; - /** + /** * History.pushQueue(callback,args) * Add an item to the queue * @param {Object} item [scope,callback,args,queue] */ - History.pushQueue = function(item){ - // Prepare the queue - History.queues[item.queue||0] = History.queues[item.queue||0]||[]; + History.pushQueue = function(item){ + // Prepare the queue + History.queues[item.queue || 0] = History.queues[item.queue || 0] || []; - // Add to the queue - History.queues[item.queue||0].push(item); + // Add to the queue + History.queues[item.queue || 0].push(item); - // Chain - return History; - }; + // Chain + return History; + }; - /** + /** * History.queue (item,queue), (func,queue), (func), (item) * Either firs the item now if not busy, or adds it to the queue */ - History.queue = function(item,queue){ - // Prepare - if ( typeof item === 'function' ) { - item = { - callback: item - }; - } - if ( typeof queue !== 'undefined' ) { - item.queue = queue; - } - - // Handle - if ( History.busy() ) { - History.pushQueue(item); - } else { - History.fireQueueItem(item); - } - - // Chain - return History; - }; - - /** + History.queue = function(item, queue){ + // Prepare + if (typeof item === 'function') { + item = { + callback: item, + }; + } + if (typeof queue !== 'undefined') { + item.queue = queue; + } + + // Handle + if (History.busy()) { + History.pushQueue(item); + } else { + History.fireQueueItem(item); + } + + // Chain + return History; + }; + + /** * History.clearQueue() * Clears the Queue */ - History.clearQueue = function(){ - History.busy.flag = false; - History.queues = []; - return History; - }; - + History.clearQueue = function(){ + History.busy.flag = false; + History.queues = []; + return History; + }; - // ==================================================================== - // IE Bug Fix + // ==================================================================== + // IE Bug Fix - /** + /** * History.stateChanged * States whether or not the state has changed since the last double check was initialised */ - History.stateChanged = false; + History.stateChanged = false; - /** + /** * History.doubleChecker * Contains the timeout used for the double checks */ - History.doubleChecker = false; + History.doubleChecker = false; - /** + /** * History.doubleCheckComplete() * Complete a double check * @return {History} */ - History.doubleCheckComplete = function(){ - // Update - History.stateChanged = true; + History.doubleCheckComplete = function(){ + // Update + History.stateChanged = true; - // Clear - History.doubleCheckClear(); + // Clear + History.doubleCheckClear(); - // Chain - return History; - }; + // Chain + return History; + }; - /** + /** * History.doubleCheckClear() * Clear a double check * @return {History} */ - History.doubleCheckClear = function(){ - // Clear - if ( History.doubleChecker ) { - clearTimeout(History.doubleChecker); - History.doubleChecker = false; - } + History.doubleCheckClear = function(){ + // Clear + if (History.doubleChecker) { + clearTimeout(History.doubleChecker); + History.doubleChecker = false; + } - // Chain - return History; - }; + // Chain + return History; + }; - /** + /** * History.doubleCheck() * Create a double check * @return {History} */ - History.doubleCheck = function(tryAgain){ - // Reset - History.stateChanged = false; - History.doubleCheckClear(); - - // Fix IE6,IE7 bug where calling history.back or history.forward does not actually change the hash (whereas doing it manually does) - // Fix Safari 5 bug where sometimes the state does not change: https://bugs.webkit.org/show_bug.cgi?id=42940 - if ( History.bugs.ieDoubleCheck ) { - // Apply Check - History.doubleChecker = setTimeout( - function(){ - History.doubleCheckClear(); - if ( !History.stateChanged ) { - //History.debug('History.doubleCheck: State has not yet changed, trying again', arguments); - // Re-Attempt - tryAgain(); - } - return true; - }, - History.options.doubleCheckInterval - ); - } - - // Chain - return History; - }; - - - // ==================================================================== - // Safari Bug Fix - - /** + History.doubleCheck = function(tryAgain){ + // Reset + History.stateChanged = false; + History.doubleCheckClear(); + + // Fix IE6,IE7 bug where calling history.back or history.forward does not actually change the hash (whereas doing it manually does) + // Fix Safari 5 bug where sometimes the state does not change: https://bugs.webkit.org/show_bug.cgi?id=42940 + if (History.bugs.ieDoubleCheck) { + // Apply Check + History.doubleChecker = setTimeout( + function(){ + History.doubleCheckClear(); + if (!History.stateChanged) { + //History.debug('History.doubleCheck: State has not yet changed, trying again', arguments); + // Re-Attempt + tryAgain(); + } + return true; + }, + History.options.doubleCheckInterval, + ); + } + + // Chain + return History; + }; + + // ==================================================================== + // Safari Bug Fix + + /** * History.safariStatePoll() * Poll the current state * @return {History} */ - History.safariStatePoll = function(){ - // Poll the URL + History.safariStatePoll = function(){ + // Poll the URL - // Get the Last State which has the new URL - var - urlState = History.extractState(History.getLocationHref()), - newState; + // Get the Last State which has the new URL + var + urlState = History.extractState(History.getLocationHref()); + var newState; - // Check for a difference - if ( !History.isLastSavedState(urlState) ) { - newState = urlState; - } - else { - return; - } + // Check for a difference + if (!History.isLastSavedState(urlState)) { + newState = urlState; + } else { + return; + } - // Check if we have a state with that url - // If not create it - if ( !newState ) { - //History.debug('History.safariStatePoll: new'); - newState = History.createStateObject(); - } + // Check if we have a state with that url + // If not create it + if (!newState) { + //History.debug('History.safariStatePoll: new'); + newState = History.createStateObject(); + } - // Apply the New State - //History.debug('History.safariStatePoll: trigger'); - History.Adapter.trigger(window,'popstate'); + // Apply the New State + //History.debug('History.safariStatePoll: trigger'); + History.Adapter.trigger(window, 'popstate'); - // Chain - return History; - }; + // Chain + return History; + }; + // ==================================================================== + // State Aliases - // ==================================================================== - // State Aliases - - /** + /** * History.back(queue) * Send the browser history back one item * @param {Integer} queue [optional] */ - History.back = function(queue){ - //History.debug('History.back: called', arguments); - - // Handle Queueing - if ( queue !== false && History.busy() ) { - // Wait + Push to Queue - //History.debug('History.back: we must wait', arguments); - History.pushQueue({ - scope: History, - callback: History.back, - args: arguments, - queue: queue - }); - return false; - } - - // Make Busy + Continue - History.busy(true); - - // Fix certain browser bugs that prevent the state from changing - History.doubleCheck(function(){ - History.back(false); - }); - - // Go back - history.go(-1); - - // End back closure - return true; - }; - - /** + History.back = function(queue){ + //History.debug('History.back: called', arguments); + + // Handle Queueing + if (queue !== false && History.busy()) { + // Wait + Push to Queue + //History.debug('History.back: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.back, + args: arguments, + queue: queue, + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.back(false); + }); + + // Go back + history.go(-1); + + // End back closure + return true; + }; + + /** * History.forward(queue) * Send the browser history forward one item * @param {Integer} queue [optional] */ - History.forward = function(queue){ - //History.debug('History.forward: called', arguments); - - // Handle Queueing - if ( queue !== false && History.busy() ) { - // Wait + Push to Queue - //History.debug('History.forward: we must wait', arguments); - History.pushQueue({ - scope: History, - callback: History.forward, - args: arguments, - queue: queue - }); - return false; - } - - // Make Busy + Continue - History.busy(true); - - // Fix certain browser bugs that prevent the state from changing - History.doubleCheck(function(){ - History.forward(false); - }); - - // Go forward - history.go(1); - - // End forward closure - return true; - }; - - /** + History.forward = function(queue){ + //History.debug('History.forward: called', arguments); + + // Handle Queueing + if (queue !== false && History.busy()) { + // Wait + Push to Queue + //History.debug('History.forward: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.forward, + args: arguments, + queue: queue, + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.forward(false); + }); + + // Go forward + history.go(1); + + // End forward closure + return true; + }; + + /** * History.go(index,queue) * Send the browser history back or forward index times * @param {Integer} queue [optional] */ - History.go = function(index,queue){ - //History.debug('History.go: called', arguments); - - // Prepare - var i; - - // Handle - if ( index > 0 ) { - // Forward - for ( i=1; i<=index; ++i ) { - History.forward(queue); - } - } - else if ( index < 0 ) { - // Backward - for ( i=-1; i>=index; --i ) { - History.back(queue); - } - } - else { - throw new Error('History.go: History.go requires a positive or negative integer passed.'); - } - - // Chain - return History; - }; - - - // ==================================================================== - // HTML5 State Support - - // Non-Native pushState Implementation - if ( History.emulated.pushState ) { - /* + History.go = function(index, queue){ + //History.debug('History.go: called', arguments); + + // Prepare + var i; + + // Handle + if (index > 0) { + // Forward + for (i = 1; i <= index; ++i) { + History.forward(queue); + } + } else if (index < 0) { + // Backward + for (i = -1; i >= index; --i) { + History.back(queue); + } + } else { + throw new Error('History.go: History.go requires a positive or negative integer passed.'); + } + + // Chain + return History; + }; + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if (History.emulated.pushState) { + /* * Provide Skeleton for HTML4 Browsers */ - // Prepare - var emptyFunction = function(){}; - History.pushState = History.pushState||emptyFunction; - History.replaceState = History.replaceState||emptyFunction; - } // History.emulated.pushState + // Prepare + var emptyFunction = function(){}; + History.pushState = History.pushState || emptyFunction; + History.replaceState = History.replaceState || emptyFunction; + } // History.emulated.pushState - // Native pushState Implementation - else { - /* + // Native pushState Implementation + else { + /* * Use native HTML5 History API Implementation */ - /** + /** * History.onPopState(event,extra) * Refresh the Current State */ - History.onPopState = function(event,extra){ - // Prepare - var stateId = false, newState = false, currentHash, currentState; - - // Reset the double check - History.doubleCheckComplete(); - - // Check for a Hash, and handle apporiatly - currentHash = History.getHash(); - if ( currentHash ) { - // Expand Hash - currentState = History.extractState(currentHash||History.getLocationHref(),true); - if ( currentState ) { - // We were able to parse it, it must be a State! - // Let's forward to replaceState - //History.debug('History.onPopState: state anchor', currentHash, currentState); - History.replaceState(currentState.data, currentState.title, currentState.url, false); - } - else { - // Traditional Anchor - //History.debug('History.onPopState: traditional anchor', currentHash); - History.Adapter.trigger(window,'anchorchange'); - History.busy(false); - } - - // We don't care for hashes - History.expectedStateId = false; - return false; - } - - // Ensure - stateId = History.Adapter.extractEventData('state',event,extra) || false; - - // Fetch State - if ( stateId ) { - // Vanilla: Back/forward button was used - newState = History.getStateById(stateId); - } - else if ( History.expectedStateId ) { - // Vanilla: A new state was pushed, and popstate was called manually - newState = History.getStateById(History.expectedStateId); - } - else { - // Initial State - newState = History.extractState(History.getLocationHref()); - } - - // The State did not exist in our store - if ( !newState ) { - // Regenerate the State - newState = History.createStateObject(null,null,History.getLocationHref()); - } - - // Clean - History.expectedStateId = false; - - // Check if we are the same state - if ( History.isLastSavedState(newState) ) { - // There has been no change (just the page's hash has finally propagated) - //History.debug('History.onPopState: no change', newState, History.savedStates); - History.busy(false); - return false; - } - - // Store the State - History.storeState(newState); - History.saveState(newState); - - // Force update of the title - History.setTitle(newState); - - // Fire Our Event - History.Adapter.trigger(window,'statechange'); - History.busy(false); - - // Return true - return true; - }; - History.Adapter.bind(window,'popstate',History.onPopState); - - /** + History.onPopState = function(event, extra){ + // Prepare + var stateId = false; var newState = false; var currentHash; var currentState; + + // Reset the double check + History.doubleCheckComplete(); + + // Check for a Hash, and handle apporiatly + currentHash = History.getHash(); + if (currentHash) { + // Expand Hash + currentState = History.extractState(currentHash || History.getLocationHref(), true); + if (currentState) { + // We were able to parse it, it must be a State! + // Let's forward to replaceState + //History.debug('History.onPopState: state anchor', currentHash, currentState); + History.replaceState(currentState.data, currentState.title, currentState.url, false); + } else { + // Traditional Anchor + //History.debug('History.onPopState: traditional anchor', currentHash); + History.Adapter.trigger(window, 'anchorchange'); + History.busy(false); + } + + // We don't care for hashes + History.expectedStateId = false; + return false; + } + + // Ensure + stateId = History.Adapter.extractEventData('state', event, extra) || false; + + // Fetch State + if (stateId) { + // Vanilla: Back/forward button was used + newState = History.getStateById(stateId); + } else if (History.expectedStateId) { + // Vanilla: A new state was pushed, and popstate was called manually + newState = History.getStateById(History.expectedStateId); + } else { + // Initial State + newState = History.extractState(History.getLocationHref()); + } + + // The State did not exist in our store + if (!newState) { + // Regenerate the State + newState = History.createStateObject(null, null, History.getLocationHref()); + } + + // Clean + History.expectedStateId = false; + + // Check if we are the same state + if (History.isLastSavedState(newState)) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onPopState: no change', newState, History.savedStates); + History.busy(false); + return false; + } + + // Store the State + History.storeState(newState); + History.saveState(newState); + + // Force update of the title + History.setTitle(newState); + + // Fire Our Event + History.Adapter.trigger(window, 'statechange'); + History.busy(false); + + // Return true + return true; + }; + History.Adapter.bind(window, 'popstate', History.onPopState); + + /** * History.pushState(data,title,url) * Add a new State to the history object, become it, and trigger onpopstate * We have to trigger for HTML4 compatibility @@ -3020,55 +2931,54 @@ if (typeof JSON !== 'object') { * @param {string} url * @return {true} */ - History.pushState = function(data,title,url,queue){ - //History.debug('History.pushState: called', arguments); - - // Check the State - if ( History.getHashByUrl(url) && History.emulated.pushState ) { - throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); - } - - // Handle Queueing - if ( queue !== false && History.busy() ) { - // Wait + Push to Queue - //History.debug('History.pushState: we must wait', arguments); - History.pushQueue({ - scope: History, - callback: History.pushState, - args: arguments, - queue: queue - }); - return false; - } - - // Make Busy + Continue - History.busy(true); - - // Create the newState - var newState = History.createStateObject(data,title,url); - - // Check it - if ( History.isLastSavedState(newState) ) { - // Won't be a change - History.busy(false); - } - else { - // Store the newState - History.storeState(newState); - History.expectedStateId = newState.id; - - // Push the newState - history.pushState(newState.id,newState.title,newState.url); - - // Fire HTML5 Event - History.Adapter.trigger(window,'popstate'); - } - - // End pushState closure - return true; - }; - - /** + History.pushState = function(data, title, url, queue){ + //History.debug('History.pushState: called', arguments); + + // Check the State + if (History.getHashByUrl(url) && History.emulated.pushState) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if (queue !== false && History.busy()) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue, + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data, title, url); + + // Check it + if (History.isLastSavedState(newState)) { + // Won't be a change + History.busy(false); + } else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.pushState(newState.id, newState.title, newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window, 'popstate'); + } + + // End pushState closure + return true; + }; + + /** * History.replaceState(data,title,url) * Replace the State and trigger onpopstate * We have to trigger for HTML4 compatibility @@ -3077,216 +2987,205 @@ if (typeof JSON !== 'object') { * @param {string} url * @return {true} */ - History.replaceState = function(data,title,url,queue){ - //History.debug('History.replaceState: called', arguments); - - // Check the State - if ( History.getHashByUrl(url) && History.emulated.pushState ) { - throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); - } - - // Handle Queueing - if ( queue !== false && History.busy() ) { - // Wait + Push to Queue - //History.debug('History.replaceState: we must wait', arguments); - History.pushQueue({ - scope: History, - callback: History.replaceState, - args: arguments, - queue: queue - }); - return false; - } - - // Make Busy + Continue - History.busy(true); - - // Create the newState - var newState = History.createStateObject(data,title,url); - - // Check it - if ( History.isLastSavedState(newState) ) { - // Won't be a change - History.busy(false); - } - else { - // Store the newState - History.storeState(newState); - History.expectedStateId = newState.id; - - // Push the newState - history.replaceState(newState.id,newState.title,newState.url); - - // Fire HTML5 Event - History.Adapter.trigger(window,'popstate'); - } - - // End replaceState closure - return true; - }; - - } // !History.emulated.pushState - - - // ==================================================================== - // Initialise - - /** + History.replaceState = function(data, title, url, queue){ + //History.debug('History.replaceState: called', arguments); + + // Check the State + if (History.getHashByUrl(url) && History.emulated.pushState) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if (queue !== false && History.busy()) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue, + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data, title, url); + + // Check it + if (History.isLastSavedState(newState)) { + // Won't be a change + History.busy(false); + } else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.replaceState(newState.id, newState.title, newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window, 'popstate'); + } + + // End replaceState closure + return true; + }; + } // !History.emulated.pushState + + // ==================================================================== + // Initialise + + /** * Load the Store */ - if ( sessionStorage ) { - // Fetch - try { - History.store = JSON.parse(sessionStorage.getItem('History.store'))||{}; - } - catch ( err ) { - History.store = {}; - } - - // Normalize - History.normalizeStore(); - } - else { - // Default Load - History.store = {}; - History.normalizeStore(); - } - - /** + if (sessionStorage) { + // Fetch + try { + History.store = JSON.parse(sessionStorage.getItem('History.store')) || {}; + } catch (err) { + History.store = {}; + } + + // Normalize + History.normalizeStore(); + } else { + // Default Load + History.store = {}; + History.normalizeStore(); + } + + /** * Clear Intervals on exit to prevent memory leaks */ - History.Adapter.bind(window,"unload",History.clearAllIntervals); + History.Adapter.bind(window, 'unload', History.clearAllIntervals); - /** + /** * Create the initial State */ - History.saveState(History.storeState(History.extractState(History.getLocationHref(),true))); + History.saveState(History.storeState(History.extractState(History.getLocationHref(), true))); - /** + /** * Bind for Saving Store */ - if ( sessionStorage ) { - // When the page is closed - History.onUnload = function(){ - // Prepare - var currentStore, item, currentStoreString; - - // Fetch - try { - currentStore = JSON.parse(sessionStorage.getItem('History.store'))||{}; - } - catch ( err ) { - currentStore = {}; - } - - // Ensure - currentStore.idToState = currentStore.idToState || {}; - currentStore.urlToId = currentStore.urlToId || {}; - currentStore.stateToId = currentStore.stateToId || {}; - - // Sync - for ( item in History.idToState ) { - if ( !History.idToState.hasOwnProperty(item) ) { - continue; - } - currentStore.idToState[item] = History.idToState[item]; - } - for ( item in History.urlToId ) { - if ( !History.urlToId.hasOwnProperty(item) ) { - continue; - } - currentStore.urlToId[item] = History.urlToId[item]; - } - for ( item in History.stateToId ) { - if ( !History.stateToId.hasOwnProperty(item) ) { - continue; - } - currentStore.stateToId[item] = History.stateToId[item]; - } - - // Update - History.store = currentStore; - History.normalizeStore(); - - // In Safari, going into Private Browsing mode causes the - // Session Storage object to still exist but if you try and use - // or set any property/function of it it throws the exception - // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to - // add something to storage that exceeded the quota." infinitely - // every second. - currentStoreString = JSON.stringify(currentStore); - try { - // Store - sessionStorage.setItem('History.store', currentStoreString); - } - catch (e) { - if (e.code === DOMException.QUOTA_EXCEEDED_ERR) { - if (sessionStorage.length) { - // Workaround for a bug seen on iPads. Sometimes the quota exceeded error comes up and simply - // removing/resetting the storage can work. - sessionStorage.removeItem('History.store'); - sessionStorage.setItem('History.store', currentStoreString); - } else { - // Otherwise, we're probably private browsing in Safari, so we'll ignore the exception. - } - } else { - throw e; - } - } - }; - - // For Internet Explorer - History.intervalList.push(setInterval(History.onUnload,History.options.storeInterval)); - - // For Other Browsers - History.Adapter.bind(window,'beforeunload',History.onUnload); - History.Adapter.bind(window,'unload',History.onUnload); - - // Both are enabled for consistency - } - - // Non-Native pushState Implementation - if ( !History.emulated.pushState ) { - // Be aware, the following is only for native pushState implementations - // If you are wanting to include something for all browsers - // Then include it above this if block - - /** + if (sessionStorage) { + // When the page is closed + History.onUnload = function(){ + // Prepare + var currentStore, item, currentStoreString; + + // Fetch + try { + currentStore = JSON.parse(sessionStorage.getItem('History.store')) || {}; + } catch (err) { + currentStore = {}; + } + + // Ensure + currentStore.idToState = currentStore.idToState || {}; + currentStore.urlToId = currentStore.urlToId || {}; + currentStore.stateToId = currentStore.stateToId || {}; + + // Sync + for (item in History.idToState) { + if (!History.idToState.hasOwnProperty(item)) { + continue; + } + currentStore.idToState[item] = History.idToState[item]; + } + for (item in History.urlToId) { + if (!History.urlToId.hasOwnProperty(item)) { + continue; + } + currentStore.urlToId[item] = History.urlToId[item]; + } + for (item in History.stateToId) { + if (!History.stateToId.hasOwnProperty(item)) { + continue; + } + currentStore.stateToId[item] = History.stateToId[item]; + } + + // Update + History.store = currentStore; + History.normalizeStore(); + + // In Safari, going into Private Browsing mode causes the + // Session Storage object to still exist but if you try and use + // or set any property/function of it it throws the exception + // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to + // add something to storage that exceeded the quota." infinitely + // every second. + currentStoreString = JSON.stringify(currentStore); + try { + // Store + sessionStorage.setItem('History.store', currentStoreString); + } catch (e) { + if (e.code === DOMException.QUOTA_EXCEEDED_ERR) { + if (sessionStorage.length) { + // Workaround for a bug seen on iPads. Sometimes the quota exceeded error comes up and simply + // removing/resetting the storage can work. + sessionStorage.removeItem('History.store'); + sessionStorage.setItem('History.store', currentStoreString); + } else { + // Otherwise, we're probably private browsing in Safari, so we'll ignore the exception. + } + } else { + throw e; + } + } + }; + + // For Internet Explorer + History.intervalList.push(setInterval(History.onUnload, History.options.storeInterval)); + + // For Other Browsers + History.Adapter.bind(window, 'beforeunload', History.onUnload); + History.Adapter.bind(window, 'unload', History.onUnload); + + // Both are enabled for consistency + } + + // Non-Native pushState Implementation + if (!History.emulated.pushState) { + // Be aware, the following is only for native pushState implementations + // If you are wanting to include something for all browsers + // Then include it above this if block + + /** * Setup Safari Fix */ - if ( History.bugs.safariPoll ) { - History.intervalList.push(setInterval(History.safariStatePoll, History.options.safariPollInterval)); - } + if (History.bugs.safariPoll) { + History.intervalList.push(setInterval(History.safariStatePoll, History.options.safariPollInterval)); + } - /** + /** * Ensure Cross Browser Compatibility */ - if ( navigator.vendor === 'Apple Computer, Inc.' || (navigator.appCodeName||'') === 'Mozilla' ) { - /** + if (navigator.vendor === 'Apple Computer, Inc.' || (navigator.appCodeName || '') === 'Mozilla') { + /** * Fix Safari HashChange Issue */ - // Setup Alias - History.Adapter.bind(window,'hashchange',function(){ - History.Adapter.trigger(window,'popstate'); - }); - - // Initialise Alias - if ( History.getHash() ) { - History.Adapter.onDomLoad(function(){ - History.Adapter.trigger(window,'hashchange'); - }); - } - } - - } // !History.emulated.pushState - - - }; // History.initCore - - // Try to Initialise History - if (!History.options || !History.options.delayInit) { - History.init(); - } + // Setup Alias + History.Adapter.bind(window, 'hashchange', function(){ + History.Adapter.trigger(window, 'popstate'); + }); + // Initialise Alias + if (History.getHash()) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window, 'hashchange'); + }); + } + } + } // !History.emulated.pushState + }; // History.initCore + + // Try to Initialise History + if (!History.options || !History.options.delayInit) { + History.init(); + } })(window); diff --git a/src/assets/_project/lib/ext/jquery.jsonp.js b/src/assets/_project/lib/ext/jquery.jsonp.js index 2abeef7d0..3932f1ee0 100644 --- a/src/assets/_project/lib/ext/jquery.jsonp.js +++ b/src/assets/_project/lib/ext/jquery.jsonp.js @@ -8,278 +8,260 @@ * This document is licensed as free software under the terms of the * MIT License: http://www.opensource.org/licenses/mit-license.php */ -( function( $ ) { - - // ###################### UTILITIES ## - - // Noop - function noop() { - } - - // Generic callback - function genericCallback( data ) { - lastValue = [ data ]; - } - - // Call if defined - function callIfDefined( method , object , parameters ) { - return method && method.apply( object.context || object , parameters ); - } - - // Give joining character given url - function qMarkOrAmp( url ) { - return /\?/ .test( url ) ? "&" : "?"; - } - - var // String constants (for better minification) - STR_ASYNC = "async", - STR_CHARSET = "charset", - STR_EMPTY = "", - STR_ERROR = "error", - STR_INSERT_BEFORE = "insertBefore", - STR_JQUERY_JSONP = "_jqjsp", - STR_ON = "on", - STR_ON_CLICK = STR_ON + "click", - STR_ON_ERROR = STR_ON + STR_ERROR, - STR_ON_LOAD = STR_ON + "load", - STR_ON_READY_STATE_CHANGE = STR_ON + "readystatechange", - STR_READY_STATE = "readyState", - STR_REMOVE_CHILD = "removeChild", - STR_SCRIPT_TAG = "