silverstripe-framework/thirdparty/jquery-live-extension/live-extension.js

239 lines
5.6 KiB
JavaScript
Raw Normal View History

/**
* @author Alexander Farkas
* @ version 1.05
*/
(function($){
function getFnIndex(args){
var ret = 2;
$.each(args, function(i, data){
if($.isFunction(data)){
ret = i;
return false;
}
});
return ret;
}
(function(){
var contains = document.compareDocumentPosition ? function(a, b){
return a.compareDocumentPosition(b) & 16;
} : function(a, b){
return a !== b && (a.contains ? a.contains(b) : true);
},
oldLive = $.fn.live,
oldDie = $.fn.die;
function createEnterLeaveFn(fn, type){
return jQuery.event.proxy(fn, function(e) {
if( this !== e.relatedTarget && e.relatedTarget && !contains(this, e.relatedTarget) ){
e.type = type;
fn.apply(this, arguments);
}
});
}
var enterLeaveTypes = {
mouseenter: 'mouseover',
mouseleave: 'mouseout'
};
$.fn.live = function(types){
var that = this,
args = arguments,
fnIndex = getFnIndex(args),
fn = args[fnIndex];
$.each(types.split(' '), function(i, type){
var proxy = fn;
if(enterLeaveTypes[type]){
proxy = createEnterLeaveFn(proxy, type);
type = enterLeaveTypes[type];
}
args[0] = type;
args[fnIndex] = proxy;
oldLive.apply(that, args);
});
return this;
};
$.fn.die = function(type, fn){
if(/mouseenter|mouseleave/.test(type)){
if(type == 'mouseenter'){
type = type.replace(/mouseenter/g, 'mouseover');
}
if(type == 'mouseleave') {
type = type.replace(/mouseleave/g, 'mouseout');
}
}
oldDie.call(this, type, fn);
return this;
};
function createBubbleFn(fn, selector, context){
return jQuery.event.proxy(fn, function(e) {
var parent = this.parentNode,
stop = (enterLeaveTypes[e.type]) ? e.relatedTarget : undefined;
fn.apply(this, arguments);
while(parent && parent !== context && parent !== e.relatedTarget){
if($.multiFilter( selector, [parent] )[0]){
fn.apply(parent, arguments);
}
parent = parent.parentNode;
}
});
}
$.fn.bubbleLive = function(){
var args = arguments,
fnIndex = getFnIndex(args);
args[fnIndex] = createBubbleFn(args[fnIndex], this.selector, this.context);
$.fn.live.apply(this, args);
};
$.fn.liveHover = function(enter, out){
return this.live('mouseenter', enter)
.live('mouseleave', out);
};
})();
(function(){
$.support.bubblingChange = !($.browser.msie || $.browser.safari);
if(!$.support.bubblingChange){
var oldLive = $.fn.live,
oldDie = $.fn.die;
function detectChange(fn){
return $.event.proxy(fn, function(e){
var jElm = $(e.target);
if ((e.type !== 'keydown' || e.keyCode === 13) && jElm.is('input, textarea, select')) {
var oldData = jElm.data('changeVal'),
isRadioCheckbox = jElm.is(':checkbox, :radio'),
nowData;
if(isRadioCheckbox && jElm.is(':enabled') && e.type === 'click'){
nowData = jElm.is(':checked');
if((e.target.type !== 'radio' || nowData === true) && e.type !== 'change' && oldData !== nowData){
e.type = 'change';
jElm.trigger(e);
}
} else if (!isRadioCheckbox) {
nowData = jElm.val();
if(oldData !== undefined && oldData !== nowData){
e.type = 'change';
jElm.trigger(e);
}
}
if(nowData !== undefined){
jElm.data('changeVal', nowData);
}
}
});
}
function createChangeProxy(fn){
return $.event.proxy(fn, function(e){
if(e.type === 'change'){
var jElm = $(e.target),
nowData = (jElm.is(':checkbox, :radio')) ? jElm.is(':checked') : jElm.val();
if(nowData === jElm.data('changeVal')){
return false;
}
jElm.data('changeVal', nowData);
}
fn.apply(this, arguments);
});
}
$.fn.live = function(type, fn){
var that = this,
args = arguments,
fnIndex = getFnIndex(args),
proxy = args[fnIndex];
if(type.indexOf('change') != -1){
$(this.context)
.bind('click focusin focusout keydown', detectChange(proxy));
proxy = createChangeProxy(proxy);
}
args[fnIndex] = proxy;
oldLive.apply(that, args);
return this;
};
$.fn.die = function(type, fn){
if(type.indexOf('change') != -1){
$(this.context)
.unbind('click focusin focusout keydown', fn);
}
oldDie.apply(this, arguments);
return this;
};
}
})();
/**
* Copyright (c) 2007 Jörn Zaefferer
*/
(function(){
$.support.focusInOut = !!($.browser.msie);
if (!$.support.focusInOut) {
$.each({
focus: 'focusin',
blur: 'focusout'
}, function(original, fix){
$.event.special[fix] = {
setup: function(){
if (!this.addEventListener) {
return false;
}
this.addEventListener(original, $.event.special[fix].handler, true);
},
teardown: function(){
if (!this.removeEventListener) {
return false;
}
this.removeEventListener(original, $.event.special[fix].handler, true);
},
handler: function(e){
arguments[0] = $.event.fix(e);
arguments[0].type = fix;
return $.event.handle.apply(this, arguments);
}
};
});
}
//IE has some troubble with focusout with select and keyboard navigation
var activeFocus = null, block;
$(document)
.bind('focusin', function(e){
var target = e.realTarget || e.target;
if (activeFocus && activeFocus !== target) {
e.type = 'focusout';
$(activeFocus).trigger(e);
e.type = 'focusin';
e.target = target;
}
activeFocus = target;
})
.bind('focusout', function(e){
activeFocus = null;
});
})();
})(jQuery);