blob: 31ddc856659ba21467c6ff93da545d737ccb6485 [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/*
8 * Error codes:
9 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)$");
35
Nils Diewaldd0770492014-12-19 03:55:00 +000036 var loc = (KorAP.Locale = KorAP.Locale || {} );
37 loc.AND = loc.AND || 'and';
38 loc.OR = loc.OR || 'or';
39 loc.DEL = loc.DEL || '×';
40
Nils Diewald966abf12014-12-20 02:27:45 +000041 function _bool (bool) {
42 return (bool === undefined || bool === false) ? false : true;
43 };
44
45 function _removeChildren (node) {
46 // Remove everything underneath
47 while (node.firstChild) {
48 node.removeChild(node.firstChild);
49 };
50 };
51
Nils Diewald3a2d8022014-12-16 02:45:41 +000052 KorAP.VirtualCollection = {
Nils Diewaldd0770492014-12-19 03:55:00 +000053 _root : undefined,
Nils Diewald3a2d8022014-12-16 02:45:41 +000054 create : function () {
55 return Object.create(KorAP.VirtualCollection);
56 },
Nils Diewaldd0770492014-12-19 03:55:00 +000057 render : function (json) {
58 var obj = Object.create(KorAP.VirtualCollection);
59
60 if (json !== undefined) {
61 // Root object
62 if (json['@type'] == 'korap:doc') {
Nils Diewald8f4e2542014-12-19 04:42:09 +000063 obj._root = KorAP.Doc.create(undefined, json);
Nils Diewaldd0770492014-12-19 03:55:00 +000064 }
65 else if (json['@type'] == 'korap:docGroup') {
Nils Diewald8f4e2542014-12-19 04:42:09 +000066 obj._root = KorAP.DocGroup.create(undefined, json);
Nils Diewaldd0770492014-12-19 03:55:00 +000067 }
68 else {
69 KorAP.log(813, "Collection type is not supported");
70 return;
71 };
72 }
73
74 else {
75 // Add unspecified object
Nils Diewald8f4e2542014-12-19 04:42:09 +000076 obj._root = KorAP.UnspecifiedDoc.create();
Nils Diewaldd0770492014-12-19 03:55:00 +000077 };
78
79 // Add root element to root node
80 obj.element().appendChild(
81 obj._root.element()
82 );
83
84 return obj;
Nils Diewald3a2d8022014-12-16 02:45:41 +000085 },
Nils Diewaldd0770492014-12-19 03:55:00 +000086 root : function () {
87 return this._root;
Nils Diewald3a2d8022014-12-16 02:45:41 +000088 },
Nils Diewaldd0770492014-12-19 03:55:00 +000089 element : function () {
90 if (this._element !== undefined)
91 return this._element;
92
93 this._element = document.createElement('div');
94 this._element.setAttribute('class', 'vc');
95 return this._element;
Nils Diewald3a2d8022014-12-16 02:45:41 +000096 }
97 };
98
Nils Diewald0297ba12015-01-05 21:56:12 +000099 KorAP._or = function (e) {
100 var obj = this.parentNode.refTo;
101 };
102
103 KorAP._and = function (e) {
104 var obj = this.parentNode.refTo;
105 };
106
107 KorAP._delete = function (e) {
108 var obj = this.parentNode.refTo;
109 obj.parent().delOperand(obj);
110 // Todo: CLEAR ALL THE THINGS!
111 };
112
Nils Diewald8f4e2542014-12-19 04:42:09 +0000113 /**
114 * Operators for criteria
115 */
Nils Diewaldd0770492014-12-19 03:55:00 +0000116 KorAP.Operators = {
117 create : function (and, or, del) {
118 var op = Object.create(KorAP.Operators);
119 op.and(and);
120 op.or(or);
121 op.del(del);
122 return op;
123 },
124 update : function () {
125
126 // Init the element
127 if (this._element === undefined)
128 return this.element();
129
130 var op = this._element;
131
Nils Diewald0297ba12015-01-05 21:56:12 +0000132 op.refTo = this.parent();
133
Nils Diewaldd0770492014-12-19 03:55:00 +0000134 // Remove everything underneath
Nils Diewald966abf12014-12-20 02:27:45 +0000135 _removeChildren(op);
Nils Diewaldd0770492014-12-19 03:55:00 +0000136
137 // Add and button
138 if (this._and === true) {
139 var andE = document.createElement('span');
140 andE.setAttribute('class', 'and');
Nils Diewald0297ba12015-01-05 21:56:12 +0000141 andE.addEventListener('click', KorAP._and, false);
Nils Diewaldd0770492014-12-19 03:55:00 +0000142 andE.appendChild(document.createTextNode(KorAP.Locale.AND));
143 op.appendChild(andE);
144 };
145
146 // Add or button
147 if (this._or === true) {
148 var orE = document.createElement('span');
149 orE.setAttribute('class', 'or');
Nils Diewald0297ba12015-01-05 21:56:12 +0000150 orE.addEventListener('click', KorAP._or, false);
Nils Diewaldd0770492014-12-19 03:55:00 +0000151 orE.appendChild(document.createTextNode(KorAP.Locale.OR));
152 op.appendChild(orE);
153 };
154
155 // Add delete button
156 if (this._del === true) {
157 var delE = document.createElement('span');
158 delE.setAttribute('class', 'delete');
159 delE.appendChild(document.createTextNode(KorAP.Locale.DEL));
Nils Diewald0297ba12015-01-05 21:56:12 +0000160 delE.addEventListener('click', KorAP._delete, false);
Nils Diewaldd0770492014-12-19 03:55:00 +0000161 op.appendChild(delE);
162 };
Nils Diewald966abf12014-12-20 02:27:45 +0000163
164 return op;
Nils Diewaldd0770492014-12-19 03:55:00 +0000165 },
Nils Diewald0297ba12015-01-05 21:56:12 +0000166
167 // Be aware! This may be cyclic
168 parent : function (obj) {
169 if (arguments.length === 1)
170 this._parent = obj;
171 return this._parent;
172 },
Nils Diewald5c817a42015-01-06 01:08:56 +0000173
Nils Diewaldd0770492014-12-19 03:55:00 +0000174 element : function () {
175
176 // Return existing element
177 if (this._element !== undefined)
178 return this._element;
179
180 this._element = document.createElement('div');
181 this._element.setAttribute('class', 'operators');
182
183 // Init elements
184 this.update();
185 return this._element;
186 },
187 and : function (bool) {
188 if (arguments.length === 1)
Nils Diewald966abf12014-12-20 02:27:45 +0000189 this._and = _bool(bool);
Nils Diewaldd0770492014-12-19 03:55:00 +0000190 return this._and;
191 },
192 or : function (bool) {
193 if (arguments.length === 1)
Nils Diewald966abf12014-12-20 02:27:45 +0000194 this._or = _bool(bool);
Nils Diewaldd0770492014-12-19 03:55:00 +0000195 return this._or;
196 },
197 del : function (bool) {
198 if (arguments.length === 1)
Nils Diewald966abf12014-12-20 02:27:45 +0000199 this._del = _bool(bool);
Nils Diewaldd0770492014-12-19 03:55:00 +0000200 return this._del;
201 }
202 };
203
204
205 /**
206 * Unspecified criterion
207 */
Nils Diewald8f4e2542014-12-19 04:42:09 +0000208 KorAP.UnspecifiedDoc = {
Nils Diewald966abf12014-12-20 02:27:45 +0000209 _ldType : "doc",
Nils Diewaldd0770492014-12-19 03:55:00 +0000210 create : function (parent) {
Nils Diewald8f4e2542014-12-19 04:42:09 +0000211 var obj = Object.create(KorAP.JsonLD).upgradeTo(KorAP.UnspecifiedDoc);
Nils Diewaldd0770492014-12-19 03:55:00 +0000212 if (parent !== undefined)
213 obj._parent = parent;
214 return obj;
215 },
Nils Diewald966abf12014-12-20 02:27:45 +0000216 update : function () {
217 if (this._element === undefined)
218 return this.element();
219
220 _removeChildren(this._element);
221
222 var ellipsis = document.createElement('span');
223 ellipsis.appendChild(document.createTextNode('⋯'));
224 this._element.appendChild(ellipsis);
225
226 // Set operators
227 var op = this.operators(
228 false,
229 false,
230 // No delete object, if this is the root
231 this._parent !== undefined ? true : false
232 );
233
234 this._element.appendChild(
235 op.element()
236 );
237
Nils Diewald966abf12014-12-20 02:27:45 +0000238 return this.element();
239 },
Nils Diewaldd0770492014-12-19 03:55:00 +0000240 element : function () {
241 if (this._element !== undefined)
242 return this._element;
Nils Diewald966abf12014-12-20 02:27:45 +0000243
Nils Diewaldd0770492014-12-19 03:55:00 +0000244 this._element = document.createElement('div');
Nils Diewald966abf12014-12-20 02:27:45 +0000245 this._element.setAttribute('class', 'unspecified');
246
247 this.update();
Nils Diewaldd0770492014-12-19 03:55:00 +0000248 return this._element;
249 }
250 };
251
252
Nils Diewald8f4e2542014-12-19 04:42:09 +0000253 /**
254 * Virtual collection doc criterion.
255 */
256 KorAP.Doc = {
257 _ldType : "doc",
258 _obj : function () { return KorAP.Doc; },
Nils Diewaldd0770492014-12-19 03:55:00 +0000259
260 create : function (parent, json) {
Nils Diewald8f4e2542014-12-19 04:42:09 +0000261 var obj = Object(KorAP.JsonLD).create().upgradeTo(KorAP.Doc).fromJson(json);
Nils Diewaldd0770492014-12-19 03:55:00 +0000262 if (parent !== undefined)
263 obj._parent = parent;
264 return obj;
265 },
Nils Diewald5c817a42015-01-06 01:08:56 +0000266
Nils Diewald966abf12014-12-20 02:27:45 +0000267 update : function () {
268 if (this._element === undefined)
269 return this.element();
Nils Diewaldd0770492014-12-19 03:55:00 +0000270
271 // Added key
272 var key = document.createElement('span');
273 key.setAttribute('class', 'key');
274 if (this.key())
275 key.appendChild(document.createTextNode(this.key()));
276
277 // Added match operator
278 var matchop = document.createElement('span');
279 matchop.setAttribute('data-type', this.type());
280 matchop.setAttribute('class', 'match');
281 matchop.appendChild(document.createTextNode(this.matchop()));
282
283 // Added match operator
284 var value = document.createElement('span');
285 value.setAttribute('data-type', this.type());
286 value.setAttribute('class', 'value');
287 if (this.value())
288 value.appendChild(document.createTextNode(this.value()));
289
Nils Diewald966abf12014-12-20 02:27:45 +0000290 var e = this._element;
291
Nils Diewaldd0770492014-12-19 03:55:00 +0000292 // Add spans
293 e.appendChild(key);
294 e.appendChild(matchop);
295 e.appendChild(value);
Nils Diewald966abf12014-12-20 02:27:45 +0000296
297 // Set operators
298 var op = this.operators(true, true, true);
299
300 e.appendChild(op.element());
301
Nils Diewaldd0770492014-12-19 03:55:00 +0000302 return e;
303 },
304
Nils Diewald966abf12014-12-20 02:27:45 +0000305 element : function () {
306 if (this._element !== undefined)
307 return this._element;
308
309 this._element = document.createElement('div');
310 this._element.setAttribute('class', 'doc');
311
312 this.update();
313 return this._element;
314 },
315
Nils Diewaldd0770492014-12-19 03:55:00 +0000316 // Wrap a new operation around the doc element
317 wrap : function (op) {
Nils Diewald8f4e2542014-12-19 04:42:09 +0000318 var group = KorAP.DocGroup.create(undefined);
Nils Diewald966abf12014-12-20 02:27:45 +0000319 group.append(this);
320 group.append(null);
Nils Diewaldd0770492014-12-19 03:55:00 +0000321 this.parent(group);
322/*
323 var div = document.createElement('div');
324 div.setAttribute('data-operation', op);
325 var parent = this.element.parent;
326 parent.removeChild(this.element);
327 parent.appendChild(div);
328 div.appendChild(this.element);
329 return div;
330*/
Nils Diewaldd0770492014-12-19 03:55:00 +0000331 },
Nils Diewald3a2d8022014-12-16 02:45:41 +0000332 // Deserialize from json
333 fromJson : function (json) {
Nils Diewald3a2d8022014-12-16 02:45:41 +0000334 if (json === undefined)
Nils Diewaldd0770492014-12-19 03:55:00 +0000335 return this;
Nils Diewald3a2d8022014-12-16 02:45:41 +0000336
Nils Diewald3a2d8022014-12-16 02:45:41 +0000337 if (json["@type"] !== "korap:doc") {
338 KorAP.log(701, "JSON-LD group has no @type attribute");
339 return;
340 };
341
Nils Diewald3a2d8022014-12-16 02:45:41 +0000342 if (json["value"] === undefined ||
343 typeof json["value"] != 'string') {
344 KorAP.log(805, "Value is invalid");
345 return;
346 };
347
348 // There is a defined key
349 if (json["key"] !== undefined &&
350 typeof json["key"] === 'string') {
351
352 // Set key
Nils Diewaldd0770492014-12-19 03:55:00 +0000353 this.key(json["key"]);
Nils Diewald3a2d8022014-12-16 02:45:41 +0000354
355 // Set match operation
356 if (json["match"] !== undefined) {
Nils Diewaldd0770492014-12-19 03:55:00 +0000357 if (typeof json["match"] === 'string') {
358 this.matchop(json["match"]);
359 }
Nils Diewald3a2d8022014-12-16 02:45:41 +0000360 else {
361 KorAP.log(802, "Match type is not supported by value type");
362 return;
363 };
364 };
365
366 // Key is a string
367 if (json["type"] === undefined ||
368 json["type"] == "type:string") {
Nils Diewaldd0770492014-12-19 03:55:00 +0000369 this.type("string");
Nils Diewald3a2d8022014-12-16 02:45:41 +0000370
371 // Check match type
Nils Diewaldd0770492014-12-19 03:55:00 +0000372 if (!KorAP._validStringMatchRE.test(this.matchop())) {
Nils Diewald3a2d8022014-12-16 02:45:41 +0000373 KorAP.log(802, "Match type is not supported by value type");
374 return;
375 };
376
377 // Set string value
Nils Diewaldd0770492014-12-19 03:55:00 +0000378 this.value(json["value"]);
Nils Diewald3a2d8022014-12-16 02:45:41 +0000379 }
380
381 // Key is a date
382 else if (json["type"] === "type:date") {
Nils Diewaldd0770492014-12-19 03:55:00 +0000383 this.type("date");
Nils Diewald3a2d8022014-12-16 02:45:41 +0000384
385 if (json["value"] !== undefined &&
386 KorAP._validDateRE.test(json["value"])) {
387
Nils Diewaldd0770492014-12-19 03:55:00 +0000388 if (!KorAP._validDateMatchRE.test(this.matchop())) {
Nils Diewald3a2d8022014-12-16 02:45:41 +0000389 KorAP.log(802, "Match type is not supported by value type");
390 return;
391 };
392
393 // Set value
Nils Diewaldd0770492014-12-19 03:55:00 +0000394 this.value(json["value"]);
Nils Diewald3a2d8022014-12-16 02:45:41 +0000395 }
396 else {
397 KorAP.log(806, "Value is not a valid date string");
398 return;
399 };
400 }
401
402 // Key is a regular expression
403 else if (json["type"] === "type:regex") {
Nils Diewaldd0770492014-12-19 03:55:00 +0000404 this.type("regex");
Nils Diewald3a2d8022014-12-16 02:45:41 +0000405
406 try {
407
408 // Try to create a regular expression
409 var check = new RegExp(json["value"]);
410
Nils Diewaldd0770492014-12-19 03:55:00 +0000411 if (!KorAP._validRegexMatchRE.test(this.matchop())) {
Nils Diewald3a2d8022014-12-16 02:45:41 +0000412 KorAP.log(802, "Match type is not supported by value type");
413 return;
414 };
415
Nils Diewaldd0770492014-12-19 03:55:00 +0000416 this.value(json["value"]);
Nils Diewald3a2d8022014-12-16 02:45:41 +0000417 }
Nils Diewaldd0770492014-12-19 03:55:00 +0000418
Nils Diewald3a2d8022014-12-16 02:45:41 +0000419 catch (e) {
420 KorAP.log(807, "Value is not a valid regular expression");
421 return;
422 };
Nils Diewaldd0770492014-12-19 03:55:00 +0000423 this.type("regex");
Nils Diewald3a2d8022014-12-16 02:45:41 +0000424 }
425
426 else {
427 KorAP.log(804, "Unknown value type");
428 return;
429 };
430 };
431
432 return this;
433 },
Nils Diewaldd0770492014-12-19 03:55:00 +0000434 key : function (value) {
435 if (arguments.length === 1)
436 this._key = value;
Nils Diewald3a2d8022014-12-16 02:45:41 +0000437 return this._key;
438 },
Nils Diewaldd0770492014-12-19 03:55:00 +0000439 matchop : function (match) {
440 if (arguments.length === 1)
441 this._matchop = match.replace(/^match:/, '');
Nils Diewald3a2d8022014-12-16 02:45:41 +0000442 return this._matchop || "eq";
443 },
Nils Diewaldd0770492014-12-19 03:55:00 +0000444 type : function (type) {
445 if (arguments.length === 1)
446 this._type = type;
Nils Diewald3a2d8022014-12-16 02:45:41 +0000447 return this._type || "string";
448 },
Nils Diewaldd0770492014-12-19 03:55:00 +0000449 value : function (value) {
450 if (arguments.length === 1)
451 this._value = value;
Nils Diewald3a2d8022014-12-16 02:45:41 +0000452 return this._value;
453 },
Nils Diewald3a2d8022014-12-16 02:45:41 +0000454 toJson : function () {
Nils Diewaldd0770492014-12-19 03:55:00 +0000455 if (!this.matchop() || !this.key())
Nils Diewald3a2d8022014-12-16 02:45:41 +0000456 return {};
457
458 return {
Nils Diewaldd0770492014-12-19 03:55:00 +0000459 "@type" : "korap:" + this.ldType(),
460 "key" : this.key(),
461 "match" : "match:" + this.matchop(),
462 "value" : this.value() || '',
463 "type" : "type:" + this.type()
Nils Diewald3a2d8022014-12-16 02:45:41 +0000464 };
465 }
466 };
Nils Diewald8f4e2542014-12-19 04:42:09 +0000467
468 /**
469 * Virtual collection group criterion.
470 */
471 KorAP.DocGroup = {
472 _ldType : "docGroup",
473
474 create : function (parent, json) {
475 var obj = Object.create(KorAP.JsonLD).upgradeTo(KorAP.DocGroup);
476 obj._operands = [];
477 obj.fromJson(json);
478 if (parent !== undefined)
479 obj._parent = parent;
480 return obj;
481 },
Nils Diewald966abf12014-12-20 02:27:45 +0000482 append : function (operand) {
483
484 // Append unspecified object
485 if (operand === undefined) {
486
487 // Be aware of cyclic structures!
488 operand = KorAP.UnspecifiedDoc.create(this);
489 this._operands.push(operand);
490 this.update();
491 return operand;
492 };
493
Nils Diewald8f4e2542014-12-19 04:42:09 +0000494 switch (operand["@type"]) {
495 case undefined:
496 if (operand["ldType"] !== undefined) {
497 if (operand.ldType() !== 'doc' &&
Nils Diewald966abf12014-12-20 02:27:45 +0000498 operand.ldType() !== 'docGroup') {
Nils Diewald8f4e2542014-12-19 04:42:09 +0000499 KorAP.log(812, "Operand not supported in document group");
500 return;
501 };
Nils Diewald966abf12014-12-20 02:27:45 +0000502 // Be aware of cyclic structures!
503 operand.parent(this);
Nils Diewald8f4e2542014-12-19 04:42:09 +0000504 this._operands.push(operand);
Nils Diewald966abf12014-12-20 02:27:45 +0000505 this.update();
Nils Diewald8f4e2542014-12-19 04:42:09 +0000506 return operand;
507 };
508
509 KorAP.log(701, "JSON-LD group has no @type attribute");
510 return;
511
512 case "korap:doc":
Nils Diewald966abf12014-12-20 02:27:45 +0000513 // Be aware of cyclic structures!
514 var doc = KorAP.Doc.create(this, operand);
Nils Diewald8f4e2542014-12-19 04:42:09 +0000515 if (doc === undefined)
516 return;
517 this._operands.push(doc);
Nils Diewald966abf12014-12-20 02:27:45 +0000518 this.update();
Nils Diewald8f4e2542014-12-19 04:42:09 +0000519 return doc;
520
521 case "korap:docGroup":
Nils Diewald966abf12014-12-20 02:27:45 +0000522 // Be aware of cyclic structures!
523 var docGroup = KorAP.DocGroup.create(this, operand);
Nils Diewald8f4e2542014-12-19 04:42:09 +0000524 if (docGroup === undefined)
525 return;
526 this._operands.push(docGroup);
Nils Diewald966abf12014-12-20 02:27:45 +0000527 this.update();
Nils Diewald8f4e2542014-12-19 04:42:09 +0000528 return docGroup;
529
530 default:
531 KorAP.log(812, "Operand not supported in document group");
532 return;
533 };
534 },
Nils Diewald966abf12014-12-20 02:27:45 +0000535 update : function () {
Nils Diewald5c817a42015-01-06 01:08:56 +0000536 if (this._operands.length == 1) {
537 if (this.parent() !== undefined) {
538 return this.parent().replaceOperand(
539 this,
540 this.getOperand(0)
541 );
542 };
543 };
544
Nils Diewald966abf12014-12-20 02:27:45 +0000545 if (this._element === undefined)
Nils Diewald5c817a42015-01-06 01:08:56 +0000546 return this;
Nils Diewald966abf12014-12-20 02:27:45 +0000547
Nils Diewald5c817a42015-01-06 01:08:56 +0000548 var group = this._element;
549 group.setAttribute('data-operation', this.operation());
Nils Diewald966abf12014-12-20 02:27:45 +0000550
Nils Diewald5c817a42015-01-06 01:08:56 +0000551 _removeChildren(group);
Nils Diewald966abf12014-12-20 02:27:45 +0000552
553 // Append operands
Nils Diewald5c817a42015-01-06 01:08:56 +0000554 for (var i in this._operands) {
555 group.appendChild(
Nils Diewald966abf12014-12-20 02:27:45 +0000556 this.getOperand(i).element()
557 );
558 };
559
560 // Set operators
561 var op = this.operators(
562 this.operation() == 'and' ? false : true,
563 this.operation() == 'or' ? false : true,
564 true
565 );
566
Nils Diewald5c817a42015-01-06 01:08:56 +0000567 group.appendChild(
Nils Diewald966abf12014-12-20 02:27:45 +0000568 op.element()
569 );
570
Nils Diewald5c817a42015-01-06 01:08:56 +0000571 return this;
Nils Diewald966abf12014-12-20 02:27:45 +0000572 },
Nils Diewald8f4e2542014-12-19 04:42:09 +0000573 element : function () {
574 if (this._element !== undefined)
575 return this._element;
576
577 this._element = document.createElement('div');
578 this._element.setAttribute('class', 'docGroup');
Nils Diewald8f4e2542014-12-19 04:42:09 +0000579
Nils Diewald966abf12014-12-20 02:27:45 +0000580 this.update();
Nils Diewald8f4e2542014-12-19 04:42:09 +0000581
582 return this._element;
583 },
584 operation : function (op) {
585 if (arguments.length === 1) {
586 if (KorAP._validGroupOpRE.test(op)) {
587 this._op = op;
588 }
589 else {
590 KorAP.log(810, "Unknown operation type");
591 return;
592 };
593 };
594 return this._op || 'and';
595 },
596 operands : function () {
597 return this._operands;
598 },
599 getOperand : function (index) {
600 return this._operands[index];
601 },
602
Nils Diewald5c817a42015-01-06 01:08:56 +0000603 // Replace operand
604 replaceOperand : function (group, obj) {
605 for (var i in this._operands) {
606 if (this._operands[i] === group) {
607 this._operands[i] = obj;
608 group.destroy();
609 return this.update();
610 }
611 };
612 return false;
613 },
614
Nils Diewald0297ba12015-01-05 21:56:12 +0000615 // Delete operand from group
616 delOperand : function (obj) {
617 for (var i in this._operands) {
618 if (this._operands[i] === obj) {
619 this._operands.splice(i,1);
620
Nils Diewald5c817a42015-01-06 01:08:56 +0000621 // Destroy object for cyclic references
622 obj.destroy();
623
Nils Diewald0297ba12015-01-05 21:56:12 +0000624 // Todo: Update has to check
625 // that this may mean the group is empty etc.
Nils Diewald5c817a42015-01-06 01:08:56 +0000626 return this.update();
Nils Diewald0297ba12015-01-05 21:56:12 +0000627 };
628 };
Nils Diewald5c817a42015-01-06 01:08:56 +0000629
630 // Operand not found
631 return undefined;
Nils Diewald0297ba12015-01-05 21:56:12 +0000632 },
633
Nils Diewald8f4e2542014-12-19 04:42:09 +0000634 // Deserialize from json
635 fromJson : function (json) {
636 if (json === undefined)
637 return this;
638
639 if (json["@type"] !== "korap:docGroup") {
640 KorAP.log(701, "JSON-LD group has no @type attribute");
641 return;
642 };
643
644 if (json["operation"] === undefined ||
645 typeof json["operation"] !== 'string') {
646 KorAP.log(811, "Document group expects operation");
647 return;
648 };
649
650 var operation = json["operation"];
651
652 this.operation(operation.replace(/^operation:/,''));
653
654 if (json["operands"] === undefined ||
655 !(json["operands"] instanceof Array)) {
656 KorAP.log(704, "Operation needs operand list")
657 return;
658 };
659
660 // Add all documents
661 for (var i in json["operands"]) {
662 var operand = json["operands"][i];
Nils Diewald966abf12014-12-20 02:27:45 +0000663 this.append(operand);
Nils Diewald8f4e2542014-12-19 04:42:09 +0000664 };
665
666 return this;
667 },
668 toJson : function () {
669 var opArray = new Array();
670 for (var i in this._operands) {
671 opArray.push(this._operands[i].toJson());
672 };
673 return {
674 "@type" : "korap:" + this.ldType(),
675 "operation" : "operation:" + this.operation(),
676 "operands" : opArray
677 };
678 }
679 };
680
681
682 // Abstract JsonLD object
683 KorAP.JsonLD = {
684 create : function () {
685 return Object.create(KorAP.JsonLD);
686 },
687
688 /**
689 * Upgrade this object to another object
690 * while private data stays intact
691 */
692 upgradeTo : function (props) {
693 for (var prop in props) {
694 this[prop] = props[prop];
695 };
696 return this;
697 },
698 ldType : function (type) {
699 if (arguments.length === 1)
700 this._ldType = type;
701 return this._ldType;
702 },
703 parent : function (obj) {
704 if (arguments.length === 1)
705 this._parent = obj;
706 return this._parent;
Nils Diewald966abf12014-12-20 02:27:45 +0000707 },
Nils Diewald0297ba12015-01-05 21:56:12 +0000708
Nils Diewald5c817a42015-01-06 01:08:56 +0000709 // Destroy object - especially for
710 // acyclic structures!
711 // I'm a paranoid chicken!
712 destroy : function () {
713 if (this._ops != undefined) {
714 this._ops._parent = undefined;
715 if (this._ops._element !== undefined)
716 this._ops._element.refTo = undefined;
717 this._ops = undefined;
718 };
719 if (this._element !== undefined)
720 this._element = undefined;
721
722 // In case of a group, destroy all operands
723 if (this._operands !== undefined) {
724 for (var i in this._operands)
725 this.getOperand(i).destroy();
726 };
727 },
728
Nils Diewald0297ba12015-01-05 21:56:12 +0000729 // Be aware! This may be cyclic
Nils Diewald966abf12014-12-20 02:27:45 +0000730 operators : function (and, or, del) {
731 if (arguments === 0)
732 return this._ops;
733 this._ops = KorAP.Operators.create(
734 and, or, del
735 );
Nils Diewald0297ba12015-01-05 21:56:12 +0000736 this._ops.parent(this);
Nils Diewald966abf12014-12-20 02:27:45 +0000737 return this._ops;
738 },
739 toJson : function () {
740 return {
741 // Unspecified object
742 "@type" : "korap:" + this.ldType()
743 };
Nils Diewald8f4e2542014-12-19 04:42:09 +0000744 }
745 };
746
Nils Diewald3a2d8022014-12-16 02:45:41 +0000747}(this.KorAP));