| Akron | e51eaa3 | 2020-11-10 09:35:53 +0100 | [diff] [blame] | 1 | "use strict"; | 
|  | 2 |  | 
| Nils Diewald | 0e6992a | 2015-04-14 20:13:52 +0000 | [diff] [blame] | 3 | define(['util'], function () { | 
| Akron | bf713fc | 2020-10-13 10:44:35 +0200 | [diff] [blame] | 4 |  | 
|  | 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 Diewald | 5814133 | 2015-04-07 16:18:45 +0000 | [diff] [blame] | 12 |  | 
| Leo Repp | a6aba9a | 2021-01-23 20:16:43 +0100 | [diff] [blame] | 13 | // See https://flaviocopes.com/http-request-headers/ for a list of headers | 
|  | 14 |  | 
| Akron | 4c33c62 | 2018-11-12 13:43:27 +0100 | [diff] [blame] | 15 | KorAP.URL = KorAP.URL !== undefined ? KorAP.URL : ''; | 
| Nils Diewald | 4347ee9 | 2015-05-04 20:32:48 +0000 | [diff] [blame] | 16 | KorAP.API = KorAP.API || {}; | 
| Akron | b89863a | 2018-11-13 16:43:59 +0100 | [diff] [blame] | 17 |  | 
| Akron | bf713fc | 2020-10-13 10:44:35 +0200 | [diff] [blame] | 18 | const legacySigle = new RegExp('^([^_]+)_([^\\.]+)\\.(.+?)$'); | 
|  | 19 |  | 
| Akron | 48b1e4d | 2015-06-17 18:47:01 +0200 | [diff] [blame] | 20 | /** | 
|  | 21 | * Retrieve information about a match | 
|  | 22 | */ | 
| Nils Diewald | 4347ee9 | 2015-05-04 20:32:48 +0000 | [diff] [blame] | 23 | KorAP.API.getMatchInfo = function (match, param, cb) { | 
| Nils Diewald | 5814133 | 2015-04-07 16:18:45 +0000 | [diff] [blame] | 24 |  | 
| Nils Diewald | 4347ee9 | 2015-05-04 20:32:48 +0000 | [diff] [blame] | 25 | // match is a KorAP.Match object | 
| Akron | bf713fc | 2020-10-13 10:44:35 +0200 | [diff] [blame] | 26 | let url = KorAP.URL + '/corpus'; | 
| Akron | 0b489ad | 2018-02-02 16:49:32 +0100 | [diff] [blame] | 27 | /* | 
|  | 28 | url += '/' + match.corpusID; | 
|  | 29 | url += '/' + match.docID; | 
|  | 30 | url += '/' + match.textID; | 
|  | 31 | */ | 
| Akron | 19d97fe | 2016-09-06 20:47:05 +0200 | [diff] [blame] | 32 |  | 
| Akron | 19d97fe | 2016-09-06 20:47:05 +0200 | [diff] [blame] | 33 | // This is for legacy support | 
| Akron | bf713fc | 2020-10-13 10:44:35 +0200 | [diff] [blame] | 34 | const legacy = legacySigle.exec(match.textSigle); | 
|  | 35 | let docFragment = ""; | 
| Akron | 7f613e0 | 2016-11-07 02:50:44 +0100 | [diff] [blame] | 36 | if (legacy !== null && legacy[0]) { | 
| Akron | b89863a | 2018-11-13 16:43:59 +0100 | [diff] [blame] | 37 | docFragment = legacy[1] + '/' + legacy[2] + '/' + legacy[3]; | 
| Akron | 19d97fe | 2016-09-06 20:47:05 +0200 | [diff] [blame] | 38 | } | 
|  | 39 | else { | 
| Akron | b89863a | 2018-11-13 16:43:59 +0100 | [diff] [blame] | 40 | docFragment = match.textSigle; | 
| Akron | 19d97fe | 2016-09-06 20:47:05 +0200 | [diff] [blame] | 41 | } | 
| Akron | b89863a | 2018-11-13 16:43:59 +0100 | [diff] [blame] | 42 |  | 
|  | 43 | docFragment += '/' + match.matchID; | 
|  | 44 | url += '/' + docFragment; | 
| Nils Diewald | 5814133 | 2015-04-07 16:18:45 +0000 | [diff] [blame] | 45 |  | 
| Nils Diewald | 4347ee9 | 2015-05-04 20:32:48 +0000 | [diff] [blame] | 46 | // { spans: true, layer:x, foundry : y} | 
|  | 47 | if (param['spans'] == true) { | 
|  | 48 | url += '?spans=true'; | 
| Akron | b89863a | 2018-11-13 16:43:59 +0100 | [diff] [blame] | 49 | docFragment += ' +spans '; | 
|  | 50 | if (param['foundry'] !== undefined) { | 
| Akron | 515851a | 2017-05-02 12:53:17 +0200 | [diff] [blame] | 51 | url += '&foundry=' + param['foundry']; | 
| Akron | b89863a | 2018-11-13 16:43:59 +0100 | [diff] [blame] | 52 | docFragment += param['foundry']; | 
|  | 53 | }; | 
|  | 54 | if (param['layer'] !== undefined) { | 
| Akron | 515851a | 2017-05-02 12:53:17 +0200 | [diff] [blame] | 55 | url += '&layer=' + param['layer']; | 
| Akron | b89863a | 2018-11-13 16:43:59 +0100 | [diff] [blame] | 56 | docFragment += '/'+param['layer']; | 
|  | 57 | } | 
| Nils Diewald | 5814133 | 2015-04-07 16:18:45 +0000 | [diff] [blame] | 58 | } | 
| Nils Diewald | 4347ee9 | 2015-05-04 20:32:48 +0000 | [diff] [blame] | 59 |  | 
|  | 60 | // { spans : false, layer: [Array of KorAP.InfoLayer] } | 
|  | 61 | else { | 
|  | 62 | // TODO | 
| Akron | b89863a | 2018-11-13 16:43:59 +0100 | [diff] [blame] | 63 | docFragment += ' -spans'; | 
| Nils Diewald | 4347ee9 | 2015-05-04 20:32:48 +0000 | [diff] [blame] | 64 | url += '?spans=false'; | 
|  | 65 | } | 
|  | 66 |  | 
| Akron | b89863a | 2018-11-13 16:43:59 +0100 | [diff] [blame] | 67 | KorAP.API.getJSON(url, cb, "MatchInfo: " + docFragment); | 
| Nils Diewald | 5814133 | 2015-04-07 16:18:45 +0000 | [diff] [blame] | 68 | }; | 
| Nils Diewald | 4347ee9 | 2015-05-04 20:32:48 +0000 | [diff] [blame] | 69 |  | 
| Akron | 0b489ad | 2018-02-02 16:49:32 +0100 | [diff] [blame] | 70 |  | 
| Akron | 48b1e4d | 2015-06-17 18:47:01 +0200 | [diff] [blame] | 71 | /** | 
| Akron | 0ad7cd2 | 2018-02-08 18:03:06 +0100 | [diff] [blame] | 72 | * Retrieve information about a document. | 
|  | 73 | */ | 
|  | 74 | KorAP.API.getTextInfo = function (doc, param, cb) { | 
|  | 75 |  | 
|  | 76 | // doc is a KorAP.Match object | 
| Akron | bf713fc | 2020-10-13 10:44:35 +0200 | [diff] [blame] | 77 | let url = KorAP.URL + '/corpus' + '/' + doc.textSigle; | 
| Akron | 0ad7cd2 | 2018-02-08 18:03:06 +0100 | [diff] [blame] | 78 |  | 
|  | 79 | if (param['fields'] !== undefined) { | 
|  | 80 | url += '?fields='; // TODO! | 
|  | 81 | } | 
|  | 82 | else { | 
| Akron | 4bbd8b3 | 2018-03-06 19:19:44 +0100 | [diff] [blame] | 83 | url += '?fields=@all'; // TODO: Maybe '*'? | 
| Akron | 0ad7cd2 | 2018-02-08 18:03:06 +0100 | [diff] [blame] | 84 | } | 
| Akron | bf713fc | 2020-10-13 10:44:35 +0200 | [diff] [blame] | 85 |  | 
| Akron | b89863a | 2018-11-13 16:43:59 +0100 | [diff] [blame] | 86 | KorAP.API.getJSON(url, cb, "TextInfo: " + doc.textSigle); | 
| Akron | 0ad7cd2 | 2018-02-08 18:03:06 +0100 | [diff] [blame] | 87 | }; | 
|  | 88 |  | 
|  | 89 |  | 
|  | 90 | /** | 
| Akron | cd42a14 | 2019-07-12 18:55:37 +0200 | [diff] [blame] | 91 | * Retrieve information about virtual corpora | 
| Akron | 48b1e4d | 2015-06-17 18:47:01 +0200 | [diff] [blame] | 92 | */ | 
|  | 93 | KorAP.API.getCollections = function (cb) { | 
| Akron | b89863a | 2018-11-13 16:43:59 +0100 | [diff] [blame] | 94 | KorAP.API.getJSON(KorAP.URL + '/collection', cb, "CorpusInfo"); | 
| Akron | 48b1e4d | 2015-06-17 18:47:01 +0200 | [diff] [blame] | 95 | }; | 
|  | 96 |  | 
| hebasta | 0ee5080 | 2018-06-20 10:24:45 +0200 | [diff] [blame] | 97 |  | 
|  | 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 Repp | a6aba9a | 2021-01-23 20:16:43 +0100 | [diff] [blame] | 103 | * @param cq corpus query (formerly collectionQuery) | 
| hebasta | 0ee5080 | 2018-06-20 10:24:45 +0200 | [diff] [blame] | 104 | * | 
|  | 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){ | 
| Akron | bf713fc | 2020-10-13 10:44:35 +0200 | [diff] [blame] | 109 | let url  =  KorAP.URL + "/corpus?cq=" + encodeURIComponent(cq); | 
| Akron | b89863a | 2018-11-13 16:43:59 +0100 | [diff] [blame] | 110 | KorAP.API.getJSON(url, cb, "CorpusInfo: " + cq); | 
| hebasta | 0ee5080 | 2018-06-20 10:24:45 +0200 | [diff] [blame] | 111 | }; | 
| Akron | 8dda1c6 | 2021-01-20 10:27:32 +0100 | [diff] [blame] | 112 |  | 
|  | 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 | }; | 
| Akron | bf713fc | 2020-10-13 10:44:35 +0200 | [diff] [blame] | 121 |  | 
| hebasta | 4ba496a | 2018-06-05 15:56:01 +0200 | [diff] [blame] | 122 | /** | 
| Leo Repp | a6aba9a | 2021-01-23 20:16:43 +0100 | [diff] [blame] | 123 | * 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) { | 
| Akron | bf713fc | 2020-10-13 10:44:35 +0200 | [diff] [blame] | 133 | const req = new XMLHttpRequest(); | 
| Leo Repp | a6aba9a | 2021-01-23 20:16:43 +0100 | [diff] [blame] | 134 | req.open(requestType, url, true); | 
|  | 135 | // Dispatch global "window" event. See Kalamar::Plugin::Piwik | 
| Akron | bf713fc | 2020-10-13 10:44:35 +0200 | [diff] [blame] | 136 | const reqE = new CustomEvent('korapRequest', { | 
| Akron | 4c33c62 | 2018-11-12 13:43:27 +0100 | [diff] [blame] | 137 | bubbles : false, | 
| Akron | b89863a | 2018-11-13 16:43:59 +0100 | [diff] [blame] | 138 | detail: { | 
|  | 139 | "url" : url, | 
|  | 140 | "title" : title | 
|  | 141 | } | 
| Akron | 4c33c62 | 2018-11-12 13:43:27 +0100 | [diff] [blame] | 142 | }); | 
|  | 143 | window.dispatchEvent(reqE); | 
|  | 144 |  | 
| Nils Diewald | 4347ee9 | 2015-05-04 20:32:48 +0000 | [diff] [blame] | 145 | req.setRequestHeader("Accept", "application/json"); | 
| Leo Repp | a6aba9a | 2021-01-23 20:16:43 +0100 | [diff] [blame] | 146 | req.setRequestHeader("Content-Type", "application/json"); | 
|  | 147 | req.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); | 
| Nils Diewald | 4347ee9 | 2015-05-04 20:32:48 +0000 | [diff] [blame] | 148 | req.onreadystatechange = function () { | 
|  | 149 | /* | 
| Akron | 0b489ad | 2018-02-02 16:49:32 +0100 | [diff] [blame] | 150 | States: | 
|  | 151 | 0 - unsent (prior to open) | 
|  | 152 | 1 - opened (prior to send) | 
|  | 153 | 2 - headers received | 
|  | 154 | 3 - loading (responseText has partial data) | 
|  | 155 | 4 - done | 
| Nils Diewald | 4347ee9 | 2015-05-04 20:32:48 +0000 | [diff] [blame] | 156 | */ | 
|  | 157 | if (this.readyState == 4) { | 
| Akron | 515851a | 2017-05-02 12:53:17 +0200 | [diff] [blame] | 158 |  | 
| Leo Repp | a6aba9a | 2021-01-23 20:16:43 +0100 | [diff] [blame] | 159 | if (requestType === "GET") { //GET | 
|  | 160 | let retJSObj; | 
|  | 161 | try { | 
|  | 162 | retJSObj = JSON.parse(this.responseText); | 
|  | 163 | } | 
|  | 164 | catch (e) { | 
|  | 165 | KorAP.log(0, e); | 
|  | 166 | console.log(e); | 
|  | 167 | returnValueCB(undefined); | 
|  | 168 | return; | 
|  | 169 | }; | 
|  | 170 |  | 
|  | 171 | if (retJSObj !== undefined && retJSObj["errors"] !== undefined) { | 
|  | 172 | retJSObj["errors"].forEach( | 
|  | 173 | e => KorAP.log(e[0], e[1] || "Unknown") | 
|  | 174 | ); | 
|  | 175 | } | 
|  | 176 |  | 
|  | 177 | else if (this.status !== 200) { | 
|  | 178 | KorAP.log(this.status, this.statusText, "Remote service error (XMLHttpRequest) under URL: " + url); | 
|  | 179 | }; | 
|  | 180 |  | 
|  | 181 | if (this.status === 200) { | 
|  | 182 | returnValueCB(retJSObj); | 
|  | 183 | } | 
|  | 184 |  | 
|  | 185 | else { | 
|  | 186 | returnValueCB(undefined); | 
|  | 187 | }; | 
|  | 188 |  | 
|  | 189 | } else { // PUT, POST, DELETE | 
|  | 190 | if (this.status >= 300 || this.status < 200) { //Error | 
|  | 191 | KorAP.log(this.status, this.statusText, "Remote service error (XMLHttpRequest) under URL: " + url); | 
|  | 192 | }; | 
| Akron | b5d05d7 | 2018-02-12 15:09:12 +0100 | [diff] [blame] | 193 | }; | 
| Leo Repp | a6aba9a | 2021-01-23 20:16:43 +0100 | [diff] [blame] | 194 | // Call the callback function (no matter requestType) if one is given. | 
|  | 195 | if (typeof(errorCB) === "function"){ | 
|  | 196 | errorCB({ | 
|  | 197 | "status" : this.status, | 
|  | 198 | "statusText" : this.statusText | 
|  | 199 | }); | 
|  | 200 | }; | 
|  | 201 | }; | 
| Nils Diewald | 4347ee9 | 2015-05-04 20:32:48 +0000 | [diff] [blame] | 202 | }; | 
| Akron | bf713fc | 2020-10-13 10:44:35 +0200 | [diff] [blame] | 203 |  | 
| Leo Repp | a6aba9a | 2021-01-23 20:16:43 +0100 | [diff] [blame] | 204 | /*Set a value for .timeout to use this functionality */ | 
|  | 205 | //req.ontimeout = function () { | 
|  | 206 | //  KorAP.log(0, 'Request Timeout'); | 
|  | 207 | //}; | 
|  | 208 | if (requestType === "POST" || requestType === "PUT") { | 
|  | 209 | req.send(JSON.stringify(jsObj)); | 
|  | 210 | } else { //GET, DELETE | 
|  | 211 | req.send(); | 
| Nils Diewald | 4347ee9 | 2015-05-04 20:32:48 +0000 | [diff] [blame] | 212 | }; | 
| Leo Repp | a6aba9a | 2021-01-23 20:16:43 +0100 | [diff] [blame] | 213 | }; | 
|  | 214 |  | 
|  | 215 | /** | 
|  | 216 | * General method to get JSON information. | 
|  | 217 | * | 
|  | 218 | * @param {String} url The url at which the JSON File will be located | 
|  | 219 | * @param {function} returnValueCB The callback function that receives the retrieved JS object (already parsed) as a parameter, or undefined if none is eligible | 
|  | 220 | * @param {String} title How to store this request in the logs | 
|  | 221 | * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute | 
|  | 222 | */ | 
|  | 223 | KorAP.API.getJSON = function (url, returnValueCB, title, errorCB) { | 
|  | 224 | _actionJSON("GET", url, title, undefined, returnValueCB, errorCB); | 
|  | 225 | }; | 
|  | 226 |  | 
|  | 227 | /** | 
|  | 228 | * General method to put JSON information. | 
|  | 229 | * | 
|  | 230 | * @param {String} url The url at which the JSON File will be located | 
|  | 231 | * @param {JSObj} jsObj The JS object that is getting transfered. This will be stringified | 
|  | 232 | * @param {String} title How to store this request in the logs | 
|  | 233 | * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute | 
|  | 234 | */ | 
|  | 235 | KorAP.API.putJSON = function (url, jsObj, title, errorCB) { | 
|  | 236 | _actionJSON("PUT", url, title, jsObj, undefined, errorCB); | 
|  | 237 | }; | 
|  | 238 |  | 
|  | 239 | /** | 
|  | 240 | * General method to post JSON information. | 
|  | 241 | * | 
|  | 242 | * @param {String} url The url at which the JSON File will be located | 
|  | 243 | * @param {JSObj} jsObj The JS object that is getting transfered. This will be stringified | 
|  | 244 | * @param {String} title How to store this request in the logs | 
|  | 245 | * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute | 
|  | 246 | */ | 
|  | 247 | KorAP.API.postJSON = function (url, jsObj, title, errorCB) { | 
|  | 248 | _actionJSON("POST", url, title, jsObj, undefined, errorCB); | 
|  | 249 | }; | 
|  | 250 |  | 
|  | 251 | /** | 
|  | 252 | * General method to delete a file at a specific URL | 
|  | 253 | * | 
|  | 254 | * @param {String} url The url at which the to be deleted file is located | 
|  | 255 | * @param {String} title How to store this request in the logs | 
|  | 256 | * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute | 
|  | 257 | */ | 
|  | 258 | KorAP.API.deleteJSON = function (url, title, errorCB) { | 
|  | 259 | _actionJSON("DELETE", url, title, undefined, undefined, errorCB); | 
|  | 260 | }; | 
|  | 261 |  | 
|  | 262 |  | 
|  | 263 | // Stored query related functions | 
|  | 264 |  | 
|  | 265 | /** | 
|  | 266 | * Retrieve saved list of queries | 
|  | 267 | * | 
|  | 268 | * @param {function} returnValueCB The callback function that receives the JS object Listof queries, already parsed | 
|  | 269 | * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute | 
|  | 270 | */ | 
|  | 271 | KorAP.API.getQueryList = function (returnValueCB, errorCB){ | 
|  | 272 | KorAP.API.getJSON(KorAP.URL + "/query/", returnValueCB, "getSavedQueryList", errorCB); | 
|  | 273 | }; | 
|  | 274 |  | 
|  | 275 | /** | 
|  | 276 | * Retrieve specific saved query by query name | 
|  | 277 | * | 
|  | 278 | * @param {String} qn The name of the query to be retrieved. Must be a string | 
|  | 279 | * @param {function} returnValueCB The callback function that receives the query JS object Object, already parsed | 
|  | 280 | * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute | 
|  | 281 | */ | 
|  | 282 | KorAP.API.getQuery = function (qn, returnValueCB, errorCB){ | 
|  | 283 | KorAP.API.getJSON(KorAP.URL + "/query/" + qn, returnValueCB, "getSavedQuery of name "+ qn, errorCB); | 
|  | 284 | }; | 
|  | 285 |  | 
|  | 286 | /** | 
|  | 287 | * Put new query by query name | 
|  | 288 | * | 
|  | 289 | * @param {String} qn The name of the new query | 
|  | 290 | * @param {JSObj} jsObj The query. This will be stringified | 
|  | 291 | * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute | 
|  | 292 | */ | 
|  | 293 | KorAP.API.putQuery = function (qn, jsObj, errorCB){ | 
|  | 294 | KorAP.API.putJSON(KorAP.URL + "/query/" + qn, jsObj, "putQuery of name "+ qn, errorCB); | 
|  | 295 | }; | 
|  | 296 |  | 
|  | 297 | /** | 
|  | 298 | * Post new query by query name | 
|  | 299 | * | 
|  | 300 | * @param {String} qn The name of the new query | 
|  | 301 | * @param {JSObj} jsObj The query. This will be stringified | 
|  | 302 | * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute | 
|  | 303 | */ | 
|  | 304 | KorAP.API.postQuery = function (qn, jsObj, errorCB){ | 
|  | 305 | KorAP.API.postJSON(KorAP.URL + "/query/" + qn, jsObj, "postQuery of name "+ qn, errorCB); | 
|  | 306 | }; | 
|  | 307 |  | 
|  | 308 | /** | 
|  | 309 | * delete query by query name | 
|  | 310 | * | 
|  | 311 | * @param {String} qn The name of the to be deleted query | 
|  | 312 | * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute | 
|  | 313 | */ | 
|  | 314 | KorAP.API.deleteQuery = function (qn, errorCB){ | 
|  | 315 | KorAP.API.deleteJSON(KorAP.URL + "/query/" + qn, "deleteQuery of name "+ qn, errorCB); | 
|  | 316 | }; | 
| Nils Diewald | 0e6992a | 2015-04-14 20:13:52 +0000 | [diff] [blame] | 317 | }); |