blob: 1bb3b15d099fc8a977f9ff8fd1fa9a9b50175aaa [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 Diewald1fcb2ad2015-04-20 19:19:18 +0000141 /**
142 * Create and render a new virtual collection
143 * based on a KoralQuery collection document
144 */
Nils Diewald6283d692015-04-23 20:32:53 +0000145 fromJson : function (json) {
Nils Diewaldd0770492014-12-19 03:55:00 +0000146
147 if (json !== undefined) {
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000148 // Parse root document
Nils Diewald2fe12e12015-03-06 16:47:06 +0000149 if (json['@type'] == 'koral:doc') {
Nils Diewald6283d692015-04-23 20:32:53 +0000150 this._root = docClass.create(this, json);
Nils Diewaldd0770492014-12-19 03:55:00 +0000151 }
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000152 // parse root group
Nils Diewald2fe12e12015-03-06 16:47:06 +0000153 else if (json['@type'] == 'koral:docGroup') {
Nils Diewald6283d692015-04-23 20:32:53 +0000154 this._root = docGroupClass.create(this, json);
Nils Diewaldd0770492014-12-19 03:55:00 +0000155 }
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000156 // Unknown collection type
Nils Diewaldd0770492014-12-19 03:55:00 +0000157 else {
158 KorAP.log(813, "Collection type is not supported");
159 return;
160 };
161 }
162
163 else {
164 // Add unspecified object
Nils Diewald6283d692015-04-23 20:32:53 +0000165 this._root = unspecDocClass.create(this);
Nils Diewaldd0770492014-12-19 03:55:00 +0000166 };
167
Nils Diewald8e7182e2015-01-08 15:02:07 +0000168 // Init element and update
Nils Diewald6283d692015-04-23 20:32:53 +0000169 this.update();
Nils Diewaldd0770492014-12-19 03:55:00 +0000170
Nils Diewald6283d692015-04-23 20:32:53 +0000171 return this;
172 },
173
174 clean : function () {
175 if (this._root.ldType() !== "non") {
176 this._root.destroy();
177 this.root(unspecDocClass.create(this));
178 };
179 return this;
Nils Diewald3a2d8022014-12-16 02:45:41 +0000180 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000181
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000182 /**
183 * Get or set the root object of the
184 * virtual collection.
185 */
Nils Diewaldf219eb82015-01-07 20:15:42 +0000186 root : function (obj) {
Nils Diewald8e7182e2015-01-08 15:02:07 +0000187 if (arguments.length === 1) {
Nils Diewald8f6b6102015-01-08 18:25:33 +0000188 var e = this.element();
189 if (e.firstChild !== null) {
Nils Diewaldd5070b02015-01-11 01:44:47 +0000190 if (e.firstChild !== obj.element()) {
Nils Diewald8f6b6102015-01-08 18:25:33 +0000191 e.replaceChild(obj.element(), e.firstChild);
Nils Diewaldd5070b02015-01-11 01:44:47 +0000192 };
Nils Diewald8f6b6102015-01-08 18:25:33 +0000193 }
194
195 // Append root element
196 else {
197 e.appendChild(obj.element());
198 };
199
200 // Update parent child relations
Nils Diewaldf219eb82015-01-07 20:15:42 +0000201 this._root = obj;
Nils Diewald8f6b6102015-01-08 18:25:33 +0000202 obj.parent(this);
203
Nils Diewald8e7182e2015-01-08 15:02:07 +0000204 this.update();
205 };
Nils Diewaldd0770492014-12-19 03:55:00 +0000206 return this._root;
Nils Diewald3a2d8022014-12-16 02:45:41 +0000207 },
Nils Diewald8f6b6102015-01-08 18:25:33 +0000208
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000209 /**
210 * Get the element associated with the virtual collection
211 */
Nils Diewaldd0770492014-12-19 03:55:00 +0000212 element : function () {
213 if (this._element !== undefined)
214 return this._element;
215
216 this._element = document.createElement('div');
217 this._element.setAttribute('class', 'vc');
Nils Diewald8e7182e2015-01-08 15:02:07 +0000218
Nils Diewald8f6b6102015-01-08 18:25:33 +0000219 // Initialize root
220 this._element.appendChild(this._root.element());
221
Nils Diewaldd0770492014-12-19 03:55:00 +0000222 return this._element;
Nils Diewaldf219eb82015-01-07 20:15:42 +0000223 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000224
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000225
226 /**
227 * Update the whole object based on the underlying
228 * data structure
229 */
Nils Diewaldd599d542015-01-08 20:41:34 +0000230 update : function () {
231 this._root.update();
232 return this;
233 },
234
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000235
236 /**
237 * Get the generated json string
238 */
Nils Diewaldf219eb82015-01-07 20:15:42 +0000239 toJson : function () {
240 return this._root.toJson();
241 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000242
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000243
244 /**
245 * Get the generated query string
246 */
Nils Diewaldd599d542015-01-08 20:41:34 +0000247 toQuery : function () {
248 return this._root.toQuery();
Nils Diewald3a2d8022014-12-16 02:45:41 +0000249 }
250 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000251});