Fossil

Diff
Login

Differences From Artifact [937316a3ee]:

To Artifact [a083bb72ea]:


38
39
40
41
42
43
44
45


46
47
48
49
50
51











52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
   - contentType: Optional request content type when POSTing. Ignored
   if the method is not 'POST'.

   - responseType: optional string. One of ("text", "arraybuffer",
   "blob", or "document") (as specified by XHR2). Default = "text".
   As an extension, it supports "json", which tells it that the
   response is expected to be text and that it should be JSON.parse()d
   before passing it on to the onload() callback.



   - urlParams: string|object. If a string, it is assumed to be a
   URI-encoded list of params in the form "key1=val1&key2=val2...",
   with NO leading '?'.  If it is an object, all of its properties get
   converted to that form. Either way, the parameters get appended to
   the URL before submitting the request.












   When an options object does not provide onload() or onerror()
   handlers of its own, this function falls back to
   fossil.fetch.onload() and fossil.fetch.onerror() as defaults. The
   default implementations route the data through the dev console and
   (for onerror()) through fossil.error(). Individual pages may
   overwrite those members to provide default implementations suitable
   for the page's use.

   Returns this object, noting that the XHR request is asynchronous,
   and still in transit (or has yet to be sent) when that happens.
*/
window.fossil.fetch = function f(uri,opt){
  const F = fossil;
  if(!f.onerror){
    f.onerror = function(e/*event or exception*/){
      console.error("Ajax error:",e);
      if(e instanceof Error){
        F.error('Exception:',e);
      }
      else if(e.originalTarget && e.originalTarget.responseType==='text'){
        const txt = e.originalTarget.responseText;







|
>
>






>
>
>
>
>
>
>
>
>
>
>














|







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
   - contentType: Optional request content type when POSTing. Ignored
   if the method is not 'POST'.

   - responseType: optional string. One of ("text", "arraybuffer",
   "blob", or "document") (as specified by XHR2). Default = "text".
   As an extension, it supports "json", which tells it that the
   response is expected to be text and that it should be JSON.parse()d
   before passing it on to the onload() callback. If parsing of such
   an object fails, the onload callback is not called, and the
   onerror() callback is passed the exception from the parsing error.

   - urlParams: string|object. If a string, it is assumed to be a
   URI-encoded list of params in the form "key1=val1&key2=val2...",
   with NO leading '?'.  If it is an object, all of its properties get
   converted to that form. Either way, the parameters get appended to
   the URL before submitting the request.

   - responseHeaders: If true, the onload() callback is passed an
   additional argument: a map of all of the response headers. If it's
   a string value, the 2nd argument passed to onload() is instead the
   value of that single header. If it's an array, it's treated as a
   list of headers to return, and the 2nd argument is a map of those
   header values. When a map is passed on, all of its keys are
   lower-cased. When a single header is requested and that header is
   set multiple times, they are (per the XHR docs) concatenated
   together with ", " between them.


   When an options object does not provide onload() or onerror()
   handlers of its own, this function falls back to
   fossil.fetch.onload() and fossil.fetch.onerror() as defaults. The
   default implementations route the data through the dev console and
   (for onerror()) through fossil.error(). Individual pages may
   overwrite those members to provide default implementations suitable
   for the page's use.

   Returns this object, noting that the XHR request is asynchronous,
   and still in transit (or has yet to be sent) when that happens.
*/
window.fossil.fetch = function f(uri,opt){
  const F = fossil;
  if(!f.onerror){/* "static" functions... */
    f.onerror = function(e/*event or exception*/){
      console.error("Ajax error:",e);
      if(e instanceof Error){
        F.error('Exception:',e);
      }
      else if(e.originalTarget && e.originalTarget.responseType==='text'){
        const txt = e.originalTarget.responseText;
81
82
83
84
85
86
87











88

89
90
91
92
93
94
95
          if(j.error){ F.error(j.error) };
        }catch(e){/* Try harder */
          F.error(txt)
        }
      }
    };
    f.onload = (r)=>console.debug('ajax response:',r);











  }

  if('/'===uri[0]) uri = uri.substr(1);
  if(!opt) opt = {};
  else if('function'===typeof opt) opt={onload:opt};
  if(!opt.onload) opt.onload = f.onload;
  if(!opt.onerror) opt.onerror = f.onerror;
  let payload = opt.payload, jsonResponse = false;
  if(undefined!==payload){







>
>
>
>
>
>
>
>
>
>
>
|
>







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
          if(j.error){ F.error(j.error) };
        }catch(e){/* Try harder */
          F.error(txt)
        }
      }
    };
    f.onload = (r)=>console.debug('ajax response:',r);
    f.parseResponseHeaders = function(h){
      const rc = {};
      if(!h) return rc;
      const ar = h.trim().split(/[\r\n]+/);
      ar.forEach(function(line) {
        const parts = line.split(': ');
        const header = parts.shift();
        const value = parts.join(': ');
        rc[header.toLowerCase()] = value;
      });
      return rc;
    };
  }/*static init*/
  if('/'===uri[0]) uri = uri.substr(1);
  if(!opt) opt = {};
  else if('function'===typeof opt) opt={onload:opt};
  if(!opt.onload) opt.onload = f.onload;
  if(!opt.onerror) opt.onerror = f.onerror;
  let payload = opt.payload, jsonResponse = false;
  if(undefined!==payload){
116
117
118
119
120
121
122
123
124
125
126
127
128












129
130
131


132
133
134
135
136
137
138
139
140
       list. We use it as a flag to tell us to JSON.parse()
       the response. */
    jsonResponse = true;
    x.responseType = 'text';
  }else{
    x.responseType = opt.responseType||'text';
  }
  if(opt.onload){
    x.onload = function(e){
      if(200!==this.status){
        if(opt.onerror) opt.onerror(e);
        return;
      }












      try{
        opt.onload((jsonResponse && this.response)
                   ? JSON.parse(this.response) : this.response);


      }catch(e){
        if(opt.onerror) opt.onerror(e);
      }
    }
  }
  if(undefined!==payload) x.send(payload);
  else x.send();
  return this;
};







<
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
>
>
|
|
|
|
<




141
142
143
144
145
146
147

148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

174
175
176
177
       list. We use it as a flag to tell us to JSON.parse()
       the response. */
    jsonResponse = true;
    x.responseType = 'text';
  }else{
    x.responseType = opt.responseType||'text';
  }

  x.onload = function(e){
    if(200!==this.status){
      if(opt.onerror) opt.onerror(e);
      return;
    }
    const orh = opt.responseHeaders;
    let head;
    if(true===orh){
      head = f.parseResponseHeaders(this.getAllResponseHeaders());
    }else if('string'===typeof orh){
      head = this.getResponseHeader(orh);
    }else if(orh instanceof Array){
      head = {};
      orh.forEach((s)=>{
        if('string' === typeof s) head[s.toLowerCase()] = x.getResponseHeader(s);
      });
    }
    try{
      const args = [(jsonResponse && this.response)
                    ? JSON.parse(this.response) : this.response];
      if(head) args.push(head);
      opt.onload.apply(opt, args);
    }catch(e){
      if(opt.onerror) opt.onerror(e);
    }
  };

  if(undefined!==payload) x.send(payload);
  else x.send();
  return this;
};