blob: c816883a41597ec71b3821baef191c4ce4593d9e [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 Diewald0e6992a2015-04-14 20:13:52 +000050 'util'
Nils Diewald1fcb2ad2015-04-20 19:19:18 +000051], function (unspecDocClass, docClass, docGroupClass, menuClass) {
Nils Diewald3a2d8022014-12-16 02:45:41 +000052 "use strict";
53
Nils Diewald359a72c2015-04-20 17:40:29 +000054 // ???
Nils Diewald86dad5b2015-01-28 15:09:07 +000055 KorAP._validStringMatchRE = new RegExp("^(?:eq|ne|contains|excludes)$");
Nils Diewaldd0770492014-12-19 03:55:00 +000056 KorAP._validDateMatchRE = new RegExp("^[lg]?eq$");
Nils Diewald3a2d8022014-12-16 02:45:41 +000057 KorAP._validDateRE = new RegExp("^(?:\\d{4})(?:-\\d\\d(?:-\\d\\d)?)?$");
Nils Diewald359a72c2015-04-20 17:40:29 +000058 KorAP._overrideStyles = false;
Nils Diewald3a2d8022014-12-16 02:45:41 +000059
Nils Diewald359a72c2015-04-20 17:40:29 +000060 var loc = KorAP.Locale;
Nils Diewaldd599d542015-01-08 20:41:34 +000061
Nils Diewald1fcb2ad2015-04-20 19:19:18 +000062 KorAP._vcKeyMenu = undefined;
63
Nils Diewaldd599d542015-01-08 20:41:34 +000064 /**
65 * Virtual Collection
66 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000067 return {
Nils Diewald1fcb2ad2015-04-20 19:19:18 +000068
69 /**
70 * The JSON-LD type of the virtual collection
71 */
Nils Diewaldf219eb82015-01-07 20:15:42 +000072 ldType : function () {
73 return null;
74 },
Nils Diewaldd599d542015-01-08 20:41:34 +000075
Nils Diewald1fcb2ad2015-04-20 19:19:18 +000076 // Initialize virtual collection
77 _init : function (keyList) {
78
79 // Inject localized css styles
Nils Diewald359a72c2015-04-20 17:40:29 +000080 if (!KorAP._overrideStyles) {
81 var sheet = KorAP.newStyleSheet();
82
83 // Add css rule for OR operations
84 sheet.insertRule(
85 '.vc .docGroup[data-operation=or] > .doc::before,' +
86 '.vc .docGroup[data-operation=or] > .docGroup::before ' +
87 '{ content: "' + loc.OR + '" }',
88 0
89 );
90
91 // Add css rule for AND operations
92 sheet.insertRule(
93 '.vc .docGroup[data-operation=and] > .doc::before,' +
94 '.vc .docGroup[data-operation=and] > .docGroup::before ' +
95 '{ content: "' + loc.AND + '" }',
96 1
97 );
98
Nils Diewald359a72c2015-04-20 17:40:29 +000099 KorAP._overrideStyles = true;
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000100
101 // Create key menu
102 KorAP._vcKeyMenu = menuClass.create(keyList);
Nils Diewald4c221252015-04-21 20:19:25 +0000103 KorAP._vcKeyMenu.limit(6);
104
105 // Create match menus ....
106 KorAP._vcMatchopMenu = {
107 'string' : menuClass.create([
108 ['eq', null],
109 ['ne', null],
110 ['contains', null],
111 ['excludes', null]
112 ]),
113 'date' : menuClass.create([
114 ['eq', null],
115 ['geq', null],
116 ['leq', null]
117 ]),
118 'regex' : menuClass.create([
119 ['eq', null],
120 ['ne', null],
121 ['contains', null],
122 ['excludes', null]
123 ])
124 };
Nils Diewald359a72c2015-04-20 17:40:29 +0000125 };
126
127 return this;
128 },
129
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000130 /**
131 * Create a new virtual collection.
132 */
133 create : function (keyList) {
Nils Diewald6283d692015-04-23 20:32:53 +0000134 var obj = Object.create(this)._init(keyList);
135 obj._root = unspecDocClass.create(obj);
136 return obj;
Nils Diewald4019bd22015-01-08 19:57:50 +0000137 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000138
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000139 /**
140 * Create and render a new virtual collection
141 * based on a KoralQuery collection document
142 */
Nils Diewald6283d692015-04-23 20:32:53 +0000143 fromJson : function (json) {
Nils Diewaldd0770492014-12-19 03:55:00 +0000144
145 if (json !== undefined) {
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000146 // Parse root document
Nils Diewald2fe12e12015-03-06 16:47:06 +0000147 if (json['@type'] == 'koral:doc') {
Nils Diewald6283d692015-04-23 20:32:53 +0000148 this._root = docClass.create(this, json);
Nils Diewaldd0770492014-12-19 03:55:00 +0000149 }
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000150 // parse root group
Nils Diewald2fe12e12015-03-06 16:47:06 +0000151 else if (json['@type'] == 'koral:docGroup') {
Nils Diewald6283d692015-04-23 20:32:53 +0000152 this._root = docGroupClass.create(this, json);
Nils Diewaldd0770492014-12-19 03:55:00 +0000153 }
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000154 // Unknown collection type
Nils Diewaldd0770492014-12-19 03:55:00 +0000155 else {
156 KorAP.log(813, "Collection type is not supported");
157 return;
158 };
159 }
160
161 else {
162 // Add unspecified object
Nils Diewald6283d692015-04-23 20:32:53 +0000163 this._root = unspecDocClass.create(this);
Nils Diewaldd0770492014-12-19 03:55:00 +0000164 };
165
Nils Diewald8e7182e2015-01-08 15:02:07 +0000166 // Init element and update
Nils Diewald6283d692015-04-23 20:32:53 +0000167 this.update();
Nils Diewaldd0770492014-12-19 03:55:00 +0000168
Nils Diewald6283d692015-04-23 20:32:53 +0000169 return this;
170 },
171
172 clean : function () {
173 if (this._root.ldType() !== "non") {
174 this._root.destroy();
175 this.root(unspecDocClass.create(this));
176 };
177 return this;
Nils Diewald3a2d8022014-12-16 02:45:41 +0000178 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000179
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000180 /**
181 * Get or set the root object of the
182 * virtual collection.
183 */
Nils Diewaldf219eb82015-01-07 20:15:42 +0000184 root : function (obj) {
Nils Diewald8e7182e2015-01-08 15:02:07 +0000185 if (arguments.length === 1) {
Nils Diewald8f6b6102015-01-08 18:25:33 +0000186 var e = this.element();
187 if (e.firstChild !== null) {
Nils Diewaldd5070b02015-01-11 01:44:47 +0000188 if (e.firstChild !== obj.element()) {
Nils Diewald8f6b6102015-01-08 18:25:33 +0000189 e.replaceChild(obj.element(), e.firstChild);
Nils Diewaldd5070b02015-01-11 01:44:47 +0000190 };
Nils Diewald8f6b6102015-01-08 18:25:33 +0000191 }
192
193 // Append root element
194 else {
195 e.appendChild(obj.element());
196 };
197
198 // Update parent child relations
Nils Diewaldf219eb82015-01-07 20:15:42 +0000199 this._root = obj;
Nils Diewald8f6b6102015-01-08 18:25:33 +0000200 obj.parent(this);
201
Nils Diewald8e7182e2015-01-08 15:02:07 +0000202 this.update();
203 };
Nils Diewaldd0770492014-12-19 03:55:00 +0000204 return this._root;
Nils Diewald3a2d8022014-12-16 02:45:41 +0000205 },
Nils Diewald8f6b6102015-01-08 18:25:33 +0000206
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000207 /**
208 * Get the element associated with the virtual collection
209 */
Nils Diewaldd0770492014-12-19 03:55:00 +0000210 element : function () {
211 if (this._element !== undefined)
212 return this._element;
213
214 this._element = document.createElement('div');
215 this._element.setAttribute('class', 'vc');
Nils Diewald8e7182e2015-01-08 15:02:07 +0000216
Nils Diewald8f6b6102015-01-08 18:25:33 +0000217 // Initialize root
218 this._element.appendChild(this._root.element());
219
Nils Diewaldd0770492014-12-19 03:55:00 +0000220 return this._element;
Nils Diewaldf219eb82015-01-07 20:15:42 +0000221 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000222
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000223
224 /**
225 * Update the whole object based on the underlying
226 * data structure
227 */
Nils Diewaldd599d542015-01-08 20:41:34 +0000228 update : function () {
229 this._root.update();
230 return this;
231 },
232
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000233
234 /**
235 * Get the generated json string
236 */
Nils Diewaldf219eb82015-01-07 20:15:42 +0000237 toJson : function () {
238 return this._root.toJson();
239 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000240
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000241
242 /**
243 * Get the generated query string
244 */
Nils Diewaldd599d542015-01-08 20:41:34 +0000245 toQuery : function () {
246 return this._root.toQuery();
Nils Diewald3a2d8022014-12-16 02:45:41 +0000247 }
248 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000249});