diff --git a/jquery.djax.js b/jquery.djax.js index 6529c15..be97983 100644 --- a/jquery.djax.js +++ b/jquery.djax.js @@ -1,25 +1,25 @@ /* -* jQuery djax -* -* @version v0.122 -* -* Copyright 2012, Brian Zeligson -* Released under the MIT license. -* http://www.opensource.org/licenses/mit-license.php -* -* Homepage: -* http://beezee.github.com/djax.html -* -* Authors: -* Brian Zeligson -* -* Contributors: -* Gary Jones @GaryJones -* -* Maintainer: -* Brian Zeligson github @beezee -* -*/ + * jQuery djax + * + * @version v0.122 + * + * Copyright 2012, Brian Zeligson + * Released under the MIT license. + * http://www.opensource.org/licenses/mit-license.php + * + * Homepage: + * http://beezee.github.com/djax.html + * + * Authors: + * Brian Zeligson + * + * Contributors: + * Gary Jones @GaryJones + * + * Maintainer: + * Brian Zeligson github @beezee + * + */ /*jslint browser: true, indent: 4, maxerr: 50, sub: true */ /*jshint bitwise:true, curly:true, eqeqeq:true, forin:true, immed:true, latedef:true, noarg:true, noempty:true, nomen:true, nonew:true, onevar:true, plusplus:true, regexp:true, smarttabs:true, strict:true, trailing:true, undef:true, white:true, browser:true, jquery:true, indent:4, maxerr:50, */ @@ -33,205 +33,255 @@ // http://closure-compiler.appspot.com/home (function ($, exports) { - 'use strict'; - - $.fn.djax = function (selector, exceptions, replaceBlockWithFunc) { - - // If browser doesn't support pushState, abort now - if (!history.pushState) { - return $(this); - } - - var self = this, - blockSelector = selector, - excludes = (exceptions && exceptions.length) ? exceptions : [], - replaceBlockWith = (replaceBlockWithFunc) ? replaceBlockWithFunc : $.fn.replaceWith, - djaxing = false; - - // Ensure that the history is correct when going from 2nd page to 1st - window.history.replaceState( - { - 'url' : window.location.href, - 'title' : $('title').text() - }, - $('title').text(), - window.location.href - ); + 'use strict'; + + $.fn.djax = function (selector, exceptions, replaceBlockWithFunc) { + + // If browser doesn't support pushState, abort now + if (!history.pushState) { + return $(this); + } + + var self = this, + blockSelector = selector, + excludes = (exceptions && exceptions.length) ? exceptions : [], + replaceBlockWith = (replaceBlockWithFunc) ? replaceBlockWithFunc : $.fn.replaceWith, + djaxing = false; + + // Ensure that the history is correct when going from 2nd page to 1st + window.history.replaceState( + { + 'url' : window.location.href, + 'title' : $('title').text() + }, + $('title').text(), + window.location.href + ); - self.clearDjaxing = function() { - self.djaxing = false; - } - - // Exclude the link exceptions - self.attachClick = function (element, event) { - - var link = $(element), - exception = false; - - $.each(excludes, function (index, exclusion) { - if (link.attr('href').indexOf(exclusion) !== -1) { - exception = true; - } - if (window.location.href.indexOf(exclusion) !== -1) { - exception = true; - } - }); - - // If the link is one of the exceptions, return early so that - // the link can be clicked and a full page load as normal - if (exception) { - return $(element); - } - - // From this point on, we handle the behaviour - event.preventDefault(); - - // If we're already doing djaxing, return now and silently fail - if (self.djaxing) { - setTimeout(self.clearDjaxing, 1000); - return $(element); - } - - $(window).trigger('djaxClick', [element]); - self.reqUrl = link.attr('href'); - self.triggered = false; - self.navigate(link.attr('href'), true); - }; - - // Handle the navigation - self.navigate = function (url, add) { - - var blocks = $(blockSelector); - - self.djaxing = true; - - // Get the new page - $(window).trigger( - 'djaxLoading', - [{ - 'url' : url - }] - ); - - var replaceBlocks = function (response) { - if (url !== self.reqUrl) { - self.navigate(self.reqUrl, false); - return true; - } - - var result = $(response), - newBlocks = $(result).find(blockSelector); - - if (add) { - window.history.pushState( - { - 'url' : url, - 'title' : $(result).filter('title').text() - }, - $(result).filter('title').text(), - url - ); - } - - // Set page title as new page title - $('title').text($(result).filter('title').text()); - - // Loop through each block and find new page equivalent - blocks.each(function () { - - var id = '#' + $(this).attr('id'), - newBlock = newBlocks.filter(id), - block = $(this); + self.clearDjaxing = function() { + self.djaxing = false; + } + + // Exclude the link exceptions + self.attachClick = function (element, event) { + + var link = $(element), + exception = false; + + $.each(excludes, function (index, exclusion) { + if (link.attr('href').indexOf(exclusion) !== -1) { + exception = true; + } + if (window.location.href.indexOf(exclusion) !== -1) { + exception = true; + } + }); + + // If the link is one of the exceptions, return early so that + // the link can be clicked and a full page load as normal + if (exception) { + return $(element); + } + + // From this point on, we handle the behaviour + event.preventDefault(); + + // If we're already doing djaxing, return now and silently fail + if (self.djaxing) { + setTimeout(self.clearDjaxing, 1000); + return $(element); + } + + $(window).trigger('djaxClick', [element]); + self.reqUrl = link.attr('href'); + self.triggered = false; + self.navigate(link.attr('href'), true); + }; + + // Handle the navigation + self.navigate = function (url, add) { + + var blocks = $(blockSelector); + + self.djaxing = true; + + // Get the new page + $(window).trigger( + 'djaxLoading', + [{ + 'url' : url + }] + ); + + var replaceBlocks = function (response) { + if (url !== self.reqUrl) { + self.navigate(self.reqUrl, false); + return true; + } + + var result = $(response), + newBlocks = $(result).find(blockSelector); + + + if (add) { + window.history.pushState( + { + 'url' : url, + 'title' : $(result).filter('title').text() + }, + $(result).filter('title').text(), + url + ); + } + + // Set page title as new page title + $('title').text($(result).filter('title').text()); + + //Remove element not done by other removes + $('.datepicker').remove(); + + var newStyle = $(result).filter('style'+blockSelector).text(); + if($('style'+blockSelector).length) + { + $('style'+blockSelector).remove(); + } + + //Get all styles to add to the new page + var head = document.getElementsByTagName('head')[0]; + var newStyles = $(result).filter('style'+blockSelector); + $.each(newStyles, function () { + var newStyle = $(this).text(); + var style = document.createElement('style'); + + style.type = 'text/css'; + style.className = blockSelector.replace('.', ''); + if (style.styleSheet){ + style.styleSheet.cssText = newStyle; + } else { + style.appendChild(document.createTextNode(newStyle)); + } + + head.appendChild(style); + }); + + + // Loop through each block and find new page equivalent + blocks.each(function () { + + var id = '#' + $(this).attr('id'), + newBlock = newBlocks.filter(id), + block = $(this); - $('a', newBlock).filter(function () { - return this.hostname === location.hostname; - }).addClass('dJAX_internal').on('click', function (event) { - return self.attachClick(this, event); - }); + $('a', newBlock).filter(function () { + return this.hostname === location.hostname; + }).addClass('dJAX_internal').on('click', function (event) { + return self.attachClick(this, event); + }); - if (newBlock.length) { - if (block.html() !== newBlock.html()) { - replaceBlockWith.call(block, newBlock); - } - } else { - block.remove(); - } - - }); - - // Loop through new page blocks and add in as needed - $.each(newBlocks, function () { - - var newBlock = $(this), - id = '#' + $(this).attr('id'), - $previousSibling; - - // If there is a new page block without an equivalent block - // in the old page, we need to find out where to insert it - if (!$(id).length) { - - // Find the previous sibling - $previousSibling = $(result).find(id).prev(); - - if ($previousSibling.length) { - // Insert after the previous element - newBlock.insertAfter('#' + $previousSibling.attr('id')); - } else { - // There's no previous sibling, so prepend to parent instead - newBlock.prependTo('#' + newBlock.parent().attr('id')); - } - } - - // Only add a class to internal links - $('a', newBlock).filter(function () { - return this.hostname === location.hostname; - }).addClass('dJAX_internal').on('click', function (event) { - return self.attachClick(this, event); - }); - - }); - - - - // Trigger djaxLoad event as a pseudo ready() - if (!self.triggered) { - $(window).trigger( - 'djaxLoad', - [{ - 'url' : url, - 'title' : $(result).filter('title').text(), - 'response' : response - }] - ); - self.triggered = true; - self.djaxing = false; - } - }; - $.get(url, function (response) { - replaceBlocks(response); - }).error(function (response) { - // handle error - console.log('error', response); - replaceBlocks(response['responseText']); - }); - }; /* End self.navigate */ - - // Only add a class to internal links - $(this).find('a').filter(function () { - return this.hostname === location.hostname; - }).addClass('dJAX_internal').on('click', function (event) { - return self.attachClick(this, event); - }); - - // On new page load - $(window).bind('popstate', function (event) { - self.triggered = false; - if (event.originalEvent.state) { - self.reqUrl = event.originalEvent.state.url; - self.navigate(event.originalEvent.state.url, false); - } - }); - - }; - -}(jQuery, window)); \ No newline at end of file + if (newBlock.length) { + if (block.html() !== newBlock.html()) { + replaceBlockWith.call(block, newBlock); + } + } else { + + block.remove(); + + } + + }); + + // Loop through new page blocks and add in as needed + $.each(newBlocks, function () { + + var newBlock = $(this), + id = '#' + $(this).attr('id'), + $previousSibling; + + // If there is a new page block without an equivalent block + // in the old page, we need to find out where to insert it + if (!$(id).length) { + + // Find the previous sibling + $previousSibling = $(result).find(id).prev(); + + if ($previousSibling.length) { + // Insert after the previous element + newBlock.insertAfter('#' + $previousSibling.attr('id')); + } else { + // There's no previous sibling, so prepend to parent instead + newBlock.prependTo('#' + newBlock.parent().attr('id')); + } + } + + // Only add a class to internal links + $('a', newBlock).filter(function () { + return this.hostname === location.hostname; + }).addClass('dJAX_internal').on('click', function (event) { + return self.attachClick(this, event); + }); + + }); + + //Get old scripts and remove them from the dom (tidiness more than anything) + var oldScripts = $('script'+blockSelector); + $.each(oldScripts, function () { + $(this).remove(); + }); + + //Get all scripts to add to the new page + var newScripts = $(result).filter('script'+blockSelector); + $.each(newScripts, function () { + var newScript = $(this).text(); + + //console.log('error', newScript); //Debugging yo + //Create new script element and add it to the DOM corrently, that way it is executed :D + var script = document.createElement("script"); + script.type = "text/javascript"; + script.text = newScript; // use this for inline script + script.className = blockSelector.replace('.', ''); + document.body.appendChild(script); + }); + + + // Trigger djaxLoad event as a pseudo ready() + if (!self.triggered) { + $(window).trigger( + 'djaxLoad', + [{ + 'url' : url, + 'title' : $(result).filter('title').text(), + 'response' : response + }] + ); + self.triggered = true; + self.djaxing = false; + } + }; + $.get(url, function (response) { + replaceBlocks(response); + }).error(function (response) { + // handle error + console.log('error', response); + replaceBlocks(response['responseText']); + }); + }; /* End self.navigate */ + + // Only add a class to internal links + $(this).find('a').filter(function () { + return this.hostname === location.hostname; + }).addClass('dJAX_internal').on('click', function (event) { + return self.attachClick(this, event); + }); + + // On new page load + $(window).bind('popstate', function (event) { + self.triggered = false; + if (event.originalEvent.state) { + self.reqUrl = event.originalEvent.state.url; + self.navigate(event.originalEvent.state.url, false); + } + }); + + }; + +}(jQuery, window));