www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

extensions-jQuery.js (10040B)


      1 // Extensions de String
      2 
      3 String.prototype.escapeXML = function() {
      4     return this
      5     .replace(/&/g, "&")
      6     .replace(/</g, "&lt;")
      7     .replace(/>/g, "&gt;")
      8     .replace(/"/g, "&quot;")
      9     .replace(/'/g, "&apos;");
     10 }
     11 
     12 /* "<div>foo</div>".toDom() ⇔ $("<div>foo</div>") */
     13 String.prototype.toDom = function() {
     14     return $("" + this);
     15 }
     16 
     17 String.prototype.appendTo = function() {
     18     var d = this.toDom();
     19     return d.appendTo.apply(d, arguments);
     20 }
     21 
     22 // Extensions de jQuery
     23 
     24 jQuery.fn.extend({
     25     /* Mathias Bynens - http://stackoverflow.com/questions/2059743/detect-elements-overflow-using-jquery */
     26     overflows: function() {
     27         return ($(this).width() !== this.clientWidth || $(this).height() !== this.clientHeight);
     28     },
     29     scrollToLast: function(speed) {
     30         return this.scrollTo(this.children().last(), speed);
     31     },
     32     addTo: function(collection) {
     33         $.merge(collection, this);
     34         return collection;
     35     },
     36     remap: function(fn) {
     37         var a = $.makeArray(arguments);
     38         a.shift();
     39 
     40         var r = $();
     41         this.each(function(i, e) {
     42             var aa = $.makeArray(a);
     43             aa.push(e);
     44             r = r.add(fn.apply(this, aa));
     45         });
     46         return r;
     47     },
     48     // Sérialise le DOM de l'élément sous forme de HTML.
     49     serializeDOM: function(value) {
     50         /* get the DOM of this node, serialized as HTML.
     51          * with value, set the DOM of this node to the
     52          * serialized HTML value (Not Implemented Yet) */
     53         if ( value === undefined ) {
     54 	    return this.html().escapeXML();
     55 	}
     56     },
     57     // renvoie le map de attr sur chaque élément (lecture seule).
     58     attrs: function(value) {
     59         return this.map(function(idx, elem) {
     60             return $([elem]).attr(value);
     61         });
     62     },
     63     // Active ou désactive resizable(), et rend la hauteur libre.
     64     toggleResizable: function() {
     65         // TODO : devrait enregistrer les options.
     66         
     67         if (this.data('notResizable')) {
     68             this.resizable();
     69             this.height(this.data('oldHeight'));
     70         } else {
     71             this.resizable('destroy');
     72             this.data('oldHeight', this.height());
     73             this.height('auto');
     74         }
     75         
     76         this.data('notResizable', ! this.data('notResizable'))
     77         
     78         return this;
     79     },
     80     
     81     // Alias pour des accesseurs courants sur les positions des éléments
     82     // Top, left, center, bottom, right, en X et en Y.
     83     offX: function(value) {
     84         if (value === undefined) {
     85             return this.offset().left;
     86         } else {
     87             return this.offset({left: value});
     88         }
     89     },
     90     offY: function(value) {
     91         if (value === undefined) {
     92             return this.offset().top;
     93         } else {
     94             return this.offset({top: value});
     95         }
     96     },
     97     leftX: function() {
     98         return this.offX.apply(this, arguments);
     99     },
    100     topY: function() {
    101         return this.offY.apply(this, arguments);
    102     },
    103     centerX: function() {
    104         return this.offX() + (this.width() / 2);
    105     },
    106     centerY: function() {
    107         return this.offY() + (this.height() / 2);
    108     },
    109     rightX: function() {
    110         return this.offX() + this.width();
    111     },
    112     bottomY: function() {
    113         return this.offY() + this.height();
    114     }
    115 });
    116 
    117 // Fonction utilitaire permettant de facilement surcharger un
    118 // accesseur pour un certain type d'éléments.
    119 function surchargeAccesseur(nom, type, get, set) {
    120     var _old = $.fn[nom];
    121     $.fn[nom] = function(options) {
    122         var args = arguments;
    123         if (options !== undefined) {
    124             var that = this;
    125             var ret = $(this).map(function (i) {
    126                 if (that[i] instanceof type) {
    127                     return set(that[i], options);
    128                 } else {
    129                     return _old.apply($(that[i]), args);
    130                 }
    131             });
    132             return ret[0];
    133         } else {
    134             if (this[0] instanceof type) {
    135                 return get(this);
    136             } else {
    137 	        return _old.call(this);
    138             }
    139         }
    140     };
    141     
    142 }
    143 
    144 function surchargeAccesseurSimple(nom, defaut, type) {
    145     surchargeAccesseur(
    146         nom,
    147         type,
    148         function (obj) { ret = obj[0][nom]; return (ret !== undefined) ? ret : defaut; },
    149         function (obj, val) { obj[nom] = val; }
    150     );
    151 }
    152 
    153 // Permet d'utiliser un évènement comme si c'était un élément du DOM.
    154 
    155 // This is the beauty of JavaScript ♥.
    156 surchargeAccesseurSimple('height', 0, $.Event);
    157 surchargeAccesseurSimple('width', 0, $.Event);
    158 surchargeAccesseurSimple('scrollLeft', 0, $.Event);
    159 surchargeAccesseurSimple('scrollTop', 0, $.Event);
    160 surchargeAccesseurSimple('outerWidth', 0, $.Event);
    161 surchargeAccesseurSimple('outerHeight', 0, $.Event);
    162 surchargeAccesseur(
    163     'offset',
    164     $.Event,
    165     function (obj) {
    166         return {
    167             left: obj[0].pageX,
    168             top:  obj[0].pageY
    169         };
    170     },
    171     function (obj, val) {
    172         if ('left' in val) { that[i].pageX = val.left; }
    173         if ('top'  in val) { that[i].pageY = val.top;  }
    174     }
    175 );
    176 
    177 // Fix firefox bug : when top or left are set to a non-integer value, flicker occurs. 
    178 (function ($) {
    179     var _offset = $.fn.offset;
    180     
    181     $.fn.offset = function(options) {
    182         var args = arguments;
    183         if (options !== undefined) {
    184             if ('left' in options) { args[0].left = Math.floor(options.left); }
    185             if ('top'  in options) { args[0].top  = Math.floor(options.top);  }
    186         }
    187         
    188         return _offset.apply(this, args);
    189     }
    190 }(jQuery));
    191 
    192 
    193 getRectangle = function(x1,y1,x2,y2) {
    194     if (y1 === undefined) {
    195         var o = $(x1).offset();
    196         return getRectangle(o.left, o.top, o.left + $(x1).width(), o.top + $(x1).height());
    197     }
    198     if (x2 === undefined) {
    199         var oa = $(x1).offset();
    200         var ob = $(y1).offset();
    201         return getRectangle(oa.left, oa.top, ob.left, ob.top);
    202     }
    203     return {
    204         x1: Math.min(x1,x2),
    205         y1: Math.min(y1,y2),
    206         x2: Math.max(x1,x2),
    207         y2: Math.max(y1,y2),
    208         width: Math.abs(x1 - x2),
    209         height: Math.abs(y1 - y2)
    210     };
    211 };
    212 
    213 jQuery.fn.corners = function(x1,y1,x2,y2) {
    214     var rect = getRectangle(x1,y1,x2,y2);
    215     this.offset({left: rect.x1, top: rect.y1});
    216     this.width(rect.width);
    217     this.height(rect.height);
    218 }
    219 
    220 jQuery.fn.zonable = function(start, zone, end) {
    221     var opts = {
    222         start: function() {return true;},
    223         zone: function() {return true;},
    224         end: function() {return true;}
    225     };
    226     if (typeof start == "function") {
    227         if (start) opts.start = start;
    228         if (zone) opts.start = start;
    229         if (end) opts.start = start;
    230     } else {
    231         if (start) $.extend(opts, start);
    232     }
    233     
    234     var z = {};
    235     z.vZone = $('#vue-zone').jqote({}).appendTo(this);
    236     z.vZone.hide();
    237     z.zoning = false;
    238     z.start = null;
    239 
    240     z.manageDown = function(e) {
    241         if (e.target != this || opts.start(e) === false) {
    242             return true;
    243         }
    244         z.start = $(e);
    245         z.zoning = true;
    246         z.vZone.show();
    247         z.manageMove(e);
    248         return false;
    249     };
    250     z.manageMove = function(e) {
    251         if (z.zoning) {
    252             if (opts.zone(z.start, e) === false) {
    253                 return true;
    254             }
    255             z.vZone.corners(z.start, e);
    256             return false;
    257         }
    258     };
    259     z.manageUp = function(e) {
    260         if (z.zoning) {
    261             z.manageMove(e);
    262             if (opts.end(z.start, e, getRectangle(z.start, e)) === false) {
    263                 return true;
    264             }
    265             z.vZone.hide();
    266             z.zoning = false;
    267             return false;
    268         }
    269     }
    270     
    271     var that = this;
    272     this.mousedown(z.manageDown);
    273     this.mousemove(z.manageMove);
    274     this.mouseup(z.manageUp);
    275 }
    276 
    277 
    278 /* Fioritures graphique */
    279 jQuery.fn.extend({
    280     blink: function (count, speed) {
    281         elem = this;
    282         count = count || 10;
    283         speed = speed || 1000;
    284         
    285         // Mouseover
    286         // Todo : il y a des bugs graphiques ici,
    287         // et il faudrait enlever ce hook "mouseover"
    288         // après la première fois.
    289         elem.mouseover(function () {
    290             elem.clearQueue("blink");
    291             elem.queue("blink", function() {
    292                 elem.removeClass('boutonHover', 1000);
    293             });
    294         });
    295         
    296         // Enqueue blinks
    297         for (; count > 0; count--) {
    298             elem.queue("blink", function () {
    299                 elem.toggleClass('boutonHover', 1000, function() { elem.dequeue("blink"); });
    300             });
    301         }
    302         elem.queue("blink", function() {
    303             elem.removeClass('boutonHover', 1000);
    304         });
    305         
    306         // Start first blink
    307         elem.dequeue("blink");
    308     },
    309     stepAnimateClass: function(from, to) {
    310         var el = $(this[0]); // TODO : faire un foreach.
    311         var actions = {};
    312         var props = ['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'];
    313 
    314         // Get the end
    315         var end = {};
    316         var oldstyle = el.attr('style');
    317         var oldclasses = el.attr('className');
    318         el.addClass(to);
    319         $.each(props, function(i, attr) {
    320             end[attr] = el.css(attr);
    321         });
    322         el.attr('className', oldclasses);
    323         el.addClass(from);
    324 
    325         // Prepare animations
    326         $.each(props, function(i, attr) {
    327             actions[attr] = {
    328                 elem: el[0],
    329                 end: end[attr],
    330                 pos: 0
    331             };
    332             $.fx.step[attr](actions[attr]);
    333         });
    334         el.attr('style', '');
    335         el.attr('style', oldstyle);
    336         el.attr('className', oldclasses);
    337         
    338         return function(pos) {
    339             if (pos === undefined) {
    340                 el.attr('style', '');
    341                 el.attr('style', oldstyle);
    342             }
    343             for (i in actions) {
    344                 actions[i].pos = pos;
    345                 $.fx.step[i](actions[i]);
    346             }
    347         }
    348     }
    349 });