blob: 80f6627bb593e05d25936fe33a331e1c3767aa2c [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) {
134 return Object.create(this)._init(keyList);
Nils Diewald3a2d8022014-12-16 02:45:41 +0000135 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000136
Nils Diewald4019bd22015-01-08 19:57:50 +0000137 clean : function () {
138 if (this._root.ldType() !== "non") {
139 this._root.destroy();
Nils Diewald0e6992a2015-04-14 20:13:52 +0000140 this.root(unspecDocClass.create(this));
Nils Diewald4019bd22015-01-08 19:57:50 +0000141 };
142 return this;
143 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000144
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000145 /**
146 * Create and render a new virtual collection
147 * based on a KoralQuery collection document
148 */
149 render : function (json, keyList) {
150 var obj = Object.create(this)._init(keyList);
Nils Diewaldd0770492014-12-19 03:55:00 +0000151
152 if (json !== undefined) {
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000153 // Parse root document
Nils Diewald2fe12e12015-03-06 16:47:06 +0000154 if (json['@type'] == 'koral:doc') {
Nils Diewald0e6992a2015-04-14 20:13:52 +0000155 obj._root = docClass.create(obj, json);
Nils Diewaldd0770492014-12-19 03:55:00 +0000156 }
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000157 // parse root group
Nils Diewald2fe12e12015-03-06 16:47:06 +0000158 else if (json['@type'] == 'koral:docGroup') {
Nils Diewald0e6992a2015-04-14 20:13:52 +0000159 obj._root = docGroupClass.create(obj, json);
Nils Diewaldd0770492014-12-19 03:55:00 +0000160 }
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000161 // Unknown collection type
Nils Diewaldd0770492014-12-19 03:55:00 +0000162 else {
163 KorAP.log(813, "Collection type is not supported");
164 return;
165 };
166 }
167
168 else {
169 // Add unspecified object
Nils Diewald7c8ced22015-04-15 19:21:00 +0000170 obj._root = unspecDocClass.create(obj);
Nils Diewaldd0770492014-12-19 03:55:00 +0000171 };
172
Nils Diewald8e7182e2015-01-08 15:02:07 +0000173 // Init element and update
174 obj.update();
Nils Diewaldd0770492014-12-19 03:55:00 +0000175
176 return obj;
Nils Diewald3a2d8022014-12-16 02:45:41 +0000177 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000178
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000179 /**
180 * Get or set the root object of the
181 * virtual collection.
182 */
Nils Diewaldf219eb82015-01-07 20:15:42 +0000183 root : function (obj) {
Nils Diewald8e7182e2015-01-08 15:02:07 +0000184 if (arguments.length === 1) {
Nils Diewald8f6b6102015-01-08 18:25:33 +0000185 var e = this.element();
186 if (e.firstChild !== null) {
Nils Diewaldd5070b02015-01-11 01:44:47 +0000187 if (e.firstChild !== obj.element()) {
Nils Diewald8f6b6102015-01-08 18:25:33 +0000188 e.replaceChild(obj.element(), e.firstChild);
Nils Diewaldd5070b02015-01-11 01:44:47 +0000189 };
Nils Diewald8f6b6102015-01-08 18:25:33 +0000190 }
191
192 // Append root element
193 else {
194 e.appendChild(obj.element());
195 };
196
197 // Update parent child relations
Nils Diewaldf219eb82015-01-07 20:15:42 +0000198 this._root = obj;
Nils Diewald8f6b6102015-01-08 18:25:33 +0000199 obj.parent(this);
200
Nils Diewald8e7182e2015-01-08 15:02:07 +0000201 this.update();
202 };
Nils Diewaldd0770492014-12-19 03:55:00 +0000203 return this._root;
Nils Diewald3a2d8022014-12-16 02:45:41 +0000204 },
Nils Diewald8f6b6102015-01-08 18:25:33 +0000205
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000206 /**
207 * Get the element associated with the virtual collection
208 */
Nils Diewaldd0770492014-12-19 03:55:00 +0000209 element : function () {
210 if (this._element !== undefined)
211 return this._element;
212
213 this._element = document.createElement('div');
214 this._element.setAttribute('class', 'vc');
Nils Diewald8e7182e2015-01-08 15:02:07 +0000215
Nils Diewald8f6b6102015-01-08 18:25:33 +0000216 // Initialize root
217 this._element.appendChild(this._root.element());
218
Nils Diewaldd0770492014-12-19 03:55:00 +0000219 return this._element;
Nils Diewaldf219eb82015-01-07 20:15:42 +0000220 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000221
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000222
223 /**
224 * Update the whole object based on the underlying
225 * data structure
226 */
Nils Diewaldd599d542015-01-08 20:41:34 +0000227 update : function () {
228 this._root.update();
229 return this;
230 },
231
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000232
233 /**
234 * Get the generated json string
235 */
Nils Diewaldf219eb82015-01-07 20:15:42 +0000236 toJson : function () {
237 return this._root.toJson();
238 },
Nils Diewaldd599d542015-01-08 20:41:34 +0000239
Nils Diewald1fcb2ad2015-04-20 19:19:18 +0000240
241 /**
242 * Get the generated query string
243 */
Nils Diewaldd599d542015-01-08 20:41:34 +0000244 toQuery : function () {
245 return this._root.toQuery();
Nils Diewald3a2d8022014-12-16 02:45:41 +0000246 }
247 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000248});