/* Copyright (c) 2007 Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net) * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)  * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. * * Version: 1.0.2 * Requires jQuery 1.1.3+ * Docs: http://docs.jquery.com/Plugins/livequery */(function($) {$.extend($.fn, {livequery: function(type, fn, fn2) {var self = this, q;// Handle different call patternsif ($.isFunction(type))fn2 = fn, fn = type, type = undefined;// See if Live Query already exists$.each( $.livequery.queries, function(i, query) {if ( self.selector == query.selector && self.context == query.context &&type == query.type && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) )// Found the query, exit the each loopreturn (q = query) && false;});// Create new Live Query if it wasn't foundq = q || new $.livequery(this.selector, this.context, type, fn, fn2);// Make sure it is runningq.stopped = false;// Run it$.livequery.run( q.id );// Contnue the chainreturn this;},expire: function(type, fn, fn2) {var self = this;// Handle different call patternsif ($.isFunction(type))fn2 = fn, fn = type, type = undefined;// Find the Live Query based on arguments and stop it$.each( $.livequery.queries, function(i, query) {if ( self.selector == query.selector && self.context == query.context && (!type || type == query.type) && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) && !this.stopped )$.livequery.stop(query.id);});// Continue the chainreturn this;}});$.livequery = function(selector, context, type, fn, fn2) {this.selector = selector;this.context  = context || document;this.type     = type;this.fn       = fn;this.fn2      = fn2;this.elements = [];this.stopped  = false;// The id is the index of the Live Query in $.livequery.queriesthis.id = $.livequery.queries.push(this)-1;// Mark the functions for matching later onfn.$lqguid = fn.$lqguid || $.livequery.guid++;if (fn2) fn2.$lqguid = fn2.$lqguid || $.livequery.guid++;// Return the Live Queryreturn this;};$.livequery.prototype = {stop: function() {var query = this;if ( this.type )// Unbind all bound eventsthis.elements.unbind(this.type, this.fn);else if (this.fn2)// Call the second function for all matched elementsthis.elements.each(function(i, el) {query.fn2.apply(el);});// Clear out matched elementsthis.elements = [];// Stop the Live Query from running until restartedthis.stopped = true;},run: function() {// Short-circuit if stoppedif ( this.stopped ) return;var query = this;var oEls = this.elements,els  = $(this.selector, this.context),nEls = els.not(oEls);// Set elements to the latest set of matched elementsthis.elements = els;if (this.type) {// Bind events to newly matched elementsnEls.bind(this.type, this.fn);// Unbind events to elements no longer matchedif (oEls.length > 0)$.each(oEls, function(i, el) {if ( $.inArray(el, els) < 0 )$.event.remove(el, query.type, query.fn);});}else {// Call the first function for newly matched elementsnEls.each(function() {query.fn.apply(this);});// Call the second function for elements no longer matchedif ( this.fn2 && oEls.length > 0 )$.each(oEls, function(i, el) {if ( $.inArray(el, els) < 0 )query.fn2.apply(el);});}}};$.extend($.livequery, {guid: 0,queries: [],queue: [],running: false,timeout: null,checkQueue: function() {if ( $.livequery.running && $.livequery.queue.length ) {var length = $.livequery.queue.length;// Run each Live Query currently in the queuewhile ( length-- )$.livequery.queries[ $.livequery.queue.shift() ].run();}},pause: function() {// Don't run anymore Live Queries until restarted$.livequery.running = false;},play: function() {// Restart Live Queries$.livequery.running = true;// Request a run of the Live Queries$.livequery.run();},registerPlugin: function() {$.each( arguments, function(i,n) {// Short-circuit if the method doesn't existif (!$.fn[n]) return;// Save a reference to the original methodvar old = $.fn[n];// Create a new method$.fn[n] = function() {// Call the original methodvar r = old.apply(this, arguments);// Request a run of the Live Queries$.livequery.run();// Return the original methods resultreturn r;}});},run: function(id) {if (id != undefined) {// Put the particular Live Query in the queue if it doesn't already existif ( $.inArray(id, $.livequery.queue) < 0 )$.livequery.queue.push( id );}else// Put each Live Query in the queue if it doesn't already exist$.each( $.livequery.queries, function(id) {if ( $.inArray(id, $.livequery.queue) < 0 )$.livequery.queue.push( id );});// Clear timeout if it already existsif ($.livequery.timeout) clearTimeout($.livequery.timeout);// Create a timeout to check the queue and actually run the Live Queries$.livequery.timeout = setTimeout($.livequery.checkQueue, 20);},stop: function(id) {if (id != undefined)// Stop are particular Live Query$.livequery.queries[ id ].stop();else// Stop all Live Queries$.each( $.livequery.queries, function(id) {$.livequery.queries[ id ].stop();});}});// Register core DOM manipulation methods$.livequery.registerPlugin('append', 'prepend', 'after', 'before', 'wrap', 'attr', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove');// Run Live Queries when the Document is ready$(function() { $.livequery.play(); });// Save a reference to the original init methodvar init = $.prototype.init;// Create a new init method that exposes two new properties: selector and context$.prototype.init = function(a,c) {// Call the original init and save the resultvar r = init.apply(this, arguments);// Copy over properties if they exist alreadyif (a && a.selector)r.context = a.context, r.selector = a.selector;// Set propertiesif ( typeof a == 'string' )r.context = c || document, r.selector = a;// Return the resultreturn r;};// Give the init function the jQuery prototype for later instantiation (needed after Rev 4091)$.prototype.init.prototype = $.prototype;})(jQuery);