www

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

instance-recherche.js (8815B)


      1 function MInstanceRecherche() {
      2     $.extend(this, {
      3         uid: singleton.uid(),
      4         // Propriétés
      5         mRecherche: null,
      6         termes: '',
      7         sélection: [],
      8         ajouterRésultatSélection: function(s) {
      9             this.sélection.push(s);
     10             s.ajoutSélection();
     11         },
     12         supprimerRésultatSélection: function(s) {
     13             this.sélection.remove(s);
     14             s.suppressionSélection();
     15         },
     16         effacerSélection: function(s) {
     17             for (var i = 0; i < this.sélection.length; i++)
     18                 this.sélection[i].suppressionSélection();
     19             this.sélection = [];
     20         }
     21     });
     22 }
     23 
     24 function VInstanceRecherche(vMondeParente) {
     25     $.extend(this,(
     26         $('#vue-recherche')
     27             .jqote({})
     28             .appendTo(vMondeParente)));
     29     
     30     this.vBarreTitre = this.find('.barre-titre');
     31     this.vTitre = this.find('.titre');
     32     this.vChampTermes = this.find('.termes');
     33     this.vRésultats = this.find('.résultats');
     34     this.premièreFois = true;
     35     this.addClass('première-fois');
     36 
     37     var that = this;
     38     (this.vChampTermes)
     39         .focus(function() {
     40             if (that.premièreFois) {
     41                 that.premièreFois = false;
     42                 that.vChampTermes.val("");
     43                 // TODO : unbind focus
     44             }
     45         });
     46     
     47     this.ajoutVRésultatRecherche = function(vrr, position) {
     48         if (position === undefined || position >= this.vRésultats.children().size() - 1) {
     49             this.vRésultats.append(vrr);
     50         } else {
     51             this.vRésultats.children().eq(position).before(vrr);
     52         }
     53     };
     54     
     55     this.sélection = function(s) {
     56         this.vRésultats.children.removeClass('sélectionné');
     57         s.addClass('sélectionné');
     58     };
     59     
     60     this.termes = function(val) {
     61         if (val !== undefined) {
     62             this.vChampTermes.val(val);
     63             this.removeClass('première-fois');
     64             this.premièreFois = false;
     65             // TODO : unbind focus
     66         } else if (this.premièreFois) {
     67             return "";
     68         } else {
     69             return this.vChampTermes.val();
     70         }
     71     };
     72     
     73     /*this.effacerRésultats = function() {
     74         this.vRésultats.empty();
     75     };*/
     76     
     77     this.draggable();
     78     this.resizable();
     79     this.vRésultats.css('top', this.vBarreTitre.outerHeight());
     80 }
     81 
     82 function CInstanceRecherche(mInstanceRecherche, vMondeParente) {
     83     this.modèle = mInstanceRecherche;
     84     this.vue = new VInstanceRecherche(vMondeParente);
     85     this.ancienTerme = "";
     86     this.anciensRésultats = [];
     87     
     88     var that = this;
     89     (this.vue.vChampTermes)
     90         .keyup(function() { // keypress ne prend pas en compte le backspace
     91             that.actualiserRecherche();
     92         });
     93     
     94     (this.modèle.mRecherche.monde)
     95         .onAjoutBloc(function(bloc) {
     96             that.actualiserRecherche([bloc], true, true);
     97         });
     98     
     99     (this.modèle.mRecherche.monde)
    100         .onModificationBloc(function(bloc) {
    101             that.actualiserRecherche([bloc], true, true);
    102         });
    103     
    104     this.actualiserRecherche = function(domaine, animAjout, animSuppression) {
    105         var termes = this.vue.termes().toLowerCase().split(" ");
    106         var domaine = domaine || this.modèle.mRecherche.monde.blocs;
    107         var résultats = filtrerValeurs(mInstanceRecherche, domaine, termes, function(b) {
    108             return {
    109                 original: b.nom,
    110                 searchOn: b.nom.toLowerCase()
    111             };
    112         });
    113         
    114         this.anciensRésultats = fusionRésultats(this.anciensRésultats, domaine, résultats, this.vue, this.modèle, animAjout, animSuppression);
    115     }
    116     
    117     this.actualiserRecherche(null, true, true);
    118 }
    119 
    120 /* Fonctions auxiliaires */
    121 
    122 function filtrerValeurs(mInstanceRecherche, ensemble, termes, getTexte) {
    123     var maxres = 50;
    124     var résultats = [];
    125     var nbres = 0;
    126     var ensemble_length = ensemble.length;
    127     termes = termes.filter(function (e) { return e != ""; });
    128     
    129     for (var i = 0; i < ensemble_length; i++) {
    130         var texte = getTexte(ensemble[i]);
    131         var mrr = searchAndReturnFormatted(mInstanceRecherche, texte.searchOn, texte.original, termes);
    132         
    133         if (mrr !== false) {
    134             mrr.objet = ensemble[i];
    135             mrr.uid = ensemble[i].uid;
    136             résultats.push(mrr);
    137             nbres++;
    138             if (nbres >= maxres) break;
    139         }
    140     }
    141     
    142     résultats.sort(function(a,b){return a.score - b.score});
    143     for (var i = 0; i<résultats.length; i++) { résultats[i].position = i; }
    144     return résultats;
    145 }
    146 
    147 /* searchAndReturnFormatted("abcdefghijkabcxyz", ["abc", "ef", "cxy"]); */
    148 function searchAndReturnFormatted(mInstanceRecherche, haystack, original, needles) {
    149     var status = new Array(haystack.length);
    150     for (var i = 0; i < status.length; i++) {
    151         status[i] = 0;
    152     }
    153     
    154     for (var n = 0; n < needles.length; n++) {
    155         var nl = needles[n].length;
    156         var idx = haystack.indexOf(needles[n]);
    157         if (idx < 0) {
    158             // Aucune occurence de needles[n]
    159             return false;
    160         }
    161         while (idx >= 0) {
    162             for (var i = idx; i < idx + nl; i++) {
    163                 if (status[i] > 0) {
    164                     for (j = idx; j < idx + nl; j++) {
    165                         if (j >= i && status[j] >= 1) {
    166                             status[j] = 3;
    167                         } else {
    168                             status[j] = 2;
    169                         }
    170                     }
    171                     i = idx + nl;
    172                     break;
    173                 }
    174                 status[i] = 1;
    175             }
    176             idx = haystack.indexOf(needles[n], i);
    177         }
    178     }
    179     
    180     var old = -1;
    181     var str = "";
    182     for (var i = 0; i < status.length; i++) {
    183         if (old != status[i]) {
    184             if (old >= 1)
    185                 str += '</span>';
    186             if (status[i] == 1) {
    187                 str += '<span class="occurence">';
    188             } else if (status[i] == 2) {
    189                 str += '<span class="superposée">';
    190             } else if (status[i] == 3) {
    191                 str += '<span class="superposition">';
    192             }
    193         }
    194         str += original[i];
    195         old = status[i];
    196     }
    197     
    198     if (old >= 1)
    199         str += '</span>';
    200     var mrr = new MRésultatRecherche();
    201     mrr.mInstanceRecherche = mInstanceRecherche;
    202     mrr.html = str;
    203     mrr.score = $.sum(status); // We definitely need a better score calculation…
    204     return mrr;
    205 }
    206 
    207 /* anciens = [] of CRésultatRecherche;
    208  * domaine = [] of MBloc;
    209  * nouveaux = [] of MRésultatRecherche;
    210  * vRechercheParente is a VRechercheParente
    211  * mInstanceRecherche is a MInstanceRecherche
    212  * animAjout is a boolean
    213  * animSuppression is a boolean
    214  */
    215 
    216 function fusionRésultats(anciens, domaine, nouveaux, vRechercheParente, mInstanceRecherche, animAjout, animSuppression) {
    217     anciens.sort(function(a,b)  { return a.modèle.objet.uid - b.modèle.objet.uid; });
    218     domaine.sort(function(a,b)  { return a.uid              - b.uid;              });
    219     nouveaux.sort(function(a,b) { return a.objet.uid        - b.objet.uid;        });
    220     
    221     // Ceci est une sorte de tri fusion à trois tableaux… aaaaaarrrgggh !
    222 
    223     /* anciens  domaine  nouveaux      ||  Action
    224      * oui      non      non (obligé)  ||  = Reste
    225      * oui      oui      oui           ||  = Reste
    226      * oui      oui      non           ||  - Supprime
    227      * non      oui      oui           ||  + Ajoute
    228      * non      oui      non           ||  0 Aucune
    229      */
    230     
    231     var fusion = [];
    232     var iD = 0;
    233     var iN = 0;
    234     var iA = 0;
    235     var lA = anciens.length;
    236     var lD = domaine.length;
    237     var lN = nouveaux.length;
    238     while ((iA < lA) || (iD < lD) || (iN < lN)) {
    239         var uidA = (iA < lA) ? anciens[iA].modèle.objet.uid : Infinity;
    240         var uidD = (iD < lD) ? domaine[iD].uid              : Infinity;
    241         var uidN = (iN < lN) ? nouveaux[iN].objet.uid       : Infinity;
    242         
    243         var a = (iA < lA && uidA <= uidD);
    244         var d = (iD < lD && uidA >= uidD);
    245         var n = (iN < lN && uidD == uidN) && d;
    246 
    247         //console.log([iA,iD,iN], [uidA,uidD,uidN], [a,d,n]);
    248         
    249         if (a  && !(d && !n)) { // Reste
    250             if (n) {
    251                 anciens[iA].setModèle(nouveaux[iN]);
    252             }
    253             fusion.push(anciens[iA]);
    254         }
    255         if (a  && d  && !n) {  // Supprime
    256             anciens[iA].suppression(animSuppression);
    257         }
    258         if (!a && d  && n) {   // Ajoute
    259             var cr = new CRésultatRecherche(nouveaux[iN], vRechercheParente);
    260             if (animAjout) {
    261                 cr.vue.animAjout();
    262             }
    263             fusion.push(cr);
    264         }
    265 
    266         if (a) iA++;
    267         if (d) iD++;
    268         if (n) iN++;
    269     }
    270     return fusion;
    271 }