blob: ed8facc34a7c28160996ed419f3bb1a91ab136c1 [file] [log] [blame]
Akron99713ef2017-06-28 18:19:28 +02001/**
2 * Information about a match.
3 */
Nils Diewald7c8ced22015-04-15 19:21:00 +00004define([
5 'match/infolayer',
6 'match/table',
Akron41387d22018-02-02 18:10:06 +01007 'match/treehierarchy',
8 'match/treearc',
Akron151bc872018-02-02 14:04:15 +01009 'match/meta',
Nils Diewald7c8ced22015-04-15 19:21:00 +000010 'util'
11], function (infoLayerClass,
Akron3bb91bc2016-12-02 16:43:17 +010012 matchTableClass,
Akron41387d22018-02-02 18:10:06 +010013 matchTreeHierarchyClass,
14 matchTreeArcClass,
Akronb6685bb2018-02-04 00:44:47 +010015 matchMetaClass) {
Akron3bb91bc2016-12-02 16:43:17 +010016
Nils Diewald7148c6f2015-05-04 15:07:53 +000017 // Override
Nils Diewald0e6992a2015-04-14 20:13:52 +000018 KorAP.API.getMatchInfo = KorAP.API.getMatchInfo || function () {
19 KorAP.log(0, 'KorAP.API.getMatchInfo() not implemented')
20 return {};
21 };
22
Akron0b489ad2018-02-02 16:49:32 +010023 const loc = KorAP.Locale;
24 const d = document;
Nils Diewald0e6992a2015-04-14 20:13:52 +000025
Nils Diewald0e6992a2015-04-14 20:13:52 +000026 return {
Nils Diewald7148c6f2015-05-04 15:07:53 +000027
28 /**
29 * Create new match object
30 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000031 create : function (match) {
32 return Object.create(this)._init(match);
33 },
34
Akron151bc872018-02-02 14:04:15 +010035
Nils Diewald0e6992a2015-04-14 20:13:52 +000036 /**
37 * Initialize object
38 */
39 _init : function (match) {
40 this._match = match;
Akronedbf33a2018-02-05 19:18:03 +010041 this._visibleTable = false;
42 this._visibleMeta = false;
Nils Diewald0e6992a2015-04-14 20:13:52 +000043 this.opened = false;
44 return this;
45 },
46
Akron151bc872018-02-02 14:04:15 +010047
Nils Diewald0e6992a2015-04-14 20:13:52 +000048 /**
49 * Get match object
50 */
51 match : function () {
52 return this._match;
53 },
54
Nils Diewald7148c6f2015-05-04 15:07:53 +000055
56 /**
57 * Open the information view,
58 * if closed, otherwise close.
59 */
Akronbd342982018-01-25 18:01:46 +010060 /*
Nils Diewald0e6992a2015-04-14 20:13:52 +000061 toggle : function () {
Akron3bb91bc2016-12-02 16:43:17 +010062
Akron08b82d62016-12-05 15:06:05 +010063 var elem = this._match.element();
Akron3bb91bc2016-12-02 16:43:17 +010064
65 if (this.opened == true) {
Akrond67d45b2017-05-18 21:47:38 +020066 elem.removeChild(
67 this.element()
68 );
69 this.opened = false;
Nils Diewald0e6992a2015-04-14 20:13:52 +000070 }
71 else {
Akrond67d45b2017-05-18 21:47:38 +020072 // Append element to match
Akron3bb91bc2016-12-02 16:43:17 +010073 elem.appendChild(
Akrond67d45b2017-05-18 21:47:38 +020074 this.element()
75 );
76 this.opened = true;
Nils Diewald0e6992a2015-04-14 20:13:52 +000077 };
78
79 return this.opened;
80 },
Akronbd342982018-01-25 18:01:46 +010081 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000082
83
84 /**
Nils Diewald7148c6f2015-05-04 15:07:53 +000085 * Retrieve and parse snippet for table
86 * representation
Nils Diewald0e6992a2015-04-14 20:13:52 +000087 */
Akron151bc872018-02-02 14:04:15 +010088 getTableData : function (tokens, cb) {
Nils Diewald0e6992a2015-04-14 20:13:52 +000089 var focus = [];
90
91 // Get all tokens
92 if (tokens === undefined) {
Akrond67d45b2017-05-18 21:47:38 +020093 focus = this._match.getTokens();
Nils Diewald0e6992a2015-04-14 20:13:52 +000094 }
95
96 // Get only some tokens
97 else {
Akrond67d45b2017-05-18 21:47:38 +020098
99 // Push newly to focus array
100 for (var i = 0; i < tokens.length; i++) {
101 var term = tokens[i];
102 try {
103 // Create info layer objects
104 var layer = infoLayerClass.create(term);
105 layer.type = "tokens";
106 focus.push(layer);
107 }
108 catch (e) {
109 continue;
110 };
111 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000112 };
113
114 // No tokens chosen
115 if (focus.length == 0)
Akrond67d45b2017-05-18 21:47:38 +0200116 cb(null);
Nils Diewald0e6992a2015-04-14 20:13:52 +0000117
Akron4f791442018-02-12 13:25:47 +0100118 try {
119 // Get info (may be cached)
120 KorAP.API.getMatchInfo(
121 this._match,
122 { 'spans' : false, 'layer' : focus },
Akrond67d45b2017-05-18 21:47:38 +0200123
Akron4f791442018-02-12 13:25:47 +0100124 // Callback for retrieval
125 function (matchResponse) {
Akron3bb91bc2016-12-02 16:43:17 +0100126
Akron4f791442018-02-12 13:25:47 +0100127 if (matchResponse === undefined)
128 cb(null);
Akron515851a2017-05-02 12:53:17 +0200129
Akron4f791442018-02-12 13:25:47 +0100130 // Get snippet from match info
131 if (matchResponse["snippet"] !== undefined) {
132 this._table = matchTableClass.create(matchResponse["snippet"]);
133 cb(this._table);
134 };
135 }.bind(this)
136 );
137 }
138 catch (e) {
139 KorAP.log(0, e);
140 cb(null);
141 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000142
143 /*
144 // Todo: Store the table as a hash of the focus
145 return null;
146 */
147 },
Akronbd342982018-01-25 18:01:46 +0100148
149
Akron4f791442018-02-12 13:25:47 +0100150 /**
151 * Receive meta data from server.
152 */
Akron0ad7cd22018-02-08 18:03:06 +0100153 getMetaData : function (cb) {
Akron4f791442018-02-12 13:25:47 +0100154 try {
155 KorAP.API.getTextInfo(
156 this._match, {}, function (textResponse) {
Akron0ad7cd22018-02-08 18:03:06 +0100157
Akron4f791442018-02-12 13:25:47 +0100158 if (textResponse === undefined) {
159 cb(null);
160 return;
161 };
Akron0ad7cd22018-02-08 18:03:06 +0100162
Akron4f791442018-02-12 13:25:47 +0100163 var doc = textResponse["document"];
Akron0ad7cd22018-02-08 18:03:06 +0100164
Akron4f791442018-02-12 13:25:47 +0100165 if (doc === undefined) {
166 cb(null);
167 return;
168 };
Akron0ad7cd22018-02-08 18:03:06 +0100169
Akron4f791442018-02-12 13:25:47 +0100170 var fields = doc["fields"];
171 if (fields === undefined) {
172 cb(null);
173 return;
174 };
Akron0ad7cd22018-02-08 18:03:06 +0100175
Akron4f791442018-02-12 13:25:47 +0100176 // Add metainfo to matchview
177 cb(matchMetaClass.create(
178 this._match, fields
179 ));
180 }
181 );
182 }
183 catch (e) {
184 KorAP.log(0, e);
185 cb(null);
186 };
Akronbd342982018-01-25 18:01:46 +0100187 },
Nils Diewald0e6992a2015-04-14 20:13:52 +0000188
189
190 /**
191 * Retrieve and parse snippet for tree representation
192 */
Akron151bc872018-02-02 14:04:15 +0100193 getTreeData : function (foundry, layer, type, cb) {
Nils Diewald0e6992a2015-04-14 20:13:52 +0000194 var focus = [];
Akron0ad7cd22018-02-08 18:03:06 +0100195
Akron4f791442018-02-12 13:25:47 +0100196 try {
197 // TODO: Support and cache multiple trees
198 KorAP.API.getMatchInfo(
199 this._match, {
200 'spans' : true,
201 'foundry' : foundry,
202 'layer' : layer
203 },
204 function (matchResponse) {
205 if (matchResponse === undefined) {
206 cb(null);
207 return;
208 };
Akronc56cf2d2016-11-09 22:02:38 +0100209
Akron4f791442018-02-12 13:25:47 +0100210 // Get snippet from match info
211 if (matchResponse["snippet"] !== undefined) {
212 // Todo: This should be cached somehow
213
214 if (type === "spans") {
215 cb(matchTreeHierarchyClass.create(matchResponse["snippet"]));
216 }
217 else if (type === "rels") {
218 cb(matchTreeArcClass.create(matchResponse["snippet"]));
219 }
220
221 // Unknown tree type
222 else {
223 cb(null);
224 };
Akron0988d882017-11-10 16:13:12 +0100225 }
Akron0988d882017-11-10 16:13:12 +0100226 else {
227 cb(null);
228 };
Akron4f791442018-02-12 13:25:47 +0100229 }.bind(this)
230 );
231 }
232 catch (e) {
233 KorAP.log(0, e);
234 cb(null);
235 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000236 },
237
Akron151bc872018-02-02 14:04:15 +0100238
Nils Diewald0e6992a2015-04-14 20:13:52 +0000239 /**
240 * Destroy this match information view.
241 */
242 destroy : function () {
243
244 // Remove circular reference
Akron8b592d42018-01-26 18:33:06 +0100245 /*
Nils Diewald0e6992a2015-04-14 20:13:52 +0000246 if (this._treeMenu !== undefined)
Akron99713ef2017-06-28 18:19:28 +0200247 delete this._treeMenu["info"];
Nils Diewald0e6992a2015-04-14 20:13:52 +0000248
249 this._treeMenu.destroy();
250 this._treeMenu = undefined;
Akron8b592d42018-01-26 18:33:06 +0100251 */
Nils Diewald0e6992a2015-04-14 20:13:52 +0000252 this._match = undefined;
Akron99713ef2017-06-28 18:19:28 +0200253 this._matchCreator = undefined;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000254 // Element destroy
255 },
256
Akron151bc872018-02-02 14:04:15 +0100257
Nils Diewald0e6992a2015-04-14 20:13:52 +0000258 /**
259 * Add a new tree view to the list
260 */
Akron151bc872018-02-02 14:04:15 +0100261 showTree : function (foundry, layer, type, cb) {
Akron0b489ad2018-02-02 16:49:32 +0100262 var matchtree = d.createElement('div');
Akronc8eb4a12018-02-03 00:39:58 +0100263 matchtree.classList.add('matchtree', 'loading');
264
265 this.element().appendChild(matchtree);
Akrond67d45b2017-05-18 21:47:38 +0200266
Akron151bc872018-02-02 14:04:15 +0100267 // Add title line
268 var h6 = matchtree.addE('h6');
269 h6.addE('span').addT(foundry);
270 h6.addE('span').addT(layer);
271
272 var tree = matchtree.addE('div');
Nils Diewald0e6992a2015-04-14 20:13:52 +0000273
Akron151bc872018-02-02 14:04:15 +0100274 // Add close action button
Akronc8eb4a12018-02-03 00:39:58 +0100275 var actions = this._addButton('close', matchtree, function (e) {
276 this.parentNode.removeChild(this);
277 e.halt();
278 });
Nils Diewald0e6992a2015-04-14 20:13:52 +0000279
Akronc8eb4a12018-02-03 00:39:58 +0100280 // tree.classList.add('loading'); // alternatively
Nils Diewald0ec142f2015-05-05 00:29:23 +0000281
Nils Diewald0e6992a2015-04-14 20:13:52 +0000282 // Get tree data async
Akron151bc872018-02-02 14:04:15 +0100283 this.getTreeData(foundry, layer, type, function (treeObj) {
Akronc8eb4a12018-02-03 00:39:58 +0100284 matchtree.classList.remove('loading');
Nils Diewald0ec142f2015-05-05 00:29:23 +0000285
Akrond67d45b2017-05-18 21:47:38 +0200286 // Something went wrong - probably log!!!
Nils Diewald0ec142f2015-05-05 00:29:23 +0000287
Akrond67d45b2017-05-18 21:47:38 +0200288 if (treeObj === null) {
Akron151bc872018-02-02 14:04:15 +0100289 tree.addT('No data available.');
Akrond67d45b2017-05-18 21:47:38 +0200290 }
291 else {
292 tree.appendChild(treeObj.element());
Akron0988d882017-11-10 16:13:12 +0100293 treeObj.show();
Akron151bc872018-02-02 14:04:15 +0100294
Akrond67d45b2017-05-18 21:47:38 +0200295 // Reposition the view to the center
296 // (This may in a future release be a reposition
Akron151bc872018-02-02 14:04:15 +0100297 // to move the root to the actual match)
Akronc56cf2d2016-11-09 22:02:38 +0100298
Akron0988d882017-11-10 16:13:12 +0100299 // This is currently not supported by relations
300 if (type === "spans") {
Akron0b489ad2018-02-02 16:49:32 +0100301 var dl = d.createElement('li');
Akron0988d882017-11-10 16:13:12 +0100302 dl.className = 'download';
303 dl.addEventListener(
304 'click', function (e) {
Akron151bc872018-02-02 14:04:15 +0100305 var a = treeObj.downloadLink();
Akron0b489ad2018-02-02 16:49:32 +0100306 d.body.appendChild(a);
Akron0988d882017-11-10 16:13:12 +0100307 a.click();
Akron0b489ad2018-02-02 16:49:32 +0100308 d.body.removeChild(a)
Akron0988d882017-11-10 16:13:12 +0100309 e.halt();
310 }
311 );
312
313 actions.appendChild(dl);
314 };
315
Akronc56cf2d2016-11-09 22:02:38 +0100316 treeObj.center();
Akrond67d45b2017-05-18 21:47:38 +0200317 };
318
319 if (cb !== undefined)
320 cb(treeObj);
Nils Diewald0e6992a2015-04-14 20:13:52 +0000321 });
Akronc8eb4a12018-02-03 00:39:58 +0100322 matchtree.classList.remove('loading');
Nils Diewald0e6992a2015-04-14 20:13:52 +0000323 },
Akronbd342982018-01-25 18:01:46 +0100324
325
Akrone7679692018-01-26 12:06:33 +0100326 // Add meta information to match
Akron151bc872018-02-02 14:04:15 +0100327 showMeta : function () {
Akronedbf33a2018-02-05 19:18:03 +0100328
329 // Already visible
330 if (this._visibleMeta)
331 return;
332
333 this._visibleMeta = true;
334
Akronaeceda72018-02-02 20:44:06 +0100335 var metaTable = document.createElement('div');
Akronc8eb4a12018-02-03 00:39:58 +0100336 metaTable.classList.add('metatable', 'loading');
337 this.element().appendChild(metaTable);
Akronbd342982018-01-25 18:01:46 +0100338
Akron0ad7cd22018-02-08 18:03:06 +0100339 /*
340 * This was temporary
Akronbd342982018-01-25 18:01:46 +0100341 var metaInfo = this._match.element().getAttribute('data-info');
Akronbd342982018-01-25 18:01:46 +0100342 if (metaInfo)
343 metaInfo = JSON.parse(metaInfo);
Akron0ad7cd22018-02-08 18:03:06 +0100344 */
Akronedbf33a2018-02-05 19:18:03 +0100345 var that = this;
346
Akron0ad7cd22018-02-08 18:03:06 +0100347 this.getMetaData(function (meta) {
Akronc8eb4a12018-02-03 00:39:58 +0100348 // Load data
349 metaTable.classList.remove('loading');
350
Akron0ad7cd22018-02-08 18:03:06 +0100351 metaTable.appendChild(meta.element());
Akronaeceda72018-02-02 20:44:06 +0100352
353 // Add button
Akron0ad7cd22018-02-08 18:03:06 +0100354 that._addButton('close', metaTable, function (e) {
Akronaeceda72018-02-02 20:44:06 +0100355 this.parentNode.removeChild(this);
Akronedbf33a2018-02-05 19:18:03 +0100356 that._visibleMeta = false;
Akronaeceda72018-02-02 20:44:06 +0100357 e.halt();
358 });
Akron0ad7cd22018-02-08 18:03:06 +0100359 });
Akron41387d22018-02-02 18:10:06 +0100360
Akron0ad7cd22018-02-08 18:03:06 +0100361 // Do not load any longer
Akronaeceda72018-02-02 20:44:06 +0100362 metaTable.classList.remove('loading');
Akronbd342982018-01-25 18:01:46 +0100363 },
364
Akron151bc872018-02-02 14:04:15 +0100365
Akronbd342982018-01-25 18:01:46 +0100366 // Add table
Akron151bc872018-02-02 14:04:15 +0100367 showTable : function () {
Akronbd342982018-01-25 18:01:46 +0100368
Akronedbf33a2018-02-05 19:18:03 +0100369 // Already visible
370 if (this._visibleTable)
371 return;
372
373 this._visibleTable = true;
374
Nils Diewald0e6992a2015-04-14 20:13:52 +0000375 // Append default table
Akron0b489ad2018-02-02 16:49:32 +0100376 var matchtable = d.createElement('div');
Akronc8eb4a12018-02-03 00:39:58 +0100377 matchtable.classList.add('matchtable', 'loading');
Akronaeceda72018-02-02 20:44:06 +0100378 var info = this.element();
379 info.appendChild(matchtable);
380
Akronedbf33a2018-02-05 19:18:03 +0100381 var that = this;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000382
Akronb6685bb2018-02-04 00:44:47 +0100383 // TODO:
384 // Create try-catch-exception-handling
385
Nils Diewald0e6992a2015-04-14 20:13:52 +0000386 // Create the table asynchronous
Akron151bc872018-02-02 14:04:15 +0100387 this.getTableData(undefined, function (table) {
Akron3bb91bc2016-12-02 16:43:17 +0100388
Akronc8eb4a12018-02-03 00:39:58 +0100389 // Load data
390 matchtable.classList.remove('loading');
391
Akrond67d45b2017-05-18 21:47:38 +0200392 if (table !== null) {
Akron3bb91bc2016-12-02 16:43:17 +0100393 matchtable.appendChild(table.element());
394 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000395 });
Akronaeceda72018-02-02 20:44:06 +0100396
397 // Add button
398 this._addButton('close', matchtable, function (e) {
399 this.parentNode.removeChild(this);
Akronedbf33a2018-02-05 19:18:03 +0100400 that._visibleTable = false;
Akronaeceda72018-02-02 20:44:06 +0100401 e.halt();
402 });
403
404 // Load data
405 matchtable.classList.remove('loading');
Akronbd342982018-01-25 18:01:46 +0100406 },
407
Akronc8eb4a12018-02-03 00:39:58 +0100408 // Add action button
Akronaeceda72018-02-02 20:44:06 +0100409 _addButton : function (buttonType, element, cb) {
410 // TODO: Unless existent
411 var actions = document.createElement('ul');
412 actions.classList.add('action', 'image');
413 var b = actions.addE('li');
414 b.className = buttonType;
415 b.addE('span').addT(buttonType);
416 b.addEventListener(
417 'click', cb.bind(element)
418 );
419
420 element.appendChild(actions);
421 return actions;
422 },
423
424
Akronbd342982018-01-25 18:01:46 +0100425 /**
426 * Create match information view.
427 */
428 element : function () {
429
430 if (this._element !== undefined)
431 return this._element;
432
433 // Create info table
Akron0b489ad2018-02-02 16:49:32 +0100434 var info = d.createElement('div');
Akronbd342982018-01-25 18:01:46 +0100435 info.classList.add('matchinfo');
Nils Diewald0e6992a2015-04-14 20:13:52 +0000436
437 this._element = info;
438
Akronbd342982018-01-25 18:01:46 +0100439 return this._element;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000440 }
441 };
442});