(function ($) { "use strict"; /** * RoyalSlider HashChange Module * @version 1.0.0 * * RoyalSlider Deep Linking Module v .1.0.6 Copyright 2011-2013, Dmitry Semenov; * jQuery hashchange plugin v1.3 Copyright (c) 2010 Ben Alman: */ $.extend($.rsProto, { _initHashChange: function () { var self = this, isBlocked, hashTimeout, hashChangeTimeout; self._hashDefaults = { enabled: false, change: false, map: undefined, // slideId => slideNum prefix: '' }; self.st.hashchange = $.extend({}, self._hashDefaults, self.st.hashchange); if (self.st.hashchange.enabled) { var changeHash = self.st.hashchange.change, prefix = '#' + self.st.hashchange.prefix, idMap = self.st.hashchange.map, getIdByHash = function () { var hash = window.location.hash; if (hash) { hash = parseInt(hash.substring(prefix.length), 10); if (idMap !== undefined) { if (hash in idMap) { hash = +idMap[hash]; } } else { --hash; } if (hash >= 0) { return hash; } } return -1; }; var id = getIdByHash(); if (id !== -1) { self.st.startSlideId = id; } if (changeHash) { $(window).on('hashchange' + self.ns, function (e) { if (!isBlocked) { var id = getIdByHash(); if (id < 0) { return; } if (id > self.numSlides - 1) id = self.numSlides - 1; self.goTo(id); } }); self.ev.on('rsBeforeAnimStart', function () { if (hashTimeout) { clearTimeout(hashTimeout); } if (hashChangeTimeout) { clearTimeout(hashChangeTimeout); } }); self.ev.on('rsAfterSlideChange', function () { if (hashTimeout) { clearTimeout(hashTimeout); } if (hashChangeTimeout) { clearTimeout(hashChangeTimeout); } hashChangeTimeout = setTimeout(function () { isBlocked = true; var hashIndex = 1; if (self.st.hashchange.map === undefined) { hashIndex = self.currSlideId + 1; } else { for (var i in self.st.hashchange.map) { if (self.st.hashchange.map[i] == self.currSlideId) { hashIndex = i; break; } } } window.location.replace(('' + window.location).split('#')[0] + prefix + hashIndex); hashTimeout = setTimeout(function () { isBlocked = false; hashTimeout = null; }, 60); }, 400); }); } self.ev.on('rsBeforeDestroy', function () { hashChangeTimeout = null; hashTimeout = null; if (changeHash) { $(window).off('hashchange' + self.ns); } }); } } }); $.rsModules.hashchange = $.rsProto._initHashChange; })(jQuery); /*! * jQuery hashchange event - v1.3 - 7/21/2010 * http://benalman.com/projects/jquery-hashchange-plugin/ * * Copyright (c) 2010 "Cowboy" Ben Alman * Dual licensed under the MIT and GPL licenses. * http://benalman.com/about/license/ */ (function ($, window, undefined) { '$:nomunge'; // Used by YUI compressor. // Reused string. var str_hashchange = 'hashchange', // Method / object references. doc = document, fake_onhashchange, special = $.event.special, // Does the browser support window.onhashchange? Note that IE8 running in // IE7 compatibility mode reports true for 'onhashchange' in window, even // though the event isn't supported, so also test document.documentMode. doc_mode = doc.documentMode, supports_onhashchange = 'on' + str_hashchange in window && ( doc_mode === undefined || doc_mode > 7 ); // Get location.hash (or what you'd expect location.hash to be) sans any // leading #. Thanks for making this necessary, Firefox! function get_fragment(url) { url = url || location.href; return '#' + url.replace(/^[^#]*#?(.*)$/, '$1'); }; $.fn[ str_hashchange ] = function (fn) { return fn ? this.bind(str_hashchange, fn) : this.trigger(str_hashchange); }; $.fn[ str_hashchange ].delay = 100; special[ str_hashchange ] = $.extend(special[ str_hashchange ], { // Called only when the first 'hashchange' event is bound to window. setup: function () { // If window.onhashchange is supported natively, there's nothing to do.. if (supports_onhashchange) { return false; } // Otherwise, we need to create our own. And we don't want to call this // until the user binds to the event, just in case they never do, since it // will create a polling loop and possibly even a hidden Iframe. $(fake_onhashchange.start); }, // Called only when the last 'hashchange' event is unbound from window. teardown: function () { // If window.onhashchange is supported natively, there's nothing to do.. if (supports_onhashchange) { return false; } // Otherwise, we need to stop ours (if possible). $(fake_onhashchange.stop); } }); // fake_onhashchange does all the work of triggering the window.onhashchange // event for browsers that don't natively support it, including creating a // polling loop to watch for hash changes and in IE 6/7 creating a hidden // Iframe to enable back and forward. fake_onhashchange = (function () { var self = {}, timeout_id, // Remember the initial hash so it doesn't get triggered immediately. last_hash = get_fragment(), fn_retval = function (val) { return val; }, history_set = fn_retval, history_get = fn_retval; // Start the polling loop. self.start = function () { timeout_id || poll(); }; // Stop the polling loop. self.stop = function () { timeout_id && clearTimeout(timeout_id); timeout_id = undefined; }; // This polling loop checks every $.fn.hashchange.delay milliseconds to see // if location.hash has changed, and triggers the 'hashchange' event on // window when necessary. function poll() { var hash = get_fragment(), history_hash = history_get(last_hash); if (hash !== last_hash) { history_set(last_hash = hash, history_hash); $(window).trigger(str_hashchange); } else if (history_hash !== last_hash) { location.href = location.href.replace(/#.*/, '') + history_hash; } timeout_id = setTimeout(poll, $.fn[ str_hashchange ].delay); }; window.attachEvent && !window.addEventListener && !supports_onhashchange && (function () { // Not only do IE6/7 need the "magical" Iframe treatment, but so does IE8 // when running in "IE7 compatibility" mode. var iframe, iframe_src; // When the event is bound and polling starts in IE 6/7, create a hidden // Iframe for history handling. self.start = function () { if (!iframe) { iframe_src = $.fn[ str_hashchange ].src; iframe_src = iframe_src && iframe_src + get_fragment(); // Create hidden Iframe. Attempt to make Iframe as hidden as possible // by using techniques from http://www.paciellogroup.com/blog/?p=604. iframe = $('