blob: 1aed3cf39e416f8732195f43f0f75dabf9bb94bf [file] [log] [blame]
Nils Diewald86dad5b2015-01-28 15:09:07 +00001/**
2 * Create virtual collections with a visual user interface.
Nils Diewald4c221252015-04-21 20:19:25 +00003 * This resembles the collection type objects of a KoralQuery
4 * "collection" object.
5 *
6 * KoralQuery v0.3 is expected.
Nils Diewald86dad5b2015-01-28 15:09:07 +00007 *
8 * @author Nils Diewald
9 */
Nils Diewald2fe12e12015-03-06 16:47:06 +000010/*
Nils Diewald1fcb2ad2015-04-20 19:19:18 +000011 * This replaces a previous version written by Mengfei Zhou
Nils Diewald2fe12e12015-03-06 16:47:06 +000012 */
Nils Diewald2fe12e12015-03-06 16:47:06 +000013
Nils Diewaldd0770492014-12-19 03:55:00 +000014/*
Nils Diewald86dad5b2015-01-28 15:09:07 +000015 TODO: Disable "and" or "or" in case it's followed
16 by an unspecified document
Nils Diewald1fcb2ad2015-04-20 19:19:18 +000017 TODO: Implement "persistence"-Option,
Nils Diewald6e43ffd2015-03-25 18:55:39 +000018 injecting the current creation date stamp
Nils Diewald86dad5b2015-01-28 15:09:07 +000019
Nils Diewaldd599d542015-01-08 20:41:34 +000020 Error codes:
Nils Diewaldd0770492014-12-19 03:55:00 +000021 701: "JSON-LD group has no @type attribute"
22 704: "Operation needs operand list"
Nils Diewald3a2d8022014-12-16 02:45:41 +000023 802: "Match type is not supported by value type"
24 804: "Unknown value type"
25 805: "Value is invalid"
26 806: "Value is not a valid date string"
27 807: "Value is not a valid regular expression"
Nils Diewald3a2d8022014-12-16 02:45:41 +000028 810: "Unknown document group operation" (like 711)
29 811: "Document group expects operation" (like 703)
30 812: "Operand not supported in document group" (like 744)
Nils Diewaldd0770492014-12-19 03:55:00 +000031 813: "Collection type is not supported" (like 713)
Nils Diewald86dad5b2015-01-28 15:09:07 +000032 814: "Unknown rewrite operation"
33 815: "Rewrite expects source"
Nils Diewald1fcb2ad2015-04-20 19:19:18 +000034
35 Localization strings:
36 KorAP.Locale = {
37 EMPTY : '...',
38 AND : 'and',
39 OR : 'or',
40 DELETE : 'x'
41 }
Nils Diewald4c221252015-04-21 20:19:25 +000042 and various field names with the prefix 'VC_'
Nils Diewaldd0770492014-12-19 03:55:00 +000043*/
44
Nils Diewald0e6992a2015-04-14 20:13:52 +000045define([
46 'vc/unspecified',
47 'vc/doc',
48 'vc/docgroup',
Nils Diewald1fcb2ad2015-04-20 19:19:18 +000049 'vc/menu',
Nils Diewald87507832015-05-01 23:36:41 +000050 'datepicker',
Nils Diewald0e6992a2015-04-14 20:13:52 +000051 'util'
Nils Diewald87507832015-05-01 23:36:41 +000052], function (unspecDocClass, docClass, docGroupClass, menuClass, dpClass) {
Nils Diewald3a2d8022014-12-16 02:45:41 +000053 "use strict";
54
Nils Diewald359a72c2015-04-20 17:40:29 +000055 // ???
Nils Diewald86dad5b2015-01-28 15:09:07 +000056 KorAP._validStringMatchRE = new RegExp("^(?:eq|ne|contains|excludes)$");
Nils Diewaldd0770492014-12-19 03:55:00 +000057 KorAP._validDateMatchRE = new RegExp("^[lg]?eq$");
Nils Diewald3a2d8022014-12-16 02:45:41 +000058 KorAP._validDateRE = new RegExp("^(?:\\d{4})(?:-\\d\\d(?:-\\d\\d)?)?$");
Nils Diewald359a72c2015-04-20 17:40:29 +000059 KorAP._overrideStyles = false;
Nils Diewald3a2d8022014-12-16 02:45:41 +000060
Nils Diewald359a72c2015-04-20 17:40:29 +000061 var loc = KorAP.Locale;
Nils Diewaldd599d542015-01-08 20:41:34 +000062
Nils Diewald1fcb2ad2015-04-20 19:19:18 +000063 KorAP._vcKeyMenu = undefined;
Nils Diewald87507832015-05-01 23:36:41 +000064 KorAP._vcDatePicker = dpClass.create();
Nils Diewald1fcb2ad2015-04-20 19:19:18 +000065
Nils Diewaldd599d542015-01-08 20:41:34 +000066 /**
67 * Virtual Collection
68 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000069 return {
Nils Diewald1fcb2ad2015-04-20 19:19:18 +000070
71 /**
72 * The JSON-LD type of the virtual collection
73 */
Nils Diewaldf219eb82015-01-07 20:15:42 +000074 ldType : function () {
75 return null;
76 },
Nils Diewaldd599d542015-01-08 20:41:34 +000077
Nils Diewald1fcb2ad2015-04-20 19:19:18 +000078 // Initialize virtual collection
79 _init : function (keyList) {
80
81 // Inject localized css styles
Nils Diewald359a72c2015-04-20 17:40:29 +000082 if (!KorAP._overrideStyles) {
83 var sheet = KorAP.newStyleSheet();
84
85 // Add css rule for OR operations
86 sheet.insertRule(
87 '.vc .docGroup[data-operation=or] > .doc::before,' +
88 '.vc .docGroup[data-operation=or] > .docGroup::before ' +
89 '{ content: "' + loc.OR + '" }',
90 0
91 );
92
93 // Add css rule for AND operations
94 sheet.insertRule(
95 '.vc .docGroup[data-operation=and] > .doc::before,' +
96 '.vc .docGroup[data-operation=and] > .docGroup::before ' +
97 '{ content: "' + loc.AND + '" }',
98 1
99 );
100
Nils Diewald359a72c2015-04-20 17:40:29 +0000101 KorAP._overrideStyles = true;
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000102
103 // Create key menu
104 KorAP._vcKeyMenu = menuClass.create(keyList);
Nils Diewald4c221252015-04-21 20:19:25 +0000105 KorAP._vcKeyMenu.limit(6);
106
107 // Create match menus ....
108 KorAP._vcMatchopMenu = {
109 'string' : menuClass.create([
110 ['eq', null],
111 ['ne', null],
112 ['contains', null],
113 ['excludes', null]
114 ]),
115 'date' : menuClass.create([
116 ['eq', null],
117 ['geq', null],
118 ['leq', null]
119 ]),
120 'regex' : menuClass.create([
121 ['eq', null],
122 ['ne', null],
123 ['contains', null],
124 ['excludes', null]
125 ])
126 };
Nils Diewald359a72c2015-04-20 17:40:29 +0000127 };
128
129 return this;
130 },
131
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000132 /**
133 * Create a new virtual collection.
134 */
135 create : function (keyList) {
Nils Diewald6283d692015-04-23 20:32:53 +0000136 var obj = Object.create(this)._init(keyList);
137 obj._root = unspecDocClass.create(obj);
138 return obj;
Nils Diewald4019bd22015-01-08 19:57:50 +0000139 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000140
Nils Diewald7148c6f2015-05-04 15:07:53 +0000141
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000142 /**
143 * Create and render a new virtual collection
144 * based on a KoralQuery collection document
145 */
Nils Diewald6283d692015-04-23 20:32:53 +0000146 fromJson : function (json) {
Nils Diewaldd0770492014-12-19 03:55:00 +0000147
148 if (json !== undefined) {
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000149 // Parse root document
Nils Diewald2fe12e12015-03-06 16:47:06 +0000150 if (json['@type'] == 'koral:doc') {
Nils Diewald6283d692015-04-23 20:32:53 +0000151 this._root = docClass.create(this, json);
Nils Diewaldd0770492014-12-19 03:55:00 +0000152 }
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000153 // parse root group
Nils Diewald2fe12e12015-03-06 16:47:06 +0000154 else if (json['@type'] == 'koral:docGroup') {
Nils Diewald6283d692015-04-23 20:32:53 +0000155 this._root = docGroupClass.create(this, json);
Nils Diewaldd0770492014-12-19 03:55:00 +0000156 }
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000157 // Unknown collection type
Nils Diewaldd0770492014-12-19 03:55:00 +0000158 else {
159 KorAP.log(813, "Collection type is not supported");
160 return;
161 };
162 }
163
164 else {
165 // Add unspecified object
Nils Diewald6283d692015-04-23 20:32:53 +0000166 this._root = unspecDocClass.create(this);
Nils Diewaldd0770492014-12-19 03:55:00 +0000167 };
168
Nils Diewald8e7182e2015-01-08 15:02:07 +0000169 // Init element and update
Nils Diewald6283d692015-04-23 20:32:53 +0000170 this.update();
Nils Diewaldd0770492014-12-19 03:55:00 +0000171
Nils Diewald6283d692015-04-23 20:32:53 +0000172 return this;
173 },
174
Nils Diewald7148c6f2015-05-04 15:07:53 +0000175
176 /**
177 * Clean the virtual document to uspecified doc.
178 */
Nils Diewald6283d692015-04-23 20:32:53 +0000179 clean : function () {
180 if (this._root.ldType() !== "non") {
181 this._root.destroy();
182 this.root(unspecDocClass.create(this));
183 };
184 return this;
Nils Diewald3a2d8022014-12-16 02:45:41 +0000185 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000186
Nils Diewald7148c6f2015-05-04 15:07:53 +0000187
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000188 /**
189 * Get or set the root object of the
190 * virtual collection.
191 */
Nils Diewaldf219eb82015-01-07 20:15:42 +0000192 root : function (obj) {
Nils Diewald8e7182e2015-01-08 15:02:07 +0000193 if (arguments.length === 1) {
Nils Diewald8f6b6102015-01-08 18:25:33 +0000194 var e = this.element();
195 if (e.firstChild !== null) {
Nils Diewaldd5070b02015-01-11 01:44:47 +0000196 if (e.firstChild !== obj.element()) {
Nils Diewald8f6b6102015-01-08 18:25:33 +0000197 e.replaceChild(obj.element(), e.firstChild);
Nils Diewaldd5070b02015-01-11 01:44:47 +0000198 };
Nils Diewald8f6b6102015-01-08 18:25:33 +0000199 }
200
201 // Append root element
202 else {
203 e.appendChild(obj.element());
204 };
205
206 // Update parent child relations
Nils Diewaldf219eb82015-01-07 20:15:42 +0000207 this._root = obj;
Nils Diewald8f6b6102015-01-08 18:25:33 +0000208 obj.parent(this);
209
Nils Diewald8e7182e2015-01-08 15:02:07 +0000210 this.update();
211 };
Nils Diewaldd0770492014-12-19 03:55:00 +0000212 return this._root;
Nils Diewald3a2d8022014-12-16 02:45:41 +0000213 },
Nils Diewald8f6b6102015-01-08 18:25:33 +0000214
Nils Diewald7148c6f2015-05-04 15:07:53 +0000215
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000216 /**
217 * Get the element associated with the virtual collection
218 */
Nils Diewaldd0770492014-12-19 03:55:00 +0000219 element : function () {
220 if (this._element !== undefined)
221 return this._element;
222
223 this._element = document.createElement('div');
224 this._element.setAttribute('class', 'vc');
Nils Diewald8e7182e2015-01-08 15:02:07 +0000225
Nils Diewald8f6b6102015-01-08 18:25:33 +0000226 // Initialize root
227 this._element.appendChild(this._root.element());
228
Nils Diewaldd0770492014-12-19 03:55:00 +0000229 return this._element;
Nils Diewaldf219eb82015-01-07 20:15:42 +0000230 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000231
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000232
233 /**
234 * Update the whole object based on the underlying
235 * data structure
236 */
Nils Diewaldd599d542015-01-08 20:41:34 +0000237 update : function () {
238 this._root.update();
239 return this;
240 },
241
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000242
243 /**
244 * Get the generated json string
245 */
Nils Diewaldf219eb82015-01-07 20:15:42 +0000246 toJson : function () {
247 return this._root.toJson();
248 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000249
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000250
251 /**
252 * Get the generated query string
253 */
Nils Diewaldd599d542015-01-08 20:41:34 +0000254 toQuery : function () {
255 return this._root.toQuery();
Nils Diewald3a2d8022014-12-16 02:45:41 +0000256 }
257 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000258});