plint

French poetry validator (local mirror of https://gitlab.com/a3nm/plint)
git clone https://a3nm.net/git/plint/
Log | Files | Refs | README

script.js (10141B)


      1 /* http://chrissilich.com/blog/convert-em-size-to-pixels-with-jquery/ */
      2 function em2px(n) {
      3     var emSize = parseFloat($("body").css("font-size"));
      4     return (emSize * n);
      5 }
      6 
      7 function htmlentities(x) {
      8   return $('<div/>').text(x).html();
      9 }
     10 
     11 function onlydigits(x) {
     12   return String(x).replace(/[^0-9]/, '');
     13 }
     14 
     15 function showCustom(a) {
     16   if (a) {
     17     document.getElementById("custom_template").style.display = "block";
     18   } else {
     19     document.getElementById("custom_template").style.display = "none";
     20   }
     21 }
     22 
     23 function reportError(msg) {
     24   if (lang == "fr") {
     25     var message = ("Impossible de vérifier le poème faute de pouvoir "
     26       + "communiquer avec le serveur&nbspp;: ");
     27   } else {
     28     var message = ("Could not check poem due to error when "
     29       + "communicating with server: ");
     30   }
     31   $( "#status" ).html("<span class=\"error\">" + message + msg + "</span>");
     32 }
     33 
     34 var setForCustom = false;
     35 
     36 function setUnload() {
     37   window.onbeforeunload = function() {
     38     if (lang == "fr") {
     39       return ("Votre poème sera perdu en fermant cette page.");
     40     } else {
     41       return ("Your poem will be lost when closing this page.");
     42     }
     43   };
     44 }
     45 
     46 function toggleUnload() {
     47   if ($('#poem').val().length > 10) {
     48     setUnload();
     49   } else {
     50     if (!setForCustom) {
     51       window.onbeforeunload = null;
     52     }
     53   }
     54 }
     55 
     56 function setCustom() {
     57   setForCustom = true;
     58   setUnload();
     59 }
     60 
     61 function getAvail() {
     62   var avail = $( window ).height() - $( '#lcontainer' ).offset().top - em2px(4) - $( '#tools' ).height() - $( '#predef' ).height();
     63   if ($( '#user_template' ).is(":visible")) {
     64     avail -= em2px(.5);
     65   }
     66   if ($( window ).width() <= 650) {
     67     avail -= em2px(1);
     68   }
     69   return avail;
     70 }
     71 
     72 function sanitize(e) {
     73   var avail = getAvail();
     74   var h1 = $( '#poem' ).height();
     75   var h2 = $( '#user_template' ).height();
     76   var h3 = $( '#cerrors' ).height();
     77   if (h1 > avail) {
     78     $( '#poem' ).height(avail);
     79     h1 = avail;
     80   }
     81   if (h2 > avail) {
     82     $( '#user_template' ).height(avail);
     83     h2 = avail;
     84   }
     85   if (h3 > avail) {
     86     $( '#cerrors' ).height(avail);
     87     h3 = avail;
     88   }
     89 }
     90 
     91 var poem_h, poem_w, user_template_h, user_template_w;
     92 
     93 function resizeCErrors(e) {
     94   // resize in width
     95   var twidth = $( window ).width() - $( '#poem' ).width() - em2px(2);
     96   if (twidth > 50) {
     97     $( '#cerrors' ).width(twidth);
     98   }
     99 
    100   if ($( window ).width() > 650) {
    101     /* stretch cerrors */
    102     $( '#cerrors' ).height($( window ).height() - $( '#cerrors' ).offset().top - em2px(1));
    103   }
    104   if ($( window ).width() <= 650) {
    105     // everyone takes full width
    106     $( '#cerrors' ).width($( window ).width() - em2px(2));
    107     $( '#user_template' ).width($( window ).width() - em2px(2));
    108     $( '#poem' ).width($( window ).width() - em2px(2));
    109     $( '#lcontainer' ).width($( window ).width() - em2px(2));
    110   }
    111   // store the sizes (see resizeAllLast function)
    112   // following http://stackoverflow.com/a/7055197
    113   poem_h = $( '#poem' ).height();
    114   poem_w = $( '#poem' ).width();
    115   user_template_h = $( '#user_template' ).height();
    116   user_template_w = $( '#user_template' ).width();
    117 }
    118 
    119 function resizeAllPoem(e) {
    120   if ($( '#poem' ).height() == poem_h && $( '#poem' ).width() == poem_w) {
    121     // nothing changed
    122     return;
    123   }
    124   sanitize(e);
    125   var avail = getAvail();
    126   var h1 = $( '#poem' ).height();
    127   avail -= h1;
    128   var h2 = $( '#user_template' ).height();
    129   var h3 = $( '#cerrors' ).height();
    130   if (!($( '#user_template' ).is(":visible")) && ($( window ).width() > 650)) {
    131     /* silly, just take the entire height */
    132     $( '#poem' ).height(avail + h1);
    133   } else {
    134     if ($( window ).width() <= 650) {
    135       /* fix user_template, use the rest for cerrors*/
    136       if ($( '#user_template' ).is(":visible")) {
    137         avail -= h2;
    138       }
    139       $( '#cerrors' ).height(0.1 + avail);
    140     } else {
    141       /* use the rest for user_template */
    142       $( '#user_template' ).height(0.1 + avail);
    143     }
    144   }
    145   // resize in width
    146   $( '#user_template' ).width($( '#poem' ).width());
    147   $( '#lcontainer' ).width($( '#poem' ).width());
    148   resizeCErrors(e);
    149 }
    150 
    151 function resizeAllUserTemplate(e) {
    152   if ($( '#user_template' ).height() == user_template_h && $( '#user_template' ).width() == user_template_w) {
    153     // nothing changed
    154     return;
    155   }
    156   sanitize(e);
    157   var avail = getAvail();
    158   var h1 = $( '#poem' ).height();
    159   var h2 = $( '#user_template' ).height();
    160   var h3 = $( '#cerrors' ).height();
    161   avail -= h2;
    162   /* share what remains among other elements */
    163   var used = h1 + 0.01;
    164   if ($( window ).width() <= 650) {
    165     used += h3;
    166   }
    167   $( '#poem' ).height(h1 * avail/used);
    168   if ($( window ).width() <= 650) {
    169     $( '#cerrors' ).height(0.1 + h3 * avail/used);
    170   }
    171   // resize in width
    172   $( '#poem' ).width($( '#user_template' ).width());
    173   $( '#lcontainer' ).width($( '#user_template' ).width());
    174   resizeCErrors(e);
    175 }
    176 
    177 function resizeAll(e) {
    178   sanitize(e);
    179   var avail = getAvail();
    180   var h1 = $( '#poem' ).height();
    181   var h2 = $( '#user_template' ).height();
    182   var h3 = $( '#cerrors' ).height();
    183   /* just scale existing proportions */
    184   var used = h1 + 0.01;
    185   if ($( '#user_template' ).is(":visible")) {
    186     used += h2;
    187   }
    188   if ($( window ).width() <= 650) {
    189     used += h3;
    190   }
    191   $( '#poem' ).height(h1 * avail/used);
    192   if ($( '#user_template' ).is(":visible")) {
    193     $( '#user_template' ).height(0.1 + h2 * avail/used);
    194   }
    195   if ($( window ).width() <= 650) {
    196     $( '#cerrors' ).height(0.1 + h3 * avail/used);
    197   }
    198   resizeCErrors(e);
    199 }
    200 
    201 function resizeAllLast(e) {
    202   // chrome does not fire mouseup when it happens outside of the element
    203   // and does not fire mousedown when resizing
    204   // https://code.google.com/p/chromium/issues/detail?id=453023
    205   // so we have to detect mouseups globally
    206   // and figure out who was resized
    207   // by comparing against stored sizes...
    208   if ($( '#poem' ).height() != poem_h || $( '#poem' ).width() != poem_w) {
    209     resizeAllPoem();
    210   } else if ($( '#user_template' ).height() != user_template_h || $( '#user_template' ).width() != user_template_w) {
    211     resizeAllUserTemplate();
    212   } else {
    213     // we can't figure it out (or the mouseup is irrelevant)
    214     // run resizeAll
    215     resizeAll();
    216   }
    217 }
    218 
    219 window.onresize = resizeAll;
    220 window.onload = resizeAll;
    221 
    222 function check() {
    223   $( "#status" ).html("Checking...");
    224   $('#check').prop( "disabled", true);
    225   var poem = $( '#poem' ).val();
    226   var mydata = {
    227       'poem': poem,
    228       'template': $( '#predef' ).val()
    229     };
    230   if (mydata['template'] == 'custom') {
    231     mydata['custom_template'] = $( "#user_template" ).val();
    232   }
    233   $.ajax({
    234     url: "checkjs",
    235     type: "post",
    236     data: mydata,
    237     error: function (jqxhr, stat, error) {
    238       reportError(htmlentities(stat) +
    239          (error.length > 0 ? ": " + htmlentities(error) : ""));
    240       $('#check').prop( "disabled", false);
    241       // do not keep old errors around lest the user may miss the problem
    242       $( "#errors" ).empty();
    243     },
    244     success: function (data) {
    245       if ("error" in data) {
    246         $( "#status" ).html("<span class=\"error\">" + htmlentities(data.error) + "</span>");
    247         $( "#errors" ).empty();
    248       } else {
    249         $( "#errors" ).empty();
    250         for (var i = 0; i < data.result.length; i++) {
    251           var err = data.result[i];
    252           for (var j = 0; j < err.errors.length; j++) {
    253             err.errors[j] = htmlentities(err.errors[j]);
    254           }
    255           $( "#errors" ).append("<li onclick=\"gotoLine(" + onlydigits(err.num) + ")\">" +
    256             "<p>" + (lang == "fr"
    257               ? "Erreurs pour la ligne "
    258               : "Errors for line ")
    259             + onlydigits(err.num) + ":</p>" +
    260             "<blockquote>" + htmlentities(err.line) + "</blockquote>" +
    261             "<pre>" + err.errors.join("<br />") + "</pre></li>");
    262         }
    263         if (data.result.length > 0) {
    264           var agreement = (data.result.length == 1 ? "" : "s");
    265           var msg = data.result.length;
    266           if (lang == "fr") {
    267             msg += (" erreur" + agreement + " trouvée" + agreement
    268                 + " en validant le poème&nbsp;!");
    269           } else {
    270             msg += (" error" + agreement
    271               + " found when validating poem" + "!");
    272           }
    273           $( "#status" ).html("<span class=\"error\">" + msg + "</span>");
    274         } else {
    275           if (lang == "fr") {
    276             var msg = "Poème conforme au modèle&nbsp;!";
    277           } else {
    278             var msg = "Poem validated against template!";
    279           }
    280           $( "#status" ).html("<span class=\"success\">" + msg + "</span>");
    281         }
    282       }
    283       $('#check').prop( "disabled", false);
    284     }
    285     });
    286 }
    287 
    288 function loadPredef() {
    289   var predef = $( '#predef' ).val();
    290   if (predef == "custom")
    291     return;
    292   $('#predef option[value="custom"]').prop('selected', true)
    293   $.ajax({
    294     url: "static/tpl/" + predef + ".tpl",
    295     type: "get",
    296     error: function (jqxhr, stat, error) {
    297       reportError(htmlentities(stat) +
    298           (error.length > 0 ? ": " + htmlentities(error) : ""));
    299     },
    300     success: function (data) {
    301       $( '#user_template' ).val(htmlentities(data));
    302       $('#user_template').show();
    303       $('#customize').prop("disabled", true);
    304       resizeAll();
    305     }
    306     });
    307   }
    308 
    309 function toggleCustom() {
    310   if ($( '#predef' ).val() == 'custom') {
    311     $('#user_template').show();
    312     $('#customize').prop( "disabled", true);
    313   } else {
    314     $('#user_template').hide();
    315     $('#customize').prop("disabled", false);
    316   }
    317   resizeAll();
    318 }
    319 
    320 function gotoLine(l) {
    321   var pos = 0;
    322   var lines = $( '#poem' ).val().split('\n');
    323   for (var i = 0; i < l - 1; i++)
    324     pos += lines[i].length + "\n".length;
    325   $( '#poem' ).caretTo(pos);
    326 }
    327 
    328 /* http://stackoverflow.com/a/7055239 */
    329 jQuery(document).ready(function(){
    330    $( '#user_template' ).mouseup(function(){
    331      resizeAllUserTemplate();
    332    });
    333    $( '#user_template' ).dblclick(function(){
    334      resizeAllUserTemplate();
    335    });
    336    $( '#poem' ).mouseup(function(){
    337      resizeAllPoem();
    338    });
    339    $( '#poem' ).dblclick(function(){
    340      resizeAllPoem();
    341    });
    342    $(document).mouseup(function() {
    343      resizeAllLast();
    344    });
    345    resizeAll();
    346 });
    347 
    348 $(document).load(function(e) {
    349   setTimeout(function () {
    350         $(window).resize();
    351   }, 100);
    352 });
    353