picolisp

Unnamed repository; edit this file to name it for gitweb.
git clone https://logand.com/git/picolisp.git/
Log | Files | Refs | README | LICENSE

form.js (16143B)


      1 /* 26jun13abu
      2  * (c) Software Lab. Alexander Burger
      3  */
      4 
      5 var FormReq = new XMLHttpRequest();
      6 FormReq.upload.addEventListener("progress", dropProgress, false);
      7 FormReq.upload.addEventListener("load", dropLoad, false);
      8 
      9 var Btn = [];
     10 var Queue = [];
     11 var SesId, Key, InBtn, Auto, Chg, Drop, Hint, Hints, Item, Beg, End;
     12 
     13 function inBtn(flg) {InBtn = flg;}
     14 
     15 function formKey(event) {
     16    Key = event.keyCode;
     17    if (Hint  &&  Hint.style.visibility == "visible") {
     18       if ((Item >= 0 && Key == 13) || Key == 38 || Key == 40)
     19          return false;
     20       if (event.keyCode == 27) {
     21          Hint.style.visibility = "hidden";
     22          return false;
     23       }
     24    }
     25    if (event.charCode || event.keyCode == 8)
     26       Chg = true;
     27    return true;
     28 }
     29 
     30 function fldChg(field) {
     31    Chg = true;
     32    if (!InBtn && Key != 13)
     33       post(field.form, false, null, null);
     34    return true;
     35 }
     36 
     37 function doBtn(btn) {
     38    Btn.push(btn);
     39    return true;
     40 }
     41 
     42 function doDrag(event) {
     43    event.stopPropagation();
     44    event.preventDefault();
     45 }
     46 
     47 function doDrop(btn, event) {
     48    doDrag(event);
     49    if (event.dataTransfer.files.length != 0) {
     50       Btn.push(Drop = btn);
     51       btn.value = "0 %";
     52       post(btn.form, false, null, event.dataTransfer.files[0]);
     53    }
     54 }
     55 
     56 function dropProgress(event) {
     57    if (Drop)
     58       Drop.value = event.lengthComputable?
     59          Math.round((event.loaded * 100) / event.total) + " %" : "(?) %";
     60 }
     61 
     62 function dropLoad(event) {
     63    Drop = null;
     64 }
     65 
     66 function hasElement(form, name) {
     67    for (var i = 0; i < form.elements.length; ++i)
     68       if (form.elements[i].name == name)
     69          return true;
     70    return false;
     71 }
     72 
     73 function setHref(fld, url) {
     74    var i = url.indexOf("~");
     75 
     76    if (url.charAt(i = i>=0? i+1 : 0) == "+")  {
     77       url = url.substr(0,i) + url.substr(i+1);
     78       fld.target = "_blank";
     79    }
     80    fld.href = decodeURIComponent(url);
     81 }
     82 
     83 /*** Form submit ***/
     84 function doPost(form) {
     85    for (var i = 0; ; ++i) {
     86       if (i == Btn.length)
     87          return true;
     88       if (Btn[i].form == form)
     89          return post(form, false, null, null);
     90    }
     91 }
     92 
     93 function post(form, auto, exe, file) {
     94    var i, data;
     95 
     96    if (!FormReq || !hasElement(form,"*Get") || (i = form.action.indexOf("~")) <= 0)
     97       return true;
     98    if (FormReq.readyState > 0 && FormReq.readyState < 4) {
     99       Queue.push([form, auto, exe, file]);
    100       return false;
    101    }
    102    form.style.cursor = "wait";
    103    try {FormReq.open("POST", SesId + "!jsForm?" + form.action.substr(i+1));}
    104    catch (e) {return true;}
    105    FormReq.onload = function() {
    106       var i, j;
    107 
    108       if (FormReq.responseText == "T") {
    109          Queue.length = 0;
    110          form.submit();
    111       }
    112       else {
    113          var txt = FormReq.responseText.split("&");
    114 
    115          if (txt[0]) {
    116             var r = txt[0].split(":");
    117 
    118             if (Auto)
    119                clearTimeout(Auto);
    120             if (!r[1])
    121                Auto = null;
    122             else {
    123                Auto = setTimeout(function() {
    124                   if (Chg)
    125                      Auto = setTimeout(arguments.callee, r[1]);
    126                   else {
    127                      Btn.push(document.getElementById(r[0]));
    128                      post(form, true, null, null);
    129                   }
    130                }, r[1] );
    131             }
    132          }
    133          if (!auto || !Chg) {
    134             for (i = 1; i < txt.length;) {
    135                var fld = txt[i++];
    136                var val = decodeURIComponent(txt[i++]);
    137 
    138                if (!fld) {
    139                   window[txt[i++]](val);
    140                   continue;
    141                }
    142                if (!(fld = document.getElementById(fld)))
    143                   continue;
    144                if (fld.tagName == "SPAN") {
    145                   if (i != txt.length && txt[i].charAt(0) == "=")
    146                      ++i;
    147                   if (i == txt.length || txt[i].charAt(0) != "+") {
    148                      if (fld.firstChild.tagName != "A")
    149                         fld.firstChild.data = val? val : "\u00A0";
    150                      else
    151                         fld.replaceChild(document.createTextNode(val? val : "\u00A0"), fld.firstChild);
    152                   }
    153                   else {
    154                      var a = document.createElement("A");
    155 
    156                      setHref(a, txt[i++].substr(1));
    157                      a.appendChild(document.createTextNode(val));
    158                      fld.replaceChild(a, fld.firstChild);
    159                   }
    160                }
    161                else if (fld.tagName == "A") {
    162                   if (i != txt.length && txt[i].charAt(0) == "=")
    163                      ++i;
    164                   if (i == txt.length || txt[i].charAt(0) != "+") {
    165                      fld.replaceChild(document.createTextNode(val? val : "\u00A0"), fld.firstChild);
    166                      fld.removeAttribute("href");
    167                   }
    168                   else {
    169                      fld.firstChild.data = val;
    170                      setHref(fld, txt[i++].substr(1));
    171                   }
    172                }
    173                else if (fld.tagName == "IMG") {
    174                   var parent = fld.parentNode;
    175 
    176                   fld.src = val;
    177                   fld.alt = txt[i++];
    178                   if (parent.tagName == "A") {
    179                      if (txt[i])
    180                         setHref(parent, txt[i]);
    181                      else {
    182                         var grand = parent.parentNode;
    183 
    184                         grand.removeChild(parent);
    185                         grand.appendChild(fld);
    186                      }
    187                   }
    188                   else if (txt[i]) {
    189                      var a = document.createElement("A");
    190 
    191                      parent.removeChild(fld);
    192                      parent.appendChild(a);
    193                      a.appendChild(fld);
    194                      setHref(a, txt[i]);
    195                   }
    196                   ++i;
    197                }
    198                else {
    199                   if (fld.type == "checkbox") {
    200                      fld.checked = val != "";
    201                      document.getElementsByName(fld.name)[0].value = "";
    202                   }
    203                   else if (fld.type == "select-one") {
    204                      for (j = 0; j < fld.options.length; ++j) {
    205                         if (fld.options[j].text == val)
    206                            fld.selectedIndex = j;
    207                         fld.options[j].disabled = false;
    208                      }
    209                   }
    210                   else if (fld.type == "radio") {
    211                      fld.value = val;
    212                      fld.checked = txt[i++].charAt(0) != "";
    213                   }
    214                   else if (fld.type == "image")
    215                      fld.src = val;
    216                   else if (fld.value != val) {
    217                      fld.value = val;
    218                      fld.scrollTop = fld.scrollHeight;
    219                   }
    220                   fld.disabled = false;
    221                   if (i < txt.length && txt[i].charAt(0) == "=") {
    222                      if (fld.type == "select-one") {
    223                         for (j = 0; j < fld.options.length; ++j)
    224                            if (fld.options[j].text != val)
    225                               fld.options[j].disabled = true;
    226                      }
    227                      fld.disabled = true;
    228                      InBtn = 0;  // 'onblur' on won't come when disabled
    229                      if (fld.type == "checkbox"  &&  fld.checked)
    230                         document.getElementsByName(fld.name)[0].value = "T";
    231                      ++i;
    232                   }
    233                }
    234                while (i < txt.length && (j = "#*?".indexOf(txt[i].charAt(0))) >= 0) {
    235                   switch (j) {
    236 
    237                   case 0:  // '#'
    238                      var cls;
    239 
    240                      val = txt[i++].substr(1);
    241                      if ((cls = fld.getAttribute("class")) != null  &&  (j = cls.indexOf(" ")) >= 0)
    242                         val += cls.substr(j);
    243                      fld.setAttribute("class", val);
    244                      break;
    245 
    246                   case 1:  // '*'
    247                      var node = fld.parentNode.parentNode.lastChild;
    248                      var img = document.createElement("IMG");
    249 
    250                      if (!node.firstChild)
    251                         node = fld.parentNode.parentNode.parentNode.lastChild;
    252                      node.removeChild(node.firstChild);
    253                      img.src = txt[i++].substr(1);
    254                      if (!txt[i])
    255                         node.appendChild(img);
    256                      else {
    257                         var a = document.createElement("A");
    258 
    259                         setHref(a, txt[i]);
    260                         a.appendChild(img);
    261                         node.appendChild(a);
    262                      }
    263                      ++i;
    264                      break;
    265 
    266                   case 2:  // '?'
    267                      fld.title = decodeURIComponent(txt[i++].substr(1));
    268                      break;
    269                   }
    270                }
    271             }
    272             Chg = false;
    273          }
    274       }
    275       form.style.cursor = "";
    276       if (Queue.length > 0) {
    277          var a = Queue.shift();
    278          post(a[0], a[1], a[2], a[3]);
    279       }
    280    }
    281    if (!exe)
    282       data = "";
    283    else {
    284       data = "*Gui:0:=" + exe[0];
    285       for (var i = 1; i < exe.length; ++i)
    286          data += "&*JsArgs:" + i + ":=" + exe[i];
    287    }
    288    for (i = 0; i < Btn.length;)
    289       if (Btn[i].form != form)
    290          ++i;
    291       else {
    292          data += "&" + Btn[i].name + "=" + encodeURIComponent(Btn[i].type == "submit"? Btn[i].value : Btn[i].src);
    293          Btn.splice(i,1);
    294       }
    295    for (i = 0; i < form.elements.length; ++i) {
    296       var fld = form.elements[i];
    297 
    298       if (fld.name  &&  fld.type != "submit") {   // "image" won't come :-(
    299          var val;
    300 
    301          if (fld.type == "checkbox")
    302             val = fld.checked? "T" : "";
    303          else if (fld.type == "select-one")
    304             val = fld.options[fld.selectedIndex].text;
    305          else if (fld.type == "radio" && !fld.checked)
    306             continue;
    307          else
    308             val = fld.value;
    309          data += "&" + fld.name + "=" + encodeURIComponent(val.replace(/ +$/,""));
    310       }
    311    }
    312    try {
    313       if (!file)
    314          FormReq.send(data);
    315       else {
    316          var rd = new FileReader();
    317          rd.readAsBinaryString(file);
    318          rd.onload = function() {
    319             FormReq.setRequestHeader("X-Pil", "*ContLen=");
    320             FormReq.sendAsBinary(data + "&*Drop=" +
    321                encodeURIComponent(file.name) + "=" +
    322                file.size + "\n" + rd.result );
    323          }
    324       }
    325    }
    326    catch (e) {
    327       FormReq.abort();
    328       return true;
    329    }
    330    return false;
    331 }
    332 
    333 /*** Hints ***/
    334 function doHint(field) {
    335    if (!Hint) {
    336       Hint = document.createElement("div");
    337       Hint.setAttribute("class", "hint");
    338       Hint.style.visibility = "hidden";
    339       Hint.style.position = "absolute";
    340       Hint.style.zIndex = 9999;
    341       Hint.style.textAlign = "left";
    342       Hints = document.createElement("div");
    343       Hints.setAttribute("class", "hints");
    344       Hints.style.position = "relative";
    345       Hints.style.top = "-2px";
    346       Hints.style.left = "-3px";
    347       Hint.appendChild(Hints);
    348    }
    349    field.parentNode.appendChild(Hint);
    350    field.onblur = function() {
    351       Hint.style.visibility = "hidden";
    352    }
    353    var top = field.offsetHeight + 2;
    354    var left = 3;
    355    for (var obj = field;  obj.id != "main" && obj.id != "menu";  obj = obj.offsetParent) {
    356       top += obj.offsetTop;
    357       left += obj.offsetLeft;
    358    }
    359    Hint.style.top = top + "px";
    360    Hint.style.left = left + "px";
    361 }
    362 
    363 function hintKey(field, event, tok, coy) {
    364    var i, data;
    365 
    366    if (event.keyCode == 9 || event.keyCode == 27)
    367       return false;
    368    if (Hint.style.visibility == "visible") {
    369       if (Item >= 0 && event.keyCode == 13) {
    370          setHint(field, Hints.childNodes[Item]);
    371          return false;
    372       }
    373       if (event.keyCode == 38) {  // Up
    374          if (Item > 0) {
    375             hintOff(Item);
    376             hintOn(--Item);
    377          }
    378          return false;
    379       }
    380       if (event.keyCode == 40) {  // Down
    381          if (Item < (lst = Hints.childNodes).length-1) {
    382             if (Item >= 0)
    383                hintOff(Item);
    384             hintOn(++Item);
    385          }
    386          return false;
    387       }
    388    }
    389    if (event.keyCode == 13)
    390       return true;
    391    var req = new XMLHttpRequest();
    392    if (tok) {
    393       for (Beg = field.selectionStart;  Beg > 0 && !field.value.charAt(Beg-1).match(/\s/);  --Beg);
    394       End = field.selectionEnd;
    395    }
    396    else {
    397       Beg = 0;
    398       End = field.value.length;
    399    }
    400    if (event.keyCode != 45) {  // INS
    401       if (Beg == End) {
    402          Hint.style.visibility = "hidden";
    403          return false;
    404       }
    405       if (coy && Hint.style.visibility == "hidden")
    406          return false;
    407    }
    408    try {
    409       req.open("POST", (SesId? SesId : "") +
    410          ((i = field.id.lastIndexOf("-")) < 0?
    411             "!jsHint?$" + field.id : "!jsHint?+" + field.id.substr(i+1) ) );
    412    }
    413    catch (e) {return true;}
    414    req.onload = function() {
    415       var i, n, lst, str;
    416 
    417       if ((str = req.responseText).length == 0)
    418          Hint.style.visibility = "hidden";
    419       else {
    420          lst = str.split("&");
    421          while (Hints.hasChildNodes())
    422             Hints.removeChild(Hints.firstChild);
    423          for (i = 0, n = 7; i < lst.length; ++i) {
    424             addHint(i, field, str = decodeURIComponent(lst[i]));
    425             if (str.length > n)
    426                n = str.length;
    427          }
    428          Hints.style.width = n + 3 + "ex";
    429          Hint.style.width = n + 4 + "ex";
    430          Hint.style.visibility = "visible";
    431          Item = -1;
    432       }
    433    }
    434    var data = "*JsHint=" + encodeURIComponent(field.value.substring(Beg,End));
    435    for (i = 0; i < field.form.elements.length; ++i) {
    436       var fld = field.form.elements[i];
    437 
    438       if (fld.name == "*Get")
    439          data += "&*Get=" + fld.value;
    440       else if (fld.name == "*Form")
    441          data += "&*Form=" + fld.value;
    442    }
    443    try {req.send(data);}
    444    catch (e) {
    445       req.abort();
    446       return true;
    447    }
    448    return (event.keyCode != 45);  // INS
    449 }
    450 
    451 function addHint(i, field, str) {
    452    var item = document.createElement("div");
    453    item.appendChild(document.createTextNode(str));
    454    item.onmouseover = function() {
    455       if (Item >= 0)
    456          hintOff(Item);
    457       hintOn(i);
    458       field.onblur = false;
    459       field.onchange = false;
    460       Item = i;
    461    }
    462    item.onmouseout = function() {
    463       hintOff(Item);
    464       field.onblur = function() {
    465          Hint.style.visibility = "hidden";
    466       }
    467       field.onchange = function() {
    468          return fldChg(field, item);
    469       };
    470       Item = -1;
    471    }
    472    item.onclick = function() {
    473       setHint(field, item);
    474    }
    475    Hints.appendChild(item);
    476 }
    477 
    478 function setHint(field, item) {
    479    Hint.style.visibility = "hidden";
    480    field.value = field.value.substr(0,Beg) + item.firstChild.nodeValue + field.value.substr(End);
    481    Chg = true;
    482    post(field.form, false, null, null);
    483    field.setSelectionRange(Beg + item.firstChild.nodeValue.length, field.value.length);
    484    field.focus();
    485    field.onchange = function() {
    486       return fldChg(field)
    487    };
    488 }
    489 
    490 function hintOn(i) {
    491    var s = Hints.childNodes[i].style;
    492    s.background = "black";
    493    s.color= "white";
    494 }
    495 
    496 function hintOff(i) {
    497    var s = Hints.childNodes[i].style;
    498    s.background = "white";
    499    s.color= "black";
    500 }
    501 
    502 /*** Lisp calls ***/
    503 function lisp(form, fun) {
    504    if (form) {
    505       var exe = [fun];
    506 
    507       for (var i = 2; i < arguments.length; ++i)
    508          if (typeof arguments[i] === "number")
    509             exe[i-1] = "+" + arguments[i];
    510          else
    511             exe[i-1] = "." + encodeURIComponent(arguments[i]);
    512       return post(form, false, exe, null);
    513    }
    514    if (arguments.length > 2) {
    515       fun += "?" + lispVal(arguments[2]);
    516       for (var i = 3; i < arguments.length; ++i)
    517          fun += "&" + lispVal(arguments[i]);
    518    }
    519    var req = new XMLHttpRequest();
    520    try {req.open("GET", SesId + "!" + fun);}
    521    catch (e) {return true;}
    522    try {req.send(null);}
    523    catch (e) {
    524       req.abort();
    525       return true;
    526    }
    527    setTimeout(function(){req.abort();}, 40);  // No response expected
    528    return false;
    529 }
    530 
    531 function lispVal(x) {
    532    if (typeof x === "number")
    533       return "+" + x;
    534    if (x.charAt(0) == "-")
    535       return "%2D" + encodeURIComponent(x.substr(1));
    536    return encodeURIComponent(x);
    537 }