www

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

tk.js (7438B)


      1 /* API :
      2  * widget(définitions); // Renvoie une nouvelle famille avec plusieurs widgets
      3  * widget(nom, définition); // Renvoie une nouvelle famille avec un seul widget
      4  * widget(Famille, définitions); // Ajoute les widgets à la famille et la renvoie
      5  * widget(Famille, nom, définition); // Ajoute un widget à la famille et la renvoie
      6  * 
      7  * *******************************
      8  * *      /!\ Attention /!\      *
      9  * * Les formes 2 et 3 modifient *
     10  * *  la famille d'origine !!!!  *
     11  * *******************************
     12  * 
     13  * Famille := un objet renvoyé par widget(…).
     14  * 
     15  * définitions := {
     16  *  définition0,
     17  *  définition1,
     18  *  …,
     19  *  définitionN
     20  * }
     21  *
     22  * défintion :=
     23  *  nomWidget1: function(_) {
     24  *      _.options(
     25  *          'monOption', 'valeur par défaut 1', // option positionnelle 1
     26  *          'truc',      'valeur par défaut 2', // option positionnelle 2
     27  *          'etc',       'valeur par défaut n', // option positionnelle n
     28  *          null, // ou false
     29  *          'uneOption', 'valeur par défaut A', // option nommée uneOption
     30  *          'uneAutre',  'valeur par défaut B', // option nommée uneAutre
     31  *      );
     32  *      // Chaque widget doit renvoyer un élément, créé par ex. avec $('<div/>'),
     33  *      // ou avec un autre widget.
     34  *      return _.autreWidget('Titre', 'Blabla', // On params positionnels de autreWidget
     35  *                           // Mettre _ juste avant le hash d'options nommées.
     36  *                           _.encoreUnAutreWidget(_, {sonOptionNommée: 3, sonTrucPositionnel: 5}),
     37  *                           $("<div>un élément</div>"),
     38  *                           // _('rest') contient le reste des options
     39  *                           _('rest'));
     40  *  }
     41  *
     42  */
     43 
     44 tk = {};
     45 
     46 (function($) {
     47     /* Création du hash des options et
     48  * du tableau des options positionnelles. */
     49     function makeOptionsHash(defpos) {
     50         var positions = [];
     51         var defauts = {};
     52         var positionnel = true;
     53         
     54         for (var i = 0; i < defpos.length; i += 2) {
     55             var k = defpos[i];
     56             var v = defpos[i+1];
     57             
     58             if (k === false || k === null) {
     59                 positionnel = false;
     60                 i--; // ne pas prendre la valeur
     61                 continue;
     62             }
     63             
     64             if (positionnel)
     65                 positions.push(k);
     66             
     67             defauts[k] = v;
     68         }
     69         
     70         return {
     71             positions: positions,
     72             defauts:   defauts
     73         };
     74     }
     75 
     76     function _options(h, defpos) {
     77         var defposhash = makeOptionsHash(defpos);
     78         var positions = defposhash.positions;
     79         var defauts = defposhash.defauts;
     80         var params = {};
     81         var firstRest = 0;
     82         
     83         if (h.realArgs[0] && h.realArgs[0].singleton === h.singleton) {
     84             // Hash de paramètres nommés dans realArgs[2]
     85             params = h.realArgs[1];
     86             firstRest = 2;
     87         } else {
     88             // Paramètres positionnels
     89             for (var i = 0; i < Math.min(h.realArgs.length, positions.length); i++) {
     90                 params[positions[i]] = h.realArgs[i];
     91             }
     92             firstRest = i;
     93         }
     94         
     95         // Reste des arguments
     96         for (var i = firstRest; i < h.realArgs.length; i++) {
     97             elem = h.realArgs[i];
     98             if (elem === null || elem === false) {
     99                 continue;
    100             }
    101             if (typeof elem == "string")
    102                 elem = $('<span/>').text(elem); // $(document.createTextNode(elem)) ne marche pas
    103             
    104             h.rest = h.rest.add(elem);
    105         }
    106         
    107         $.extend(h.futurethis, defauts, params);
    108     }
    109 
    110     var singleton = { ans: $() };
    111     
    112     function _uscore(h, args) {
    113         if (args.length == 0) {
    114             return h.singleton.ans;
    115         } else if (args[0] == 'rest') {
    116             return h.rest;
    117         } else if (args.length == 1) {
    118             var sel = args[0];
    119             var ret = $();
    120             for (var i = 0; i < sel.length; i++) {
    121                 ret = ret.add(h.rest[sel[i]]); // TODO : vérifier si ça serait pas ret.add($(...))
    122             }
    123             return ret;
    124         }
    125     }
    126     
    127     __widget = function (famille, nom, defwidget) {
    128         famille[nom] = function() {
    129             var h = {
    130                 singleton: singleton,
    131                 nom: nom,
    132                 realArgs: $.makeArray(arguments),
    133                 newArgs: [], // $.makeArray(arguments) 
    134                 futurethis: {},
    135                 rest: $(),
    136                 uscore: function() {
    137                     return _uscore(h, arguments);
    138                 }
    139             }
    140             
    141             h.uscore.singleton = h.singleton;
    142             h.newArgs.unshift(h.uscore);
    143             
    144             $.extend(h.uscore, famille, {
    145                 options: function() {
    146                     return _options(h, arguments);
    147                 }
    148             });
    149             
    150             var ret = defwidget.apply(h.futurethis, h.newArgs);
    151             if (ret === undefined) { ret = h.singleton.ans; }
    152             h.singleton.ans = ret;
    153             return ret;
    154         };
    155     }
    156     
    157     function _widget(famille, defs) {
    158         $.each(defs, function(nom, def) {
    159             __widget(famille, nom, def);
    160         });
    161         
    162         return famille;
    163     }
    164 
    165     function paire(k,v) {
    166         var r = {};
    167         r[k] = v;
    168         return r;
    169     }
    170 
    171     function fn_widget(a, b, c) {
    172         var is_fn = (arguments[1] instanceof Function);
    173         
    174         if (arguments.length == 1) return _widget({}, a);
    175         if (arguments.length == 2) return _widget(is_fn ? {}         : a,
    176                                                   is_fn ? paire(a,b) : b);
    177         if (arguments.length == 3) return _widget(a, paire(b,c));
    178     }
    179 
    180     widget = fn_widget;
    181 })(jQuery);
    182 
    183 jQuery.fn.extend({
    184     autoWidth: function() {
    185         var that = this;
    186         window.setTimeout(function() { $(that)._autoSize('width'); }, 0);
    187         $(this).bind('sizeChange posChange', function() {
    188             $(this)._autoSize('width');
    189             return true;
    190         });
    191     },
    192     autoHeight: function() {
    193         var that = this;
    194         window.setTimeout(function() { $(that)._autoSize('height'); }, 0);
    195         $(this).bind('sizeChange posChange', function() {
    196             $(this)._autoSize('height');
    197             return true;
    198         });
    199     },
    200     _autoSize: function(dimension) {
    201         var Dimension = dimension.charAt(0).toUpperCase()
    202             + dimension.substring(1);
    203         var total = this[0]['client'+Dimension];
    204         var scope = $(this)
    205             .children(':visible')
    206             .not('.tk.hcontainer-clear')
    207             .not('.ui-resizable-handle');
    208         var minus = (scope)
    209             .not('.auto-'+dimension)
    210             .invoke('outer'+Dimension, true)
    211             .sum();
    212         var nbshares = (scope)
    213             .filter('.auto-'+dimension)
    214             .size();
    215         
    216         (scope)
    217             .filter('.auto-'+dimension)
    218             [dimension]((total - minus) / nbshares);
    219         
    220         return this;
    221     },
    222     square: function() {
    223         var that = this;
    224         window.setTimeout(function() { $(that)._square(); });
    225     },
    226     _square: function() {
    227         if ($(this).width() < $(this).height()) {
    228             $(this.width($(this).height()));
    229         } else {
    230             $(this.height($(this).width()));
    231         }
    232         return this;
    233     }
    234 });