blob: 52bf129fc7e9688f6aad722b0112392ce9c77e8c [file] [log] [blame]
Nils Diewald3a2d8022014-12-16 02:45:41 +00001var KorAP = KorAP || {};
Nils Diewald3a2d8022014-12-16 02:45:41 +00002
Nils Diewald8f4e2542014-12-19 04:42:09 +00003// TODO: Implement a working localization solution!
4// TODO: Support 'update' method to update elements on change
Nils Diewald966abf12014-12-20 02:27:45 +00005// TODO: Implement "toQuery"
Nils Diewaldd0770492014-12-19 03:55:00 +00006
7/*
Nils Diewaldd599d542015-01-08 20:41:34 +00008 Error codes:
Nils Diewaldd0770492014-12-19 03:55:00 +00009 701: "JSON-LD group has no @type attribute"
10 704: "Operation needs operand list"
Nils Diewald3a2d8022014-12-16 02:45:41 +000011 802: "Match type is not supported by value type"
12 804: "Unknown value type"
13 805: "Value is invalid"
14 806: "Value is not a valid date string"
15 807: "Value is not a valid regular expression"
Nils Diewald3a2d8022014-12-16 02:45:41 +000016 810: "Unknown document group operation" (like 711)
17 811: "Document group expects operation" (like 703)
18 812: "Operand not supported in document group" (like 744)
Nils Diewaldd0770492014-12-19 03:55:00 +000019 813: "Collection type is not supported" (like 713)
20*/
21
Nils Diewald3a2d8022014-12-16 02:45:41 +000022(function (KorAP) {
23 "use strict";
24
25 // Default log message
26 KorAP.log = KorAP.log || function (type, msg) {
27 console.log(type + ": " + msg);
28 };
29
30 KorAP._validStringMatchRE = new RegExp("^(?:eq|ne|contains)$");
31 KorAP._validRegexMatchRE = new RegExp("^(?:eq|ne)$");
Nils Diewaldd0770492014-12-19 03:55:00 +000032 KorAP._validDateMatchRE = new RegExp("^[lg]?eq$");
Nils Diewald3a2d8022014-12-16 02:45:41 +000033 KorAP._validDateRE = new RegExp("^(?:\\d{4})(?:-\\d\\d(?:-\\d\\d)?)?$");
34 KorAP._validGroupOpRE = new RegExp("^(?:and|or)$");
Nils Diewaldf219eb82015-01-07 20:15:42 +000035 KorAP._quote = new RegExp("([\"\\\\])", 'g');
Nils Diewald3a2d8022014-12-16 02:45:41 +000036
Nils Diewaldf219eb82015-01-07 20:15:42 +000037 var loc = (KorAP.Locale = KorAP.Locale || {} );
38 loc.AND = loc.AND || 'and';
39 loc.OR = loc.OR || 'or';
40 loc.DEL = loc.DEL || '×';
41 loc.EMPTY = loc.EMPTY || '⋯'
Nils Diewaldd0770492014-12-19 03:55:00 +000042
Nils Diewaldd599d542015-01-08 20:41:34 +000043
Nils Diewald966abf12014-12-20 02:27:45 +000044 function _bool (bool) {
45 return (bool === undefined || bool === false) ? false : true;
46 };
47
Nils Diewaldd599d542015-01-08 20:41:34 +000048
Nils Diewald966abf12014-12-20 02:27:45 +000049 function _removeChildren (node) {
50 // Remove everything underneath
Nils Diewald8f6b6102015-01-08 18:25:33 +000051 while (node.firstChild)
Nils Diewald966abf12014-12-20 02:27:45 +000052 node.removeChild(node.firstChild);
Nils Diewald966abf12014-12-20 02:27:45 +000053 };
54
Nils Diewald4019bd22015-01-08 19:57:50 +000055
56 // Add 'or'-criterion
57 KorAP._or = function (e) {
58 var obj = this.parentNode.refTo;
59 };
60
61
62 // Add 'and'-criterion
63 KorAP._and = function (e) {
64 var obj = this.parentNode.refTo;
Nils Diewaldd599d542015-01-08 20:41:34 +000065 if (obj.ldType() === 'docGroup') {
66 console.log('~~~~~~~~~');
67 }
68 else if (obj.ldType() === 'doc') {
69 obj.parent().newAfter(obj);
70 };
Nils Diewald4019bd22015-01-08 19:57:50 +000071 };
72
Nils Diewaldd599d542015-01-08 20:41:34 +000073
Nils Diewald4019bd22015-01-08 19:57:50 +000074 // Remove doc or docGroup
75 KorAP._delete = function (e) {
76 var obj = this.parentNode.refTo;
77 if (obj.parent().ldType() !== null)
78 obj.parent().delOperand(obj).update();
79 else
80 obj.parent().clean();
81 };
82
Nils Diewaldd599d542015-01-08 20:41:34 +000083
84 /**
85 * Virtual Collection
86 */
Nils Diewald3a2d8022014-12-16 02:45:41 +000087 KorAP.VirtualCollection = {
Nils Diewaldf219eb82015-01-07 20:15:42 +000088 ldType : function () {
89 return null;
90 },
Nils Diewaldd599d542015-01-08 20:41:34 +000091
Nils Diewald3a2d8022014-12-16 02:45:41 +000092 create : function () {
93 return Object.create(KorAP.VirtualCollection);
94 },
Nils Diewaldd599d542015-01-08 20:41:34 +000095
Nils Diewald4019bd22015-01-08 19:57:50 +000096 clean : function () {
97 if (this._root.ldType() !== "non") {
98 this._root.destroy();
99 this.root(KorAP.UnspecifiedDoc.create(this));
100 };
101 return this;
102 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000103
Nils Diewaldd0770492014-12-19 03:55:00 +0000104 render : function (json) {
105 var obj = Object.create(KorAP.VirtualCollection);
106
107 if (json !== undefined) {
108 // Root object
109 if (json['@type'] == 'korap:doc') {
Nils Diewaldf219eb82015-01-07 20:15:42 +0000110 obj._root = KorAP.Doc.create(obj, json);
Nils Diewaldd0770492014-12-19 03:55:00 +0000111 }
112 else if (json['@type'] == 'korap:docGroup') {
Nils Diewaldf219eb82015-01-07 20:15:42 +0000113 obj._root = KorAP.DocGroup.create(obj, json);
Nils Diewaldd0770492014-12-19 03:55:00 +0000114 }
115 else {
116 KorAP.log(813, "Collection type is not supported");
117 return;
118 };
119 }
120
121 else {
122 // Add unspecified object
Nils Diewaldf219eb82015-01-07 20:15:42 +0000123 obj._root = KorAP.UnspecifiedDoc.create(obj);
Nils Diewaldd0770492014-12-19 03:55:00 +0000124 };
125
Nils Diewald8e7182e2015-01-08 15:02:07 +0000126 // Init element and update
127 obj.update();
Nils Diewaldd0770492014-12-19 03:55:00 +0000128
129 return obj;
Nils Diewald3a2d8022014-12-16 02:45:41 +0000130 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000131
Nils Diewaldf219eb82015-01-07 20:15:42 +0000132 root : function (obj) {
Nils Diewald8e7182e2015-01-08 15:02:07 +0000133 if (arguments.length === 1) {
Nils Diewald8f6b6102015-01-08 18:25:33 +0000134 var e = this.element();
135 if (e.firstChild !== null) {
136 if (e.firstChild !== obj.element())
137 e.replaceChild(obj.element(), e.firstChild);
138 }
139
140 // Append root element
141 else {
142 e.appendChild(obj.element());
143 };
144
145 // Update parent child relations
Nils Diewaldf219eb82015-01-07 20:15:42 +0000146 this._root = obj;
Nils Diewald8f6b6102015-01-08 18:25:33 +0000147 obj.parent(this);
148
Nils Diewald8e7182e2015-01-08 15:02:07 +0000149 this.update();
150 };
Nils Diewaldd0770492014-12-19 03:55:00 +0000151 return this._root;
Nils Diewald3a2d8022014-12-16 02:45:41 +0000152 },
Nils Diewald8f6b6102015-01-08 18:25:33 +0000153
Nils Diewaldd0770492014-12-19 03:55:00 +0000154 element : function () {
155 if (this._element !== undefined)
156 return this._element;
157
158 this._element = document.createElement('div');
159 this._element.setAttribute('class', 'vc');
Nils Diewald8e7182e2015-01-08 15:02:07 +0000160
Nils Diewald8f6b6102015-01-08 18:25:33 +0000161 // Initialize root
162 this._element.appendChild(this._root.element());
163
Nils Diewaldd0770492014-12-19 03:55:00 +0000164 return this._element;
Nils Diewaldf219eb82015-01-07 20:15:42 +0000165 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000166
167 update : function () {
168 this._root.update();
169 return this;
170 },
171
Nils Diewaldf219eb82015-01-07 20:15:42 +0000172 toJson : function () {
173 return this._root.toJson();
174 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000175
176 toQuery : function () {
177 return this._root.toQuery();
Nils Diewald3a2d8022014-12-16 02:45:41 +0000178 }
179 };
180
Nils Diewaldd599d542015-01-08 20:41:34 +0000181
Nils Diewald8f4e2542014-12-19 04:42:09 +0000182 /**
183 * Operators for criteria
184 */
Nils Diewaldd0770492014-12-19 03:55:00 +0000185 KorAP.Operators = {
186 create : function (and, or, del) {
187 var op = Object.create(KorAP.Operators);
188 op.and(and);
189 op.or(or);
190 op.del(del);
191 return op;
192 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000193
Nils Diewaldd0770492014-12-19 03:55:00 +0000194 update : function () {
Nils Diewaldd0770492014-12-19 03:55:00 +0000195 // Init the element
196 if (this._element === undefined)
197 return this.element();
198
199 var op = this._element;
200
Nils Diewald0297ba12015-01-05 21:56:12 +0000201 op.refTo = this.parent();
202
Nils Diewaldd0770492014-12-19 03:55:00 +0000203 // Remove everything underneath
Nils Diewald966abf12014-12-20 02:27:45 +0000204 _removeChildren(op);
Nils Diewaldd0770492014-12-19 03:55:00 +0000205
206 // Add and button
207 if (this._and === true) {
208 var andE = document.createElement('span');
209 andE.setAttribute('class', 'and');
Nils Diewald0297ba12015-01-05 21:56:12 +0000210 andE.addEventListener('click', KorAP._and, false);
Nils Diewald8f6b6102015-01-08 18:25:33 +0000211 andE.appendChild(
212 document.createTextNode(KorAP.Locale.AND)
213 );
Nils Diewaldd0770492014-12-19 03:55:00 +0000214 op.appendChild(andE);
215 };
216
217 // Add or button
218 if (this._or === true) {
219 var orE = document.createElement('span');
220 orE.setAttribute('class', 'or');
Nils Diewald0297ba12015-01-05 21:56:12 +0000221 orE.addEventListener('click', KorAP._or, false);
Nils Diewaldd0770492014-12-19 03:55:00 +0000222 orE.appendChild(document.createTextNode(KorAP.Locale.OR));
223 op.appendChild(orE);
224 };
225
226 // Add delete button
227 if (this._del === true) {
228 var delE = document.createElement('span');
229 delE.setAttribute('class', 'delete');
230 delE.appendChild(document.createTextNode(KorAP.Locale.DEL));
Nils Diewald0297ba12015-01-05 21:56:12 +0000231 delE.addEventListener('click', KorAP._delete, false);
Nils Diewaldd0770492014-12-19 03:55:00 +0000232 op.appendChild(delE);
233 };
Nils Diewald966abf12014-12-20 02:27:45 +0000234
235 return op;
Nils Diewaldd0770492014-12-19 03:55:00 +0000236 },
Nils Diewald0297ba12015-01-05 21:56:12 +0000237
238 // Be aware! This may be cyclic
239 parent : function (obj) {
240 if (arguments.length === 1)
241 this._parent = obj;
242 return this._parent;
243 },
Nils Diewald5c817a42015-01-06 01:08:56 +0000244
Nils Diewaldd0770492014-12-19 03:55:00 +0000245 element : function () {
246
247 // Return existing element
248 if (this._element !== undefined)
249 return this._element;
250
251 this._element = document.createElement('div');
252 this._element.setAttribute('class', 'operators');
253
254 // Init elements
255 this.update();
256 return this._element;
257 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000258
Nils Diewaldd0770492014-12-19 03:55:00 +0000259 and : function (bool) {
260 if (arguments.length === 1)
Nils Diewald966abf12014-12-20 02:27:45 +0000261 this._and = _bool(bool);
Nils Diewaldd0770492014-12-19 03:55:00 +0000262 return this._and;
263 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000264
Nils Diewaldd0770492014-12-19 03:55:00 +0000265 or : function (bool) {
266 if (arguments.length === 1)
Nils Diewald966abf12014-12-20 02:27:45 +0000267 this._or = _bool(bool);
Nils Diewaldd0770492014-12-19 03:55:00 +0000268 return this._or;
269 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000270
Nils Diewaldd0770492014-12-19 03:55:00 +0000271 del : function (bool) {
272 if (arguments.length === 1)
Nils Diewald966abf12014-12-20 02:27:45 +0000273 this._del = _bool(bool);
Nils Diewaldd0770492014-12-19 03:55:00 +0000274 return this._del;
275 }
276 };
277
278
279 /**
280 * Unspecified criterion
281 */
Nils Diewald8f4e2542014-12-19 04:42:09 +0000282 KorAP.UnspecifiedDoc = {
Nils Diewald4019bd22015-01-08 19:57:50 +0000283 _ldType : "non",
Nils Diewaldd0770492014-12-19 03:55:00 +0000284 create : function (parent) {
Nils Diewald8f6b6102015-01-08 18:25:33 +0000285 var obj = Object.create(KorAP.JsonLD).
286 upgradeTo(KorAP.UnspecifiedDoc);
287
Nils Diewaldd0770492014-12-19 03:55:00 +0000288 if (parent !== undefined)
289 obj._parent = parent;
Nils Diewald8f6b6102015-01-08 18:25:33 +0000290
Nils Diewaldd0770492014-12-19 03:55:00 +0000291 return obj;
292 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000293
Nils Diewald966abf12014-12-20 02:27:45 +0000294 update : function () {
Nils Diewald4019bd22015-01-08 19:57:50 +0000295
Nils Diewald966abf12014-12-20 02:27:45 +0000296 if (this._element === undefined)
297 return this.element();
298
Nils Diewald8f6b6102015-01-08 18:25:33 +0000299 // Remove element content
Nils Diewald966abf12014-12-20 02:27:45 +0000300 _removeChildren(this._element);
301
302 var ellipsis = document.createElement('span');
Nils Diewaldf219eb82015-01-07 20:15:42 +0000303 ellipsis.appendChild(document.createTextNode(loc.EMPTY));
Nils Diewald966abf12014-12-20 02:27:45 +0000304 this._element.appendChild(ellipsis);
305
306 // Set operators
307 var op = this.operators(
308 false,
309 false,
310 // No delete object, if this is the root
Nils Diewald8f6b6102015-01-08 18:25:33 +0000311 (this._parent !== undefined &&
312 this.parent().ldType() !== null) ? true : false
Nils Diewald966abf12014-12-20 02:27:45 +0000313 );
314
315 this._element.appendChild(
316 op.element()
317 );
318
Nils Diewald966abf12014-12-20 02:27:45 +0000319 return this.element();
320 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000321
Nils Diewaldd0770492014-12-19 03:55:00 +0000322 element : function () {
323 if (this._element !== undefined)
324 return this._element;
325 this._element = document.createElement('div');
Nils Diewaldd599d542015-01-08 20:41:34 +0000326 this._element.setAttribute('class', 'doc unspecified');
Nils Diewald966abf12014-12-20 02:27:45 +0000327 this.update();
Nils Diewaldd0770492014-12-19 03:55:00 +0000328 return this._element;
329 }
330 };
331
332
Nils Diewald8f4e2542014-12-19 04:42:09 +0000333 /**
Nils Diewaldd599d542015-01-08 20:41:34 +0000334 * Document criterion
Nils Diewald8f4e2542014-12-19 04:42:09 +0000335 */
336 KorAP.Doc = {
337 _ldType : "doc",
338 _obj : function () { return KorAP.Doc; },
Nils Diewaldd0770492014-12-19 03:55:00 +0000339
340 create : function (parent, json) {
Nils Diewald8f6b6102015-01-08 18:25:33 +0000341 var obj = Object(KorAP.JsonLD).
342 create().
343 upgradeTo(KorAP.Doc).
344 fromJson(json);
345
Nils Diewaldd0770492014-12-19 03:55:00 +0000346 if (parent !== undefined)
347 obj._parent = parent;
Nils Diewald8f6b6102015-01-08 18:25:33 +0000348
349 obj._changed = true;
Nils Diewaldd0770492014-12-19 03:55:00 +0000350 return obj;
351 },
Nils Diewald5c817a42015-01-06 01:08:56 +0000352
Nils Diewald966abf12014-12-20 02:27:45 +0000353 update : function () {
354 if (this._element === undefined)
355 return this.element();
Nils Diewaldd0770492014-12-19 03:55:00 +0000356
Nils Diewald8f6b6102015-01-08 18:25:33 +0000357 // Get element
Nils Diewald966abf12014-12-20 02:27:45 +0000358 var e = this._element;
359
Nils Diewald8f6b6102015-01-08 18:25:33 +0000360 // Check if there is a change
361 if (this._changed) {
Nils Diewald966abf12014-12-20 02:27:45 +0000362
Nils Diewald8f6b6102015-01-08 18:25:33 +0000363 // Added key
364 var key = document.createElement('span');
365 key.setAttribute('class', 'key');
366 if (this.key())
367 key.appendChild(document.createTextNode(this.key()));
Nils Diewald966abf12014-12-20 02:27:45 +0000368
Nils Diewald8f6b6102015-01-08 18:25:33 +0000369 // Added match operator
370 var matchop = document.createElement('span');
371 matchop.setAttribute('data-type', this.type());
372 matchop.setAttribute('class', 'match');
373 matchop.appendChild(
374 document.createTextNode(this.matchop())
375 );
376
377 // Added match operator
378 var value = document.createElement('span');
379 value.setAttribute('data-type', this.type());
380 value.setAttribute('class', 'value');
381 if (this.value())
382 value.appendChild(
383 document.createTextNode(this.value())
384 );
385
386 // Remove all element children
387 _removeChildren(e);
388
389 // Add spans
390 e.appendChild(key);
391 e.appendChild(matchop);
392 e.appendChild(value);
393
394 this._changed = false;
395 };
396
397 if (this._parent !== undefined) {
398 // Set operators
399 var op = this.operators(
400 true,
401 true,
Nils Diewald4019bd22015-01-08 19:57:50 +0000402 true
Nils Diewald8f6b6102015-01-08 18:25:33 +0000403 );
404
405 // Append new operators
406 e.appendChild(op.element());
407 };
Nils Diewald966abf12014-12-20 02:27:45 +0000408
Nils Diewaldd0770492014-12-19 03:55:00 +0000409 return e;
410 },
411
Nils Diewald966abf12014-12-20 02:27:45 +0000412 element : function () {
413 if (this._element !== undefined)
414 return this._element;
415
416 this._element = document.createElement('div');
417 this._element.setAttribute('class', 'doc');
418
419 this.update();
420 return this._element;
421 },
422
Nils Diewaldd0770492014-12-19 03:55:00 +0000423 // Wrap a new operation around the doc element
424 wrap : function (op) {
Nils Diewaldf219eb82015-01-07 20:15:42 +0000425/*
Nils Diewald8f4e2542014-12-19 04:42:09 +0000426 var group = KorAP.DocGroup.create(undefined);
Nils Diewald966abf12014-12-20 02:27:45 +0000427 group.append(this);
428 group.append(null);
Nils Diewaldd0770492014-12-19 03:55:00 +0000429 this.parent(group);
Nils Diewaldd0770492014-12-19 03:55:00 +0000430 var div = document.createElement('div');
431 div.setAttribute('data-operation', op);
432 var parent = this.element.parent;
433 parent.removeChild(this.element);
434 parent.appendChild(div);
435 div.appendChild(this.element);
436 return div;
437*/
Nils Diewaldd0770492014-12-19 03:55:00 +0000438 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000439
Nils Diewald3a2d8022014-12-16 02:45:41 +0000440 // Deserialize from json
441 fromJson : function (json) {
Nils Diewald3a2d8022014-12-16 02:45:41 +0000442 if (json === undefined)
Nils Diewaldd0770492014-12-19 03:55:00 +0000443 return this;
Nils Diewald3a2d8022014-12-16 02:45:41 +0000444
Nils Diewald3a2d8022014-12-16 02:45:41 +0000445 if (json["@type"] !== "korap:doc") {
446 KorAP.log(701, "JSON-LD group has no @type attribute");
447 return;
448 };
449
Nils Diewald3a2d8022014-12-16 02:45:41 +0000450 if (json["value"] === undefined ||
451 typeof json["value"] != 'string') {
452 KorAP.log(805, "Value is invalid");
453 return;
454 };
455
456 // There is a defined key
457 if (json["key"] !== undefined &&
458 typeof json["key"] === 'string') {
459
460 // Set key
Nils Diewaldd0770492014-12-19 03:55:00 +0000461 this.key(json["key"]);
Nils Diewald3a2d8022014-12-16 02:45:41 +0000462
463 // Set match operation
464 if (json["match"] !== undefined) {
Nils Diewaldd0770492014-12-19 03:55:00 +0000465 if (typeof json["match"] === 'string') {
466 this.matchop(json["match"]);
467 }
Nils Diewald3a2d8022014-12-16 02:45:41 +0000468 else {
469 KorAP.log(802, "Match type is not supported by value type");
470 return;
471 };
472 };
473
474 // Key is a string
475 if (json["type"] === undefined ||
476 json["type"] == "type:string") {
Nils Diewaldd0770492014-12-19 03:55:00 +0000477 this.type("string");
Nils Diewald3a2d8022014-12-16 02:45:41 +0000478
479 // Check match type
Nils Diewaldd0770492014-12-19 03:55:00 +0000480 if (!KorAP._validStringMatchRE.test(this.matchop())) {
Nils Diewald3a2d8022014-12-16 02:45:41 +0000481 KorAP.log(802, "Match type is not supported by value type");
482 return;
483 };
484
485 // Set string value
Nils Diewaldd0770492014-12-19 03:55:00 +0000486 this.value(json["value"]);
Nils Diewald3a2d8022014-12-16 02:45:41 +0000487 }
488
489 // Key is a date
490 else if (json["type"] === "type:date") {
Nils Diewaldd0770492014-12-19 03:55:00 +0000491 this.type("date");
Nils Diewald3a2d8022014-12-16 02:45:41 +0000492
493 if (json["value"] !== undefined &&
494 KorAP._validDateRE.test(json["value"])) {
495
Nils Diewaldd0770492014-12-19 03:55:00 +0000496 if (!KorAP._validDateMatchRE.test(this.matchop())) {
Nils Diewald3a2d8022014-12-16 02:45:41 +0000497 KorAP.log(802, "Match type is not supported by value type");
498 return;
499 };
500
501 // Set value
Nils Diewaldd0770492014-12-19 03:55:00 +0000502 this.value(json["value"]);
Nils Diewald3a2d8022014-12-16 02:45:41 +0000503 }
504 else {
505 KorAP.log(806, "Value is not a valid date string");
506 return;
507 };
508 }
509
510 // Key is a regular expression
511 else if (json["type"] === "type:regex") {
Nils Diewaldd0770492014-12-19 03:55:00 +0000512 this.type("regex");
Nils Diewald3a2d8022014-12-16 02:45:41 +0000513
514 try {
515
516 // Try to create a regular expression
517 var check = new RegExp(json["value"]);
518
Nils Diewaldd0770492014-12-19 03:55:00 +0000519 if (!KorAP._validRegexMatchRE.test(this.matchop())) {
Nils Diewald3a2d8022014-12-16 02:45:41 +0000520 KorAP.log(802, "Match type is not supported by value type");
521 return;
522 };
523
Nils Diewaldd0770492014-12-19 03:55:00 +0000524 this.value(json["value"]);
Nils Diewald3a2d8022014-12-16 02:45:41 +0000525 }
Nils Diewaldd0770492014-12-19 03:55:00 +0000526
Nils Diewald3a2d8022014-12-16 02:45:41 +0000527 catch (e) {
528 KorAP.log(807, "Value is not a valid regular expression");
529 return;
530 };
Nils Diewaldd0770492014-12-19 03:55:00 +0000531 this.type("regex");
Nils Diewald3a2d8022014-12-16 02:45:41 +0000532 }
533
534 else {
535 KorAP.log(804, "Unknown value type");
536 return;
537 };
538 };
539
540 return this;
541 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000542
Nils Diewaldd0770492014-12-19 03:55:00 +0000543 key : function (value) {
Nils Diewald8f6b6102015-01-08 18:25:33 +0000544 if (arguments.length === 1) {
Nils Diewaldd0770492014-12-19 03:55:00 +0000545 this._key = value;
Nils Diewald8f6b6102015-01-08 18:25:33 +0000546 this._changed = true;
547 };
Nils Diewald3a2d8022014-12-16 02:45:41 +0000548 return this._key;
549 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000550
Nils Diewaldd0770492014-12-19 03:55:00 +0000551 matchop : function (match) {
Nils Diewald8f6b6102015-01-08 18:25:33 +0000552 if (arguments.length === 1) {
Nils Diewaldd0770492014-12-19 03:55:00 +0000553 this._matchop = match.replace(/^match:/, '');
Nils Diewald8f6b6102015-01-08 18:25:33 +0000554 this._changed = true;
555 };
Nils Diewald3a2d8022014-12-16 02:45:41 +0000556 return this._matchop || "eq";
557 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000558
Nils Diewaldd0770492014-12-19 03:55:00 +0000559 type : function (type) {
Nils Diewald8f6b6102015-01-08 18:25:33 +0000560 if (arguments.length === 1) {
Nils Diewaldd0770492014-12-19 03:55:00 +0000561 this._type = type;
Nils Diewald8f6b6102015-01-08 18:25:33 +0000562 this._changed = true;
563 };
Nils Diewald3a2d8022014-12-16 02:45:41 +0000564 return this._type || "string";
565 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000566
Nils Diewaldd0770492014-12-19 03:55:00 +0000567 value : function (value) {
Nils Diewald8f6b6102015-01-08 18:25:33 +0000568 if (arguments.length === 1) {
Nils Diewaldd0770492014-12-19 03:55:00 +0000569 this._value = value;
Nils Diewald8f6b6102015-01-08 18:25:33 +0000570 this._changed = true;
571 };
Nils Diewald3a2d8022014-12-16 02:45:41 +0000572 return this._value;
573 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000574
Nils Diewald3a2d8022014-12-16 02:45:41 +0000575 toJson : function () {
Nils Diewaldd0770492014-12-19 03:55:00 +0000576 if (!this.matchop() || !this.key())
Nils Diewald3a2d8022014-12-16 02:45:41 +0000577 return {};
578
579 return {
Nils Diewaldd0770492014-12-19 03:55:00 +0000580 "@type" : "korap:" + this.ldType(),
581 "key" : this.key(),
582 "match" : "match:" + this.matchop(),
583 "value" : this.value() || '',
584 "type" : "type:" + this.type()
Nils Diewald3a2d8022014-12-16 02:45:41 +0000585 };
Nils Diewaldf219eb82015-01-07 20:15:42 +0000586 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000587
588 toQuery : function () {
Nils Diewaldf219eb82015-01-07 20:15:42 +0000589 if (!this.matchop() || !this.key())
590 return "";
591
592 // Build doc string based on key
593 var string = this.key() + ' ';
594
595 // Add match operator
596 switch (this.matchop()) {
597 case "ne":
598 string += '!=';
599 break;
600 case "contains":
601 string += '~';
602 break;
603 case "geq":
604 string += 'since';
605 break;
606 case "leq":
607 string += 'until';
608 break;
609 default:
610 string += (this.type() == 'date') ? 'in' : '=';
611 break;
612 };
613
614 string += ' ';
615
616 // Add value
617 switch (this.type()) {
618 case "date":
619 return string + this.value();
620 break;
621 case "regex":
622 return string + '/' + this.value() + '/';
623 break;
624 case "string":
625 return string + '"' + this.value().replace(KorAP._quote, '\\$1') + '"';
626 break;
627 };
628
Nils Diewaldd599d542015-01-08 20:41:34 +0000629 return "";
Nils Diewald3a2d8022014-12-16 02:45:41 +0000630 }
631 };
Nils Diewald8f4e2542014-12-19 04:42:09 +0000632
Nils Diewaldd599d542015-01-08 20:41:34 +0000633
Nils Diewald8f4e2542014-12-19 04:42:09 +0000634 /**
Nils Diewaldd599d542015-01-08 20:41:34 +0000635 * Document group criterion
Nils Diewald8f4e2542014-12-19 04:42:09 +0000636 */
637 KorAP.DocGroup = {
638 _ldType : "docGroup",
639
640 create : function (parent, json) {
641 var obj = Object.create(KorAP.JsonLD).upgradeTo(KorAP.DocGroup);
642 obj._operands = [];
643 obj.fromJson(json);
644 if (parent !== undefined)
645 obj._parent = parent;
646 return obj;
647 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000648
649 newAfter : function (obj) {
650 for (var i in this._operands) {
651 if (this._operands[i] === obj) {
652 var operand = KorAP.UnspecifiedDoc.create(this);
653 this._operands.splice(i + 1, 0, operand);
654 return this.update();
655 };
656 };
657 },
658
Nils Diewald966abf12014-12-20 02:27:45 +0000659 append : function (operand) {
660
661 // Append unspecified object
662 if (operand === undefined) {
663
664 // Be aware of cyclic structures!
665 operand = KorAP.UnspecifiedDoc.create(this);
666 this._operands.push(operand);
Nils Diewald966abf12014-12-20 02:27:45 +0000667 return operand;
668 };
669
Nils Diewald8f4e2542014-12-19 04:42:09 +0000670 switch (operand["@type"]) {
671 case undefined:
672 if (operand["ldType"] !== undefined) {
673 if (operand.ldType() !== 'doc' &&
Nils Diewald966abf12014-12-20 02:27:45 +0000674 operand.ldType() !== 'docGroup') {
Nils Diewald8f4e2542014-12-19 04:42:09 +0000675 KorAP.log(812, "Operand not supported in document group");
676 return;
677 };
Nils Diewald966abf12014-12-20 02:27:45 +0000678 // Be aware of cyclic structures!
679 operand.parent(this);
Nils Diewald8f4e2542014-12-19 04:42:09 +0000680 this._operands.push(operand);
681 return operand;
682 };
683
684 KorAP.log(701, "JSON-LD group has no @type attribute");
685 return;
686
687 case "korap:doc":
Nils Diewald966abf12014-12-20 02:27:45 +0000688 // Be aware of cyclic structures!
689 var doc = KorAP.Doc.create(this, operand);
Nils Diewald8f4e2542014-12-19 04:42:09 +0000690 if (doc === undefined)
691 return;
692 this._operands.push(doc);
693 return doc;
694
695 case "korap:docGroup":
Nils Diewald966abf12014-12-20 02:27:45 +0000696 // Be aware of cyclic structures!
697 var docGroup = KorAP.DocGroup.create(this, operand);
Nils Diewald8f4e2542014-12-19 04:42:09 +0000698 if (docGroup === undefined)
699 return;
700 this._operands.push(docGroup);
701 return docGroup;
702
703 default:
704 KorAP.log(812, "Operand not supported in document group");
705 return;
706 };
707 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000708
Nils Diewald966abf12014-12-20 02:27:45 +0000709 update : function () {
Nils Diewaldf219eb82015-01-07 20:15:42 +0000710 // There is only one operand in group
711 if (this._operands.length === 1) {
712 var parent = this.parent();
Nils Diewald8e7182e2015-01-08 15:02:07 +0000713 var op = this.getOperand(0);
714
Nils Diewald8f6b6102015-01-08 18:25:33 +0000715 // This will prevent destruction of
716 // the operand
717 this._operands = [];
Nils Diewaldf219eb82015-01-07 20:15:42 +0000718
719 // Parent is a group
720 if (parent.ldType() !== null) {
Nils Diewald8e7182e2015-01-08 15:02:07 +0000721 return parent.replaceOperand(this, op).update();
Nils Diewaldf219eb82015-01-07 20:15:42 +0000722 }
723
Nils Diewald8f6b6102015-01-08 18:25:33 +0000724 // Parent is vc
Nils Diewaldf219eb82015-01-07 20:15:42 +0000725 else {
Nils Diewaldf219eb82015-01-07 20:15:42 +0000726 this.destroy();
Nils Diewald8f6b6102015-01-08 18:25:33 +0000727 // Cyclic madness
728 parent.root(op);
729 op.parent(parent);
Nils Diewaldf219eb82015-01-07 20:15:42 +0000730 return parent.root();
Nils Diewald5c817a42015-01-06 01:08:56 +0000731 };
732 };
733
Nils Diewald966abf12014-12-20 02:27:45 +0000734 if (this._element === undefined)
Nils Diewald5c817a42015-01-06 01:08:56 +0000735 return this;
Nils Diewald966abf12014-12-20 02:27:45 +0000736
Nils Diewald5c817a42015-01-06 01:08:56 +0000737 var group = this._element;
738 group.setAttribute('data-operation', this.operation());
Nils Diewald966abf12014-12-20 02:27:45 +0000739
Nils Diewald5c817a42015-01-06 01:08:56 +0000740 _removeChildren(group);
Nils Diewald966abf12014-12-20 02:27:45 +0000741
742 // Append operands
Nils Diewald5c817a42015-01-06 01:08:56 +0000743 for (var i in this._operands) {
744 group.appendChild(
Nils Diewald966abf12014-12-20 02:27:45 +0000745 this.getOperand(i).element()
746 );
747 };
748
749 // Set operators
750 var op = this.operators(
751 this.operation() == 'and' ? false : true,
752 this.operation() == 'or' ? false : true,
753 true
754 );
755
Nils Diewald5c817a42015-01-06 01:08:56 +0000756 group.appendChild(
Nils Diewald966abf12014-12-20 02:27:45 +0000757 op.element()
758 );
759
Nils Diewald5c817a42015-01-06 01:08:56 +0000760 return this;
Nils Diewald966abf12014-12-20 02:27:45 +0000761 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000762
Nils Diewald8f4e2542014-12-19 04:42:09 +0000763 element : function () {
764 if (this._element !== undefined)
765 return this._element;
766
767 this._element = document.createElement('div');
768 this._element.setAttribute('class', 'docGroup');
Nils Diewald8f4e2542014-12-19 04:42:09 +0000769
Nils Diewaldf219eb82015-01-07 20:15:42 +0000770 // Update the object - including optimization
Nils Diewald966abf12014-12-20 02:27:45 +0000771 this.update();
Nils Diewald8f4e2542014-12-19 04:42:09 +0000772
773 return this._element;
774 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000775
Nils Diewald8f4e2542014-12-19 04:42:09 +0000776 operation : function (op) {
777 if (arguments.length === 1) {
778 if (KorAP._validGroupOpRE.test(op)) {
779 this._op = op;
780 }
781 else {
782 KorAP.log(810, "Unknown operation type");
783 return;
784 };
785 };
786 return this._op || 'and';
787 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000788
Nils Diewald8f4e2542014-12-19 04:42:09 +0000789 operands : function () {
790 return this._operands;
791 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000792
Nils Diewald8f4e2542014-12-19 04:42:09 +0000793 getOperand : function (index) {
794 return this._operands[index];
795 },
796
Nils Diewald5c817a42015-01-06 01:08:56 +0000797 // Replace operand
Nils Diewaldf219eb82015-01-07 20:15:42 +0000798 replaceOperand : function (oldOp, newOp) {
Nils Diewald8e7182e2015-01-08 15:02:07 +0000799
Nils Diewald5c817a42015-01-06 01:08:56 +0000800 for (var i in this._operands) {
Nils Diewaldf219eb82015-01-07 20:15:42 +0000801 if (this._operands[i] === oldOp) {
802
803 // Just insert a doc
804 if (newOp.ldType() === "doc") {
Nils Diewaldf219eb82015-01-07 20:15:42 +0000805 this._operands[i] = newOp;
Nils Diewald8f6b6102015-01-08 18:25:33 +0000806 newOp.parent(this);
Nils Diewaldf219eb82015-01-07 20:15:42 +0000807 }
808 // Insert a group of a different operation
809 // (i.e. "and" in "or"/"or" in "and")
Nils Diewald8e7182e2015-01-08 15:02:07 +0000810 else if (newOp.operation() != this.operation()) {
Nils Diewaldf219eb82015-01-07 20:15:42 +0000811 this._operands[i] = newOp;
Nils Diewald8f6b6102015-01-08 18:25:33 +0000812 newOp.parent(this);
Nils Diewaldf219eb82015-01-07 20:15:42 +0000813 }
814
815 // Flatten the group
816 else {
Nils Diewald8e7182e2015-01-08 15:02:07 +0000817 // Remove old group
818 this._operands.splice(i, 1);
819
820 // Inject new operands
Nils Diewald8f6b6102015-01-08 18:25:33 +0000821 for (var op in newOp.operands().reverse()) {
822 this._operands.splice(i, 0, newOp.getOperand(op));
823 newOp.getOperand(0).parent(this);
824 };
825 // Prevent destruction of operands
826 newOp._operands = [];
827 newOp.destroy();
Nils Diewaldf219eb82015-01-07 20:15:42 +0000828 };
829 oldOp.destroy();
830 return this;
Nils Diewald5c817a42015-01-06 01:08:56 +0000831 }
832 };
833 return false;
834 },
835
Nils Diewald0297ba12015-01-05 21:56:12 +0000836 // Delete operand from group
837 delOperand : function (obj) {
838 for (var i in this._operands) {
839 if (this._operands[i] === obj) {
Nils Diewald8e7182e2015-01-08 15:02:07 +0000840
Nils Diewald8f6b6102015-01-08 18:25:33 +0000841 // Delete identified operand
Nils Diewald0297ba12015-01-05 21:56:12 +0000842 this._operands.splice(i,1);
843
Nils Diewald5c817a42015-01-06 01:08:56 +0000844 // Destroy object for cyclic references
845 obj.destroy();
846
Nils Diewaldf219eb82015-01-07 20:15:42 +0000847 return this;
Nils Diewald0297ba12015-01-05 21:56:12 +0000848 };
849 };
Nils Diewald5c817a42015-01-06 01:08:56 +0000850
851 // Operand not found
852 return undefined;
Nils Diewald0297ba12015-01-05 21:56:12 +0000853 },
854
Nils Diewald8f4e2542014-12-19 04:42:09 +0000855 // Deserialize from json
856 fromJson : function (json) {
857 if (json === undefined)
858 return this;
859
860 if (json["@type"] !== "korap:docGroup") {
861 KorAP.log(701, "JSON-LD group has no @type attribute");
862 return;
863 };
864
865 if (json["operation"] === undefined ||
866 typeof json["operation"] !== 'string') {
867 KorAP.log(811, "Document group expects operation");
868 return;
869 };
870
871 var operation = json["operation"];
872
873 this.operation(operation.replace(/^operation:/,''));
874
875 if (json["operands"] === undefined ||
876 !(json["operands"] instanceof Array)) {
877 KorAP.log(704, "Operation needs operand list")
878 return;
879 };
880
881 // Add all documents
882 for (var i in json["operands"]) {
883 var operand = json["operands"][i];
Nils Diewald966abf12014-12-20 02:27:45 +0000884 this.append(operand);
Nils Diewald8f4e2542014-12-19 04:42:09 +0000885 };
886
887 return this;
888 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000889
Nils Diewald8f4e2542014-12-19 04:42:09 +0000890 toJson : function () {
891 var opArray = new Array();
892 for (var i in this._operands) {
893 opArray.push(this._operands[i].toJson());
894 };
895 return {
896 "@type" : "korap:" + this.ldType(),
897 "operation" : "operation:" + this.operation(),
898 "operands" : opArray
899 };
Nils Diewaldf219eb82015-01-07 20:15:42 +0000900 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000901
902 toQuery : function () {
Nils Diewaldf219eb82015-01-07 20:15:42 +0000903 return this._operands.
904 map(function (op) {
Nils Diewaldd599d542015-01-08 20:41:34 +0000905 return (op.ldType() === 'docGroup') ?
906 '(' + op.toQuery() + ')' :
907 op.toQuery();
908 }).join(this.operation() === 'or' ? ' | ' : ' & ')
Nils Diewald8f4e2542014-12-19 04:42:09 +0000909 }
910 };
911
912
Nils Diewaldd599d542015-01-08 20:41:34 +0000913 /**
914 * Abstract JsonLD criterion object
915 */
Nils Diewald8f4e2542014-12-19 04:42:09 +0000916 KorAP.JsonLD = {
Nils Diewald8f6b6102015-01-08 18:25:33 +0000917 _changed : false,
918
Nils Diewald8f4e2542014-12-19 04:42:09 +0000919 create : function () {
920 return Object.create(KorAP.JsonLD);
921 },
922
923 /**
924 * Upgrade this object to another object
925 * while private data stays intact
926 */
927 upgradeTo : function (props) {
928 for (var prop in props) {
929 this[prop] = props[prop];
930 };
931 return this;
932 },
Nils Diewald8f6b6102015-01-08 18:25:33 +0000933
Nils Diewald8f4e2542014-12-19 04:42:09 +0000934 ldType : function (type) {
935 if (arguments.length === 1)
936 this._ldType = type;
937 return this._ldType;
938 },
Nils Diewald8f6b6102015-01-08 18:25:33 +0000939
Nils Diewald8f4e2542014-12-19 04:42:09 +0000940 parent : function (obj) {
Nils Diewald8f6b6102015-01-08 18:25:33 +0000941 if (arguments.length === 1) {
Nils Diewald8f4e2542014-12-19 04:42:09 +0000942 this._parent = obj;
Nils Diewald8f6b6102015-01-08 18:25:33 +0000943 this._changed = true;
944 };
Nils Diewald8f4e2542014-12-19 04:42:09 +0000945 return this._parent;
Nils Diewald966abf12014-12-20 02:27:45 +0000946 },
Nils Diewald0297ba12015-01-05 21:56:12 +0000947
Nils Diewald5c817a42015-01-06 01:08:56 +0000948 // Destroy object - especially for
949 // acyclic structures!
950 // I'm a paranoid chicken!
951 destroy : function () {
952 if (this._ops != undefined) {
953 this._ops._parent = undefined;
954 if (this._ops._element !== undefined)
955 this._ops._element.refTo = undefined;
956 this._ops = undefined;
957 };
958 if (this._element !== undefined)
959 this._element = undefined;
960
961 // In case of a group, destroy all operands
962 if (this._operands !== undefined) {
963 for (var i in this._operands)
964 this.getOperand(i).destroy();
Nils Diewaldf219eb82015-01-07 20:15:42 +0000965 this._operands = [];
Nils Diewald5c817a42015-01-06 01:08:56 +0000966 };
967 },
968
Nils Diewald0297ba12015-01-05 21:56:12 +0000969 // Be aware! This may be cyclic
Nils Diewald966abf12014-12-20 02:27:45 +0000970 operators : function (and, or, del) {
971 if (arguments === 0)
972 return this._ops;
973 this._ops = KorAP.Operators.create(
974 and, or, del
975 );
Nils Diewald0297ba12015-01-05 21:56:12 +0000976 this._ops.parent(this);
Nils Diewald966abf12014-12-20 02:27:45 +0000977 return this._ops;
978 },
Nils Diewald8f6b6102015-01-08 18:25:33 +0000979
Nils Diewald966abf12014-12-20 02:27:45 +0000980 toJson : function () {
981 return {
982 // Unspecified object
983 "@type" : "korap:" + this.ldType()
984 };
Nils Diewald8f6b6102015-01-08 18:25:33 +0000985 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000986
987 toQuery : function () {
Nils Diewald8f6b6102015-01-08 18:25:33 +0000988 return loc.EMPTY;
Nils Diewald8f4e2542014-12-19 04:42:09 +0000989 }
990 };
991
Nils Diewald3a2d8022014-12-16 02:45:41 +0000992}(this.KorAP));