/* jquery.include @version 2.4 @author John Hunter on 2011-03-03 Licence CC-BSD Uses a standard tag with an src value - these are stripped from the dom after loading. Can handle nested includes - linking paths in the include file are modifed to match the host page context. For post-include scripts $(document).includeReady works the same as $(document).ready Based on ideas from hinclude by Mark Nottingham version 2.3 - move from success/error callbacks to use complete due to failure with jQuery 1.5 (fixed in 1.5.1) version 2.4 - allow include tags to use 'src' or 'data-src' attr */ (function($) { var maxRegression = 20, tagName = 'span', incSelect = tagName +'[src],'+ tagName +'[data-src]', ieParseDelay = 30, keepIncludeTags = false, rewritePaths = true; function parse (domNode) { if (maxRegression-- < 1) return this; // remove include tags and fire ready event if ($(incSelect).length === 0) { $(tagName +'.include-loaded')[keepIncludeTags ? 'show' : 'unwrap'](); $(document).trigger('includeReady'); return this; } // load and parse include $(incSelect, domNode).each(function () { var inc = $(this), src = inc.attr('src') || inc.attr('data-src'), path; if (src) { path = src.split('/').slice(0, -1).join('/') + '/'; try { $.ajax({ type: "GET", url: src, complete: function (xhr, status) { if (status === 'error' || !xhr.responseText) { handleError(inc); } else { var data = xhr.responseText; if (rewritePaths) { data = pathRewrite(data, path); } inc.html(data). addClass('include-loaded'). removeAttrs(['src','data-src']); setTimeout(function () { parse(inc.get(0)); }, ieParseDelay); } } }); } catch(e) { handleError(inc, src); } } }); return this; } function pathRewrite (html, path) { // modify any relative paths return html.replace(/(\b(?:src|href)=")([^"]+")/g, function () { var s = arguments; if (/^http(s{0,1}):\/{2}|^\//.test(s[2])) { return s[1] + s[2]; } return s[1] + path + s[2]; }); } function handleError (inc, src) { if (window.console && console.warn) { console.warn('Unable to load ', src); } setTimeout(function () { inc.removeAttrs(['src','data-src']); parse(inc.get(0)); }, ieParseDelay); }; // create the custom event $.fn.includeReady = function (observerFn) { $(document).bind('includeReady', function(event) { observerFn(event); }); return this; }; $.fn.unwrap = function () { return this.each(function () { var el = $(this); el.replaceWith(el.contents()); }); }; $.fn.removeAttrs = function (list) { for (var i = list.length; i--; ) { this.removeAttr(list[i]); } }; $(document).ready(function() { parse(document); }); })(jQuery);