/*! * @name jQuery.history v1.1.0 * @author yeikos * @repository https://github.com/yeikos/jquery.history * @dependencies jQuery 1.7.0+ * Copyright 2013 yeikos - MIT license * https://raw.github.com/yeikos/js.merge/master/LICENSE */ ;(function($, undefined) { var Public = function(url) { var event = $.Event('push'); Public.context.trigger(event, [url, _type]); if (event.isDefaultPrevented()) return Public; // Establecemos la nueva dirección siempre y cuando haya cambiado if (_type === 'pathname') { if (_last !== url) window.history.pushState({}, null, _last = url); } else if (_type === 'hash') { if (_last !== url) { location.hash = _last = url; // Si se trata de IE6/IE7 if (_ie67) { // El `iframe` ha de encontrarse en el documento if (!$('#jQueryHistory').length) throw new Error('jQuery.' + publicName + '.push: iframe not found.'); // Si es la primera vez if (_firstTime) { _firstTime = 0; // Añadimos primero al historial una entrada vacía para que el usuario // pueda volver al inicio de página, de lo contrario saldrá fuera de ella _iframe.contentWindow.document.open().close(); _iframe.contentWindow.location.hash = '/'; } // Cambiamos la dirección del `iframe` para simular el historial _iframe.contentWindow.document.open().close(); _iframe.contentWindow.location.hash = url; } } } else { // Es necesario que se haya iniciado una escucha activa para establecer una dirección throw new Error('jQuery.' + publicName + '.push: the listening is not active.'); } Public.context.trigger('pushed', [url, _type]); return Public; }, publicName = 'history'; // Contexto donde se centralizan los eventos (`load`, `change`, `push`, `pushed`) Public.context = $({}); // Accesos directos a los métodos `on`, `off` y `trigger` $.each(['on', 'off', 'trigger'], function(index, method) { Public[method] = function() { Public.context[method].apply(Public.context, arguments); return Public; }; }); // Acceso directo a la función principal Public.push = Public; // Obtiene el tipo de escucha actual (`pathname`, `hash`, `null`) Public.type = function() { return _type; }; // Obtiene la dirección actual según el tipo de escucha Public.url = function(_location) { _location = _location || location; if (_type === null) throw new Error ('jQuery.' + publicName + '.url: the listening has not started.'); if (_type === 'pathname') return _location.pathname + _location.search + _location.hash; if (_location.hash.length > 1) { spl = _location.href.split('#'); spl.shift(); spl = spl.join('#'); return spl; } return ''; }; // Inicializa una escucha en el documento para intervenir los cambios del historial y poder establecer direcciones Public.listen = function(type, interval) { // Desactivamos posibles escuchas anteriores Public.unlisten(); var size = arguments.length; // Detección automática del modo de escucha if (!size || type === 'auto') { type = _pushState ? 'pathname' : 'hash'; size = 1; } else if (type !== 'pathname' && type !== 'hash') { throw new Error('jQuery.' + publicName + '.listen: type is not valid.'); } // Si el modo de escucha es `hash` if (type === 'hash') { // Si no hay soporte para `onhaschange` y no se especificó un intervalo, o el intervalo es `true` if ((!_onhashchange && size === 1) || interval === true) { // Establecemos el intervalo de la configuración interval = Public.config.interval; size = 2; } // Si el intervalo fue fijado comprobamos si su valor es correcto if (size === 2 && (isNaN(interval) || interval < 1)) throw new Error('jQuery.' + publicName + '.listen: interval delay is not valid.'); } // Si el modo de escucha es `pathname` if ((_type = type) === 'pathname') { // Ha de haber soporte nativo if (!_pushState) throw new Error('jQuery.' + publicName + '.listen: this browser has not support to pushState.'); // Cuando haya un cambio en la dirección URL $(window).on('popstate.history', function(event) { // Si se trata de un evento real originado internamente por el navegador // y la dirección ha cambiado emitimos el evento `change` if (event.originalEvent && event.originalEvent.state && _last !== location.pathname) Public.trigger('change', [_last = Public.url(), 'pathname']); }); if (location.pathname.length > 1) Public.trigger('load', [Public.url(), 'pathname']); } else { // Si hay soporte nativo de `onhashchange` y no se especificó el argumento intervalo if (_onhashchange && !interval) { // Hacemos uso del evento nativo `hashchange` $(window).on('hashchange.history', function(event) { var hash = Public.url(); if (_last !== hash) Public.trigger('change', [_last = hash, 'hash']); }); // Si no hay soporte o simplemente se especificó el argumento intervalo } else { // Si no se ha detecto si el navegador es IE6/IE7 if (_ie67 === undefined) // Realizamos la comprobación una sola vez _ie67 = Public.ieCondition('lte IE 7'); // Si se trata de IE6/IE7 if (_ie67) { // Es necesario que se encuentre disponible `body` (dom ready) if (!(size = $('body')).length) throw new Error('jQuery.' + publicName + '.listen: document is not ready.'); // Creamos un `iframe` con el que emular el historial _iframe = $('