my-extensions.js (6473B)
1 Number.prototype.clip = function(min, max, floor) { 2 try { 3 return Math.min(Math.max(floor ? Math.floor(this) : this, min), max); 4 } catch(e) {alert("Error Number.prototype.clip");alert(e);} 5 }; 6 7 Number.prototype.mapInterval = function(a,b,x,y) { 8 return x + ((this-a) / (b-a) * (y-x)); 9 } 10 11 function dichotomy(start, isBigger) { 12 try { 13 var i = 0, min = 0, max, half; 14 for (max = start || 1; ++i < 10 && !isBigger(max); max *= 2); 15 for (half = start; Math.abs(min-max) > 0.1; half = (min + max) / 2) { 16 if (!isBigger(half)) min = half; 17 else max = half; 18 } 19 while (half > 1 && isBigger(half)) { --half; } 20 return half; 21 } catch(e) {alert("Error dichotomy");alert(e);throw(e);} 22 } 23 24 $.fn.fold = function(acc, fn) { 25 try { 26 this.each(function(i,e) { acc = fn(acc, i, e); }); 27 return acc; 28 } catch(e) {alert("Error $.fn.fold");alert(e);} 29 }; 30 31 $.fn.maxWidth = function() { return this.fold(0, function(acc,i,e){ return Math.max(acc, $(e).width()); }); }; 32 $.fn.maxHeight = function() { return this.fold(0, function(acc,i,e){ return Math.max(acc, $(e).height()); }); }; 33 $.fn.sumHeight = function() { return this.fold(0, function(acc,i,e){ return acc + $(e).height(); }); }; 34 $.fn.sumOuterHeight = function() { return this.fold(0, function(acc,i,e){ return acc + $(e).outerHeight(); }); }; 35 36 $.fn.hasScroll = function() { 37 var e = this.get(0); 38 return (e.clientHeight != e.scrollHeight) || (e.clientWidth != e.scrollWidth); 39 } 40 41 $.fn.fitFont = function() { 42 try { 43 var that = this; 44 this.css({overflow: 'auto'}); 45 var setFont = this.find('.setFont').andSelf(); 46 this.find('.center').css({top:0, left:0}); // Petit hack pour que ça ne déborde pas à cause de l'offset mis par .center(). 47 var size = dichotomy(parseInt(this.css("font-size"), 10), function(x) { 48 setFont.css("fontSize", x); 49 var ret = false; 50 that.$each(function(i,e) { return !(ret = e.hasScroll()); }); // ormap 51 return ret; 52 }); 53 this.css({overflow: 'hidden'}); 54 this.css("font-size", Math.max(0, size)); 55 return this; 56 } catch(e) {alert("Error $.fn.fitFont");alert(e);throw(e);} 57 }; 58 59 $.fn.$each = function(fn) { 60 this.each(function(i,e) { return fn(i, $(e)); }); 61 }; 62 63 function queueize(method) { 64 try { 65 return function() { 66 var $this = this; 67 var args = Array.prototype.slice.call(arguments); // cast Arguments → Array 68 return this.queue(function(next) { 69 $this[method].apply($this,args); 70 next(); 71 }); 72 }; 73 } catch(e) {alert("Error queueize");alert(e);} 74 } 75 76 $.fn.qAddClass = queueize("addClass"); 77 $.fn.qRemoveClass = queueize("removeClass"); 78 $.fn.qRemove = queueize("remove"); 79 $.fn.qShow = queueize("show"); 80 $.fn.qHide = queueize("hide"); 81 $.fn.qCss = queueize("css"); 82 83 $.fn.wh = function(w, h) { 84 try { 85 if (isNaN(+w) && w && typeof w.width != 'undefined') { h = w.height; w = w.width; } 86 if (typeof w == 'undefined') return {width: this.width(), height:this.height()}; 87 return this.width(w).height(isNaN(+h) ? w : h); 88 } catch(e) {alert("Error $.fn.wh");alert(e);} 89 }; 90 91 $.fn.center = function(to, justCss) { 92 if (to) this.css("position", "absolute"); 93 var deltaX = this.outerWidth()/2; 94 var deltaY = this.outerHeight()/2; 95 96 if (to) { 97 var css = { 98 left: to.left - deltaX, 99 top: to.top - deltaY 100 }; 101 return (justCss ? css : this.offset(css)); 102 } else { 103 var pos = this.offset(); 104 pos.left += deltaX; 105 pos.top += deltaY; 106 return pos; 107 } 108 }; 109 110 /** 111 * startcolor et endcolor sont de la forme {r:0,g:255,b:127} 112 */ 113 $.fn.goodBad = function(min, max, startcolor, endcolor) { 114 var val = parseInt(this.text(), 10); 115 if (isNaN(val)) return this; 116 this.css("color","rgb(" 117 +(val.mapInterval(min,max,startcolor.r,endcolor.r).clip(0, 255, true))+"," 118 +(val.mapInterval(min,max,startcolor.g,endcolor.g).clip(0, 255, true))+"," 119 +(val.mapInterval(min,max,startcolor.b,endcolor.b).clip(0, 255, true))+")"); 120 return this; 121 }; 122 123 $.debounce = function debounce(fn, interval) { 124 var wait = false; 125 var delayedFn = false; 126 interval = interval || 200; 127 return function() { 128 var that = this; 129 var args = Array.prototype.slice.call(arguments); // cast Arguments → Array 130 delayedFn = function() { delayedFn = false; fn.apply(that, args); } 131 if (!wait) { 132 wait = true; 133 delayedFn(); 134 var loop = function() { 135 if (delayedFn) { 136 delayedFn(); 137 window.setTimeout(loop, interval); 138 } else { 139 wait = false; 140 } 141 } 142 window.setTimeout(loop, interval); 143 } 144 }; 145 }; 146 147 /** Zoom from small center of startElem to big center of endElem, or do the reverse animation (from big end to small start). */ 148 $.fn.zoom = function(startElem, endElem, reverse) { 149 var that = this; 150 startElem = $(startElem); 151 endElem = $(endElem); 152 return this.queue(function(next) { 153 if (that.size() == 0) return next(); 154 that.removeClass('transition'); // disable animations 155 window.setTimeout(function() { 156 // Calcul de la taille de police pour end(). 157 var endbox = $('<div style="text-align:center;"/>').appendTo('body').wh(endElem.wh()); 158 that.appendTo(endbox); 159 that.css({position:'', top:'', left:''}); 160 endbox.fitFont(); 161 var BFontSize = endbox.css('fontSize'); 162 var APos = endbox.css('fontSize', 0).center(startElem.center()).offset(); 163 var BPos = endbox.css('fontSize', BFontSize).center(endElem.center()).offset(); 164 var A = function() { endbox.css('fontSize', 0).offset(APos); }; 165 var B = function() { endbox.css('fontSize', BFontSize).offset(BPos); }; 166 (reverse ? B : A)(); 167 window.setTimeout(function() { 168 endbox.addClass('transition'); // enable animations 169 (reverse ? A : B)(); 170 endbox.delay(700).qRemoveClass('transition'); 171 if (reverse) endbox.qRemove(); 172 next(); 173 }, 0); 174 }, 0); 175 }); 176 }; 177 178 function decodeHash(hash) { 179 /* hash.match(/^#([a-z]+(\/[0-9]+(\/-?[0-9]+(,-?[0-9]+)*)?)?)?$/) */ 180 hash = hash.substring(1).split('/'); 181 return { 182 screen:hash[0] || 'splash', 183 pgid:hash[1] || 0, 184 answers:(hash[2] ? hash[2].split(',') : []) 185 }; 186 } 187 188 function appendAnswer(data, answer) { 189 return $.extend({}, data, { answers: data.answers.concat([answer]) }); 190 } 191 192 function encodeHash(data) { 193 var hash = "#"; 194 if (data.screen == '') return hash; 195 hash += data.screen 196 if (data.pgid == 0) return hash; 197 hash += '/'+data.pgid; 198 if (data.answers.length == 0) return hash; 199 hash += '/'+data.answers.join(','); 200 return hash; 201 } 202 203 function Cache(resolver) { 204 var cache = {}; 205 this.get = function(k, arg) { 206 return cache[k] = cache[k] || $.Deferred(function(dfd) { resolver(k, dfd, arg); }).fail(function() { cache[k] = false; }).promise(); 207 }; 208 }