mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-08-26 04:26:01 +02:00
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@92553 467b73ca-7a2a-4603-9d3b-597d59a354a9
239 lines
5.6 KiB
JavaScript
239 lines
5.6 KiB
JavaScript
/**
|
|
* @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);
|