blob: 2587d1ced0c099d12f4e5eaf413f8c5692bfffe0 [file] [log] [blame]
Nils Diewald86dad5b2015-01-28 15:09:07 +00001/**
2 * Create virtual collections with a visual user interface.
3 *
4 * @author Nils Diewald
5 */
Nils Diewald2fe12e12015-03-06 16:47:06 +00006/*
Nils Diewald1fcb2ad2015-04-20 19:19:18 +00007 * This replaces a previous version written by Mengfei Zhou
Nils Diewald2fe12e12015-03-06 16:47:06 +00008 */
Nils Diewald2fe12e12015-03-06 16:47:06 +00009
Nils Diewaldd0770492014-12-19 03:55:00 +000010/*
Nils Diewald86dad5b2015-01-28 15:09:07 +000011 TODO: Disable "and" or "or" in case it's followed
12 by an unspecified document
Nils Diewald1fcb2ad2015-04-20 19:19:18 +000013 TODO: Implement "persistence"-Option,
Nils Diewald6e43ffd2015-03-25 18:55:39 +000014 injecting the current creation date stamp
Nils Diewald86dad5b2015-01-28 15:09:07 +000015
Nils Diewaldd599d542015-01-08 20:41:34 +000016 Error codes:
Nils Diewaldd0770492014-12-19 03:55:00 +000017 701: "JSON-LD group has no @type attribute"
18 704: "Operation needs operand list"
Nils Diewald3a2d8022014-12-16 02:45:41 +000019 802: "Match type is not supported by value type"
20 804: "Unknown value type"
21 805: "Value is invalid"
22 806: "Value is not a valid date string"
23 807: "Value is not a valid regular expression"
Nils Diewald3a2d8022014-12-16 02:45:41 +000024 810: "Unknown document group operation" (like 711)
25 811: "Document group expects operation" (like 703)
26 812: "Operand not supported in document group" (like 744)
Nils Diewaldd0770492014-12-19 03:55:00 +000027 813: "Collection type is not supported" (like 713)
Nils Diewald86dad5b2015-01-28 15:09:07 +000028 814: "Unknown rewrite operation"
29 815: "Rewrite expects source"
Nils Diewald1fcb2ad2015-04-20 19:19:18 +000030
31 Localization strings:
32 KorAP.Locale = {
33 EMPTY : '...',
34 AND : 'and',
35 OR : 'or',
36 DELETE : 'x'
37 }
Nils Diewaldd0770492014-12-19 03:55:00 +000038*/
39
Nils Diewald0e6992a2015-04-14 20:13:52 +000040define([
41 'vc/unspecified',
42 'vc/doc',
43 'vc/docgroup',
Nils Diewald1fcb2ad2015-04-20 19:19:18 +000044 'vc/menu',
Nils Diewald0e6992a2015-04-14 20:13:52 +000045 'util'
Nils Diewald1fcb2ad2015-04-20 19:19:18 +000046], function (unspecDocClass, docClass, docGroupClass, menuClass) {
Nils Diewald3a2d8022014-12-16 02:45:41 +000047 "use strict";
48
Nils Diewald359a72c2015-04-20 17:40:29 +000049 // ???
Nils Diewald86dad5b2015-01-28 15:09:07 +000050 KorAP._validStringMatchRE = new RegExp("^(?:eq|ne|contains|excludes)$");
Nils Diewaldd0770492014-12-19 03:55:00 +000051 KorAP._validDateMatchRE = new RegExp("^[lg]?eq$");
Nils Diewald3a2d8022014-12-16 02:45:41 +000052 KorAP._validDateRE = new RegExp("^(?:\\d{4})(?:-\\d\\d(?:-\\d\\d)?)?$");
Nils Diewald359a72c2015-04-20 17:40:29 +000053 KorAP._overrideStyles = false;
Nils Diewald3a2d8022014-12-16 02:45:41 +000054
Nils Diewald359a72c2015-04-20 17:40:29 +000055 var loc = KorAP.Locale;
Nils Diewaldd599d542015-01-08 20:41:34 +000056
Nils Diewald1fcb2ad2015-04-20 19:19:18 +000057 KorAP._vcKeyMenu = undefined;
58
Nils Diewaldd599d542015-01-08 20:41:34 +000059 /**
60 * Virtual Collection
61 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000062 return {
Nils Diewald1fcb2ad2015-04-20 19:19:18 +000063
64 /**
65 * The JSON-LD type of the virtual collection
66 */
Nils Diewaldf219eb82015-01-07 20:15:42 +000067 ldType : function () {
68 return null;
69 },
Nils Diewaldd599d542015-01-08 20:41:34 +000070
Nils Diewald1fcb2ad2015-04-20 19:19:18 +000071 // Initialize virtual collection
72 _init : function (keyList) {
73
74 // Inject localized css styles
Nils Diewald359a72c2015-04-20 17:40:29 +000075 if (!KorAP._overrideStyles) {
76 var sheet = KorAP.newStyleSheet();
77
78 // Add css rule for OR operations
79 sheet.insertRule(
80 '.vc .docGroup[data-operation=or] > .doc::before,' +
81 '.vc .docGroup[data-operation=or] > .docGroup::before ' +
82 '{ content: "' + loc.OR + '" }',
83 0
84 );
85
86 // Add css rule for AND operations
87 sheet.insertRule(
88 '.vc .docGroup[data-operation=and] > .doc::before,' +
89 '.vc .docGroup[data-operation=and] > .docGroup::before ' +
90 '{ content: "' + loc.AND + '" }',
91 1
92 );
93
Nils Diewald359a72c2015-04-20 17:40:29 +000094 KorAP._overrideStyles = true;
Nils Diewald1fcb2ad2015-04-20 19:19:18 +000095
96 // Create key menu
97 KorAP._vcKeyMenu = menuClass.create(keyList);
98 KorAP._vcKeyMenu.limit(5);
Nils Diewald359a72c2015-04-20 17:40:29 +000099 };
100
101 return this;
102 },
103
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000104 /**
105 * Create a new virtual collection.
106 */
107 create : function (keyList) {
108 return Object.create(this)._init(keyList);
Nils Diewald3a2d8022014-12-16 02:45:41 +0000109 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000110
Nils Diewald4019bd22015-01-08 19:57:50 +0000111 clean : function () {
112 if (this._root.ldType() !== "non") {
113 this._root.destroy();
Nils Diewald0e6992a2015-04-14 20:13:52 +0000114 this.root(unspecDocClass.create(this));
Nils Diewald4019bd22015-01-08 19:57:50 +0000115 };
116 return this;
117 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000118
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000119 /**
120 * Create and render a new virtual collection
121 * based on a KoralQuery collection document
122 */
123 render : function (json, keyList) {
124 var obj = Object.create(this)._init(keyList);
Nils Diewaldd0770492014-12-19 03:55:00 +0000125
126 if (json !== undefined) {
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000127 // Parse root document
Nils Diewald2fe12e12015-03-06 16:47:06 +0000128 if (json['@type'] == 'koral:doc') {
Nils Diewald0e6992a2015-04-14 20:13:52 +0000129 obj._root = docClass.create(obj, json);
Nils Diewaldd0770492014-12-19 03:55:00 +0000130 }
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000131 // parse root group
Nils Diewald2fe12e12015-03-06 16:47:06 +0000132 else if (json['@type'] == 'koral:docGroup') {
Nils Diewald0e6992a2015-04-14 20:13:52 +0000133 obj._root = docGroupClass.create(obj, json);
Nils Diewaldd0770492014-12-19 03:55:00 +0000134 }
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000135 // Unknown collection type
Nils Diewaldd0770492014-12-19 03:55:00 +0000136 else {
137 KorAP.log(813, "Collection type is not supported");
138 return;
139 };
140 }
141
142 else {
143 // Add unspecified object
Nils Diewald7c8ced22015-04-15 19:21:00 +0000144 obj._root = unspecDocClass.create(obj);
Nils Diewaldd0770492014-12-19 03:55:00 +0000145 };
146
Nils Diewald8e7182e2015-01-08 15:02:07 +0000147 // Init element and update
148 obj.update();
Nils Diewaldd0770492014-12-19 03:55:00 +0000149
150 return obj;
Nils Diewald3a2d8022014-12-16 02:45:41 +0000151 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000152
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000153 /**
154 * Get or set the root object of the
155 * virtual collection.
156 */
Nils Diewaldf219eb82015-01-07 20:15:42 +0000157 root : function (obj) {
Nils Diewald8e7182e2015-01-08 15:02:07 +0000158 if (arguments.length === 1) {
Nils Diewald8f6b6102015-01-08 18:25:33 +0000159 var e = this.element();
160 if (e.firstChild !== null) {
Nils Diewaldd5070b02015-01-11 01:44:47 +0000161 if (e.firstChild !== obj.element()) {
Nils Diewald8f6b6102015-01-08 18:25:33 +0000162 e.replaceChild(obj.element(), e.firstChild);
Nils Diewaldd5070b02015-01-11 01:44:47 +0000163 };
Nils Diewald8f6b6102015-01-08 18:25:33 +0000164 }
165
166 // Append root element
167 else {
168 e.appendChild(obj.element());
169 };
170
171 // Update parent child relations
Nils Diewaldf219eb82015-01-07 20:15:42 +0000172 this._root = obj;
Nils Diewald8f6b6102015-01-08 18:25:33 +0000173 obj.parent(this);
174
Nils Diewald8e7182e2015-01-08 15:02:07 +0000175 this.update();
176 };
Nils Diewaldd0770492014-12-19 03:55:00 +0000177 return this._root;
Nils Diewald3a2d8022014-12-16 02:45:41 +0000178 },
Nils Diewald8f6b6102015-01-08 18:25:33 +0000179
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000180 /**
181 * Get the element associated with the virtual collection
182 */
Nils Diewaldd0770492014-12-19 03:55:00 +0000183 element : function () {
184 if (this._element !== undefined)
185 return this._element;
186
187 this._element = document.createElement('div');
188 this._element.setAttribute('class', 'vc');
Nils Diewald8e7182e2015-01-08 15:02:07 +0000189
Nils Diewald8f6b6102015-01-08 18:25:33 +0000190 // Initialize root
191 this._element.appendChild(this._root.element());
192
Nils Diewaldd0770492014-12-19 03:55:00 +0000193 return this._element;
Nils Diewaldf219eb82015-01-07 20:15:42 +0000194 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000195
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000196
197 /**
198 * Update the whole object based on the underlying
199 * data structure
200 */
Nils Diewaldd599d542015-01-08 20:41:34 +0000201 update : function () {
202 this._root.update();
203 return this;
204 },
205
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000206
207 /**
208 * Get the generated json string
209 */
Nils Diewaldf219eb82015-01-07 20:15:42 +0000210 toJson : function () {
211 return this._root.toJson();
212 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000213
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000214
215 /**
216 * Get the generated query string
217 */
Nils Diewaldd599d542015-01-08 20:41:34 +0000218 toQuery : function () {
219 return this._root.toQuery();
Nils Diewald3a2d8022014-12-16 02:45:41 +0000220 }
221 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000222});