Permalink
Browse files

MINOR Added jquery live extensions, necessary for 'change' event in j…

…query.concrete

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@92553 467b73ca-7a2a-4603-9d3b-597d59a354a9
  • Loading branch information...
1 parent 0231e8b commit f418cdd55eb5fd04db7c6f32f4b960052d4410d4 @chillu chillu committed Nov 21, 2009
Showing with 238 additions and 0 deletions.
  1. +238 −0 thirdparty/jquery-live-extension/live-extension.js
@@ -0,0 +1,238 @@
+/**
+ * @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);

0 comments on commit f418cdd

Please sign in to comment.