blob: 5efdf5ab1a4d6a780d327546ece0e6aa3ae37902 [file] [log] [blame]
Akrone51eaa32020-11-10 09:35:53 +01001"use strict";
2
Nils Diewald0e6992a2015-04-14 20:13:52 +00003define(['util'], function () {
Akronbf713fc2020-10-13 10:44:35 +02004
5 // TODO:
6 // - https://github.com/honza/140medley/blob/master/140medley.js
7 // - https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
8 // - https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
9 // - r.addEventListener("progress", updateProgress, false);
10 // - http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml
11 // - http://stackoverflow.com/questions/6112744/load-javascript-on-demand
Nils Diewald58141332015-04-07 16:18:45 +000012
Leo Reppa6aba9a2021-01-23 20:16:43 +010013 // See https://flaviocopes.com/http-request-headers/ for a list of headers
14
Akron4c33c622018-11-12 13:43:27 +010015 KorAP.URL = KorAP.URL !== undefined ? KorAP.URL : '';
Nils Diewald4347ee92015-05-04 20:32:48 +000016 KorAP.API = KorAP.API || {};
Akronb89863a2018-11-13 16:43:59 +010017
Akronbf713fc2020-10-13 10:44:35 +020018 const legacySigle = new RegExp('^([^_]+)_([^\\.]+)\\.(.+?)$');
19
Akron48b1e4d2015-06-17 18:47:01 +020020 /**
21 * Retrieve information about a match
22 */
Nils Diewald4347ee92015-05-04 20:32:48 +000023 KorAP.API.getMatchInfo = function (match, param, cb) {
Nils Diewald58141332015-04-07 16:18:45 +000024
Nils Diewald4347ee92015-05-04 20:32:48 +000025 // match is a KorAP.Match object
Akronbf713fc2020-10-13 10:44:35 +020026 let url = KorAP.URL + '/corpus';
Akron0b489ad2018-02-02 16:49:32 +010027 /*
28 url += '/' + match.corpusID;
29 url += '/' + match.docID;
30 url += '/' + match.textID;
31 */
Akron19d97fe2016-09-06 20:47:05 +020032
Akron19d97fe2016-09-06 20:47:05 +020033 // This is for legacy support
Akronbf713fc2020-10-13 10:44:35 +020034 const legacy = legacySigle.exec(match.textSigle);
35 let docFragment = "";
Akron7f613e02016-11-07 02:50:44 +010036 if (legacy !== null && legacy[0]) {
Akronb89863a2018-11-13 16:43:59 +010037 docFragment = legacy[1] + '/' + legacy[2] + '/' + legacy[3];
Akron19d97fe2016-09-06 20:47:05 +020038 }
39 else {
Akronb89863a2018-11-13 16:43:59 +010040 docFragment = match.textSigle;
Akron19d97fe2016-09-06 20:47:05 +020041 }
Akronb89863a2018-11-13 16:43:59 +010042
43 docFragment += '/' + match.matchID;
44 url += '/' + docFragment;
Nils Diewald58141332015-04-07 16:18:45 +000045
Nils Diewald4347ee92015-05-04 20:32:48 +000046 // { spans: true, layer:x, foundry : y}
47 if (param['spans'] == true) {
48 url += '?spans=true';
Akronb89863a2018-11-13 16:43:59 +010049 docFragment += ' +spans ';
50 if (param['foundry'] !== undefined) {
Akron515851a2017-05-02 12:53:17 +020051 url += '&foundry=' + param['foundry'];
Akronb89863a2018-11-13 16:43:59 +010052 docFragment += param['foundry'];
53 };
54 if (param['layer'] !== undefined) {
Akron515851a2017-05-02 12:53:17 +020055 url += '&layer=' + param['layer'];
Akronb89863a2018-11-13 16:43:59 +010056 docFragment += '/'+param['layer'];
57 }
Nils Diewald58141332015-04-07 16:18:45 +000058 }
Nils Diewald4347ee92015-05-04 20:32:48 +000059
60 // { spans : false, layer: [Array of KorAP.InfoLayer] }
61 else {
62 // TODO
Akronb89863a2018-11-13 16:43:59 +010063 docFragment += ' -spans';
Nils Diewald4347ee92015-05-04 20:32:48 +000064 url += '?spans=false';
65 }
66
Akronb89863a2018-11-13 16:43:59 +010067 KorAP.API.getJSON(url, cb, "MatchInfo: " + docFragment);
Nils Diewald58141332015-04-07 16:18:45 +000068 };
Nils Diewald4347ee92015-05-04 20:32:48 +000069
Akron0b489ad2018-02-02 16:49:32 +010070
Akron48b1e4d2015-06-17 18:47:01 +020071 /**
Akron0ad7cd22018-02-08 18:03:06 +010072 * Retrieve information about a document.
73 */
74 KorAP.API.getTextInfo = function (doc, param, cb) {
75
76 // doc is a KorAP.Match object
Akronbf713fc2020-10-13 10:44:35 +020077 let url = KorAP.URL + '/corpus' + '/' + doc.textSigle;
Akron0ad7cd22018-02-08 18:03:06 +010078
79 if (param['fields'] !== undefined) {
80 url += '?fields='; // TODO!
81 }
82 else {
Akron4bbd8b32018-03-06 19:19:44 +010083 url += '?fields=@all'; // TODO: Maybe '*'?
Akron0ad7cd22018-02-08 18:03:06 +010084 }
Akronbf713fc2020-10-13 10:44:35 +020085
Akronb89863a2018-11-13 16:43:59 +010086 KorAP.API.getJSON(url, cb, "TextInfo: " + doc.textSigle);
Akron0ad7cd22018-02-08 18:03:06 +010087 };
88
89
90 /**
Akroncd42a142019-07-12 18:55:37 +020091 * Retrieve information about virtual corpora
Akron48b1e4d2015-06-17 18:47:01 +020092 */
93 KorAP.API.getCollections = function (cb) {
Akronb89863a2018-11-13 16:43:59 +010094 KorAP.API.getJSON(KorAP.URL + '/collection', cb, "CorpusInfo");
Akron48b1e4d2015-06-17 18:47:01 +020095 };
96
hebasta0ee50802018-06-20 10:24:45 +020097
98 /**
99 * Retrieve information about corpus statistic
100 *
101 * Example URL: /corpus?cq=availability+%3D+%2FCC-BY.*%2F+%26+textClass+%3D+%22kultur%22
102 *
Leo Reppa6aba9a2021-01-23 20:16:43 +0100103 * @param cq corpus query (formerly collectionQuery)
hebasta0ee50802018-06-20 10:24:45 +0200104 *
105 * Adress the MOJO-Endpoint for example with
106 * http://localhost:3000/corpus?cq=availability+%3D+%2FCC-BY.*%2F+%26+textClass+%3D+%22kultur%22
107 */
108 KorAP.API.getCorpStat = function (cq, cb){
Akronbf713fc2020-10-13 10:44:35 +0200109 let url = KorAP.URL + "/corpus?cq=" + encodeURIComponent(cq);
Akronb89863a2018-11-13 16:43:59 +0100110 KorAP.API.getJSON(url, cb, "CorpusInfo: " + cq);
hebasta0ee50802018-06-20 10:24:45 +0200111 };
Akron8dda1c62021-01-20 10:27:32 +0100112
113
114 /**
115 * Retrieve a list of all plugin objects to
116 * establish in the frontend.
117 */
118 KorAP.API.getPluginList = function (url, cb) {
119 KorAP.API.getJSON(url, cb, "Plugin-List")
120 };
Akronbf713fc2020-10-13 10:44:35 +0200121
hebasta4ba496a2018-06-05 15:56:01 +0200122 /**
Leo Reppa6aba9a2021-01-23 20:16:43 +0100123 * General function to communicate JS Objects with the server
124 *
125 * @param {HTTMLRequestType} requestType Should be "GET", "PUT", "POST" or "DELETE"
126 * @param {String} url The url that specifies where the JSON file is ("GET"), will be ("PUT" and "POST") or will have been ("DELETE")
127 * @param {String} title How to store this request in the logs
128 * @param {JSObj} jsObj For "PUT" and "POST". The JS Object that is getting transfered. This function stringifies it.
129 * @param {function} returnValueCB For "GET". The callback function that receives the retrieved JS object (already parsed) as a parameter, or undefined if none is eligible
130 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
131 */
132 function _actionJSON (requestType, url, title, jsObj, returnValueCB, errorCB) {
Akronbf713fc2020-10-13 10:44:35 +0200133 const req = new XMLHttpRequest();
Leo Reppa6aba9a2021-01-23 20:16:43 +0100134 req.open(requestType, url, true);
135 // Dispatch global "window" event. See Kalamar::Plugin::Piwik
Akronbf713fc2020-10-13 10:44:35 +0200136 const reqE = new CustomEvent('korapRequest', {
Akron4c33c622018-11-12 13:43:27 +0100137 bubbles : false,
Akronb89863a2018-11-13 16:43:59 +0100138 detail: {
139 "url" : url,
140 "title" : title
141 }
Akron4c33c622018-11-12 13:43:27 +0100142 });
143 window.dispatchEvent(reqE);
144
Nils Diewald4347ee92015-05-04 20:32:48 +0000145 req.setRequestHeader("Accept", "application/json");
Leo Repp8e21cbe2021-08-18 16:37:52 +0200146 req.setRequestHeader("Content-Type", "application/json"); //https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type //this doesnt fit
Leo Reppa6aba9a2021-01-23 20:16:43 +0100147 req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
Leo Repp8e21cbe2021-08-18 16:37:52 +0200148 //req.setRequestHeader('Origin',"API");
Nils Diewald4347ee92015-05-04 20:32:48 +0000149 req.onreadystatechange = function () {
150 /*
Akron0b489ad2018-02-02 16:49:32 +0100151 States:
152 0 - unsent (prior to open)
153 1 - opened (prior to send)
154 2 - headers received
155 3 - loading (responseText has partial data)
156 4 - done
Nils Diewald4347ee92015-05-04 20:32:48 +0000157 */
158 if (this.readyState == 4) {
Akron515851a2017-05-02 12:53:17 +0200159
Leo Reppa6aba9a2021-01-23 20:16:43 +0100160 if (requestType === "GET") { //GET
161 let retJSObj;
162 try {
163 retJSObj = JSON.parse(this.responseText);
164 }
165 catch (e) {
166 KorAP.log(0, e);
167 console.log(e);
168 returnValueCB(undefined);
169 return;
170 };
171
172 if (retJSObj !== undefined && retJSObj["errors"] !== undefined) {
173 retJSObj["errors"].forEach(
174 e => KorAP.log(e[0], e[1] || "Unknown")
175 );
176 }
177
178 else if (this.status !== 200) {
179 KorAP.log(this.status, this.statusText, "Remote service error (XMLHttpRequest) under URL: " + url);
180 };
181
182 if (this.status === 200) {
183 returnValueCB(retJSObj);
184 }
185
186 else {
187 returnValueCB(undefined);
188 };
189
190 } else { // PUT, POST, DELETE
191 if (this.status >= 300 || this.status < 200) { //Error
192 KorAP.log(this.status, this.statusText, "Remote service error (XMLHttpRequest) under URL: " + url);
193 };
Akronb5d05d72018-02-12 15:09:12 +0100194 };
Leo Reppa6aba9a2021-01-23 20:16:43 +0100195 // Call the callback function (no matter requestType) if one is given.
196 if (typeof(errorCB) === "function"){
197 errorCB({
198 "status" : this.status,
199 "statusText" : this.statusText
200 });
201 };
202 };
Nils Diewald4347ee92015-05-04 20:32:48 +0000203 };
Akronbf713fc2020-10-13 10:44:35 +0200204
Leo Reppa6aba9a2021-01-23 20:16:43 +0100205 /*Set a value for .timeout to use this functionality */
206 //req.ontimeout = function () {
207 // KorAP.log(0, 'Request Timeout');
208 //};
209 if (requestType === "POST" || requestType === "PUT") {
210 req.send(JSON.stringify(jsObj));
211 } else { //GET, DELETE
212 req.send();
Nils Diewald4347ee92015-05-04 20:32:48 +0000213 };
Leo Reppa6aba9a2021-01-23 20:16:43 +0100214 };
215
216 /**
217 * General method to get JSON information.
218 *
219 * @param {String} url The url at which the JSON File will be located
220 * @param {function} returnValueCB The callback function that receives the retrieved JS object (already parsed) as a parameter, or undefined if none is eligible
221 * @param {String} title How to store this request in the logs
222 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
223 */
224 KorAP.API.getJSON = function (url, returnValueCB, title, errorCB) {
225 _actionJSON("GET", url, title, undefined, returnValueCB, errorCB);
226 };
227
228 /**
229 * General method to put JSON information.
230 *
231 * @param {String} url The url at which the JSON File will be located
232 * @param {JSObj} jsObj The JS object that is getting transfered. This will be stringified
233 * @param {String} title How to store this request in the logs
234 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
235 */
236 KorAP.API.putJSON = function (url, jsObj, title, errorCB) {
237 _actionJSON("PUT", url, title, jsObj, undefined, errorCB);
238 };
239
240 /**
241 * General method to post JSON information.
242 *
243 * @param {String} url The url at which the JSON File will be located
244 * @param {JSObj} jsObj The JS object that is getting transfered. This will be stringified
245 * @param {String} title How to store this request in the logs
246 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
247 */
248 KorAP.API.postJSON = function (url, jsObj, title, errorCB) {
249 _actionJSON("POST", url, title, jsObj, undefined, errorCB);
250 };
251
252 /**
253 * General method to delete a file at a specific URL
254 *
255 * @param {String} url The url at which the to be deleted file is located
256 * @param {String} title How to store this request in the logs
257 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
258 */
259 KorAP.API.deleteJSON = function (url, title, errorCB) {
260 _actionJSON("DELETE", url, title, undefined, undefined, errorCB);
261 };
262
263
264 // Stored query related functions
265
266 /**
267 * Retrieve saved list of queries
268 *
269 * @param {function} returnValueCB The callback function that receives the JS object Listof queries, already parsed
270 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
271 */
272 KorAP.API.getQueryList = function (returnValueCB, errorCB){
273 KorAP.API.getJSON(KorAP.URL + "/query/", returnValueCB, "getSavedQueryList", errorCB);
274 };
275
276 /**
277 * Retrieve specific saved query by query name
278 *
279 * @param {String} qn The name of the query to be retrieved. Must be a string
280 * @param {function} returnValueCB The callback function that receives the query JS object Object, already parsed
281 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
282 */
283 KorAP.API.getQuery = function (qn, returnValueCB, errorCB){
284 KorAP.API.getJSON(KorAP.URL + "/query/" + qn, returnValueCB, "getSavedQuery of name "+ qn, errorCB);
285 };
286
287 /**
288 * Put new query by query name
289 *
290 * @param {String} qn The name of the new query
291 * @param {JSObj} jsObj The query. This will be stringified
292 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
293 */
294 KorAP.API.putQuery = function (qn, jsObj, errorCB){
295 KorAP.API.putJSON(KorAP.URL + "/query/" + qn, jsObj, "putQuery of name "+ qn, errorCB);
296 };
297
298 /**
299 * Post new query by query name
300 *
301 * @param {String} qn The name of the new query
302 * @param {JSObj} jsObj The query. This will be stringified
303 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
304 */
305 KorAP.API.postQuery = function (qn, jsObj, errorCB){
306 KorAP.API.postJSON(KorAP.URL + "/query/" + qn, jsObj, "postQuery of name "+ qn, errorCB);
307 };
308
309 /**
310 * delete query by query name
311 *
312 * @param {String} qn The name of the to be deleted query
313 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
314 */
315 KorAP.API.deleteQuery = function (qn, errorCB){
316 KorAP.API.deleteJSON(KorAP.URL + "/query/" + qn, "deleteQuery of name "+ qn, errorCB);
317 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000318});