Ajax のライブラリを勉強のために書き直す。FireFoxとiPadで動けばそれでよし。

やっぱり勉強しないと理解できない。

// Ajax のライブラリ

(function () {

  function uriEncode (parm) {
    var result = [ ];
    var pm, dv, prop;
    var i, I;
    
    if (parm == null || parm == '')
      return '';
    
    switch (typeof parm) {
    case 'string' :
      if (0 === parm.indexOf ('\u0026'))
        parm = parm.substring (1, parm.length);

      pm = parm.split ('\u0026');
      for (i = 0, I = pm.length; i < I; i += 1)
        result.push (encode.apply (null, pm[i].split ('=')));//正規表現は重いだろう
      break;

    case 'object' :
      for (prop in parm)
        if (parm.hasOwnProperty (prop))
          result.push (encode (prop, parm[prop] || ''));
      break;

    default :
      throw new Error; 
    }

    return result.join ('\u0026');
  }


  function encode (prop) {
    var val = Array.prototype.splice.call (arguments, 1).join ('=');//String.splitが…
    return encodeURIComponent (prop) + '=' + encodeURIComponent (val);
  }
  
  //____________________

  function handler (event) {
    var req, result, status;
    
    if ((req = event.target)) {
      if (4 === req.readyState) {
        try {
          status = req.status;
          switch (true) {
          case 304 === status :
          case 199 < status && status < 300:
            result = req.responseText;
            break
                 
          case 0 === req.status :
          default :
            result = 'Error!!(' + status + ') 通信は失敗しました';
            break;
          }
          req.abort ();
          req.removeEventListener ('readystatechange', this, false);
          req = null;
        }
        catch (err) {
          throw new Error (err);
        }

        if ('undefined' !== typeof result)
          this.callBackFunc.call (this.callBackObj, result);
      }
    }
  }

//____________________
/*
  parm = 'a=123&b=456=789';
  parm = {a: 123, b:"456=789"};
*/
  function ajax (parm, url, method, async, callBackFunc, callBackObj) {

    Init : {
      var METHOD = (method.toUpperCase () === 'GET') ? 'GET': 'POST';
      var httpRequest = new XMLHttpRequest ();
      var result;

      if (! httpRequest)
        throw new Error ('XMLHTTP インスタンスを生成できませんでした');

      if ((async = !!async)) {
        httpRequest.addEventListener (
          'readystatechange', {
            handleEvent  : handler,
            callBackFunc : callBackFunc,
            callBackObj  : callBackObj || null
          }, false);
      }

      parm = uriEncode (parm);//先頭の'?'は取り除かれている
    }


    Open_Set : {
      switch (METHOD) {
      case 'POST' :
        httpRequest.open (METHOD, url, async);
        httpRequest.setRequestHeader ('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
        httpRequest.setRequestHeader ('Pragma', 'no-cache');
        httpRequest.setRequestHeader ('Cache-Control', 'no-cache');
        httpRequest.send (parm);
        break;
      
      case 'GET' :
        httpRequest.open (METHOD, url + '?' + parm, async);
        httpRequest.setRequestHeader ('Pragma', 'no-cache');
        httpRequest.setRequestHeader ('Cache-Control', 'no-cache');
        httpRequest.send (null);
        break;
      
      default :
        throw new Error ('');
      }
    }
    
    
    Final : {
      if (! async) {
        result = httpRequest.responseText;

        if (0 === result.indexOf ('Error'))
          throw new Error (result);
        
        httpRequest.abort ();
        httpRequest = null;
        
        if ('function' === typeof callBackFunc)
          return callBackFunc.call (this.callBackObj, result);
        else
          return result;
      }
    }
  }
  
  this.Ajax = ajax;
}) ();