blob: 655535f22486c0d0748c1f4e776a783c364c2d9e [file] [log] [blame]
Akron99713ef2017-06-28 18:19:28 +02001/**
2 * Information about a match.
3 */
Akronbec4a6a2018-07-10 14:45:15 +02004/*
5 * TODO:
Akron537bc522018-07-13 19:06:27 +02006 * Create a "panel" object, that is the parent of this
Akronbec4a6a2018-07-10 14:45:15 +02007 * class and supports a simple .add() method to add views
8 * to an element.
9 */
Nils Diewald7c8ced22015-04-15 19:21:00 +000010define([
11 'match/infolayer',
12 'match/table',
Akron41387d22018-02-02 18:10:06 +010013 'match/treehierarchy',
14 'match/treearc',
Akron151bc872018-02-02 14:04:15 +010015 'match/meta',
Nils Diewald7c8ced22015-04-15 19:21:00 +000016 'util'
17], function (infoLayerClass,
Akron3bb91bc2016-12-02 16:43:17 +010018 matchTableClass,
Akron41387d22018-02-02 18:10:06 +010019 matchTreeHierarchyClass,
20 matchTreeArcClass,
Akronb6685bb2018-02-04 00:44:47 +010021 matchMetaClass) {
Akron3bb91bc2016-12-02 16:43:17 +010022
Nils Diewald7148c6f2015-05-04 15:07:53 +000023 // Override
Nils Diewald0e6992a2015-04-14 20:13:52 +000024 KorAP.API.getMatchInfo = KorAP.API.getMatchInfo || function () {
25 KorAP.log(0, 'KorAP.API.getMatchInfo() not implemented')
26 return {};
27 };
28
Akron0b489ad2018-02-02 16:49:32 +010029 const loc = KorAP.Locale;
30 const d = document;
Nils Diewald0e6992a2015-04-14 20:13:52 +000031
Nils Diewald0e6992a2015-04-14 20:13:52 +000032 return {
Nils Diewald7148c6f2015-05-04 15:07:53 +000033
34 /**
35 * Create new match object
36 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000037 create : function (match) {
38 return Object.create(this)._init(match);
39 },
40
Akron151bc872018-02-02 14:04:15 +010041
Nils Diewald0e6992a2015-04-14 20:13:52 +000042 /**
43 * Initialize object
44 */
45 _init : function (match) {
46 this._match = match;
Akronedbf33a2018-02-05 19:18:03 +010047 this._visibleTable = false;
48 this._visibleMeta = false;
Nils Diewald0e6992a2015-04-14 20:13:52 +000049 this.opened = false;
50 return this;
51 },
52
Akron151bc872018-02-02 14:04:15 +010053
Nils Diewald0e6992a2015-04-14 20:13:52 +000054 /**
55 * Get match object
56 */
57 match : function () {
58 return this._match;
59 },
60
Nils Diewald7148c6f2015-05-04 15:07:53 +000061
62 /**
Nils Diewald7148c6f2015-05-04 15:07:53 +000063 * Retrieve and parse snippet for table
64 * representation
Nils Diewald0e6992a2015-04-14 20:13:52 +000065 */
Akron151bc872018-02-02 14:04:15 +010066 getTableData : function (tokens, cb) {
Nils Diewald0e6992a2015-04-14 20:13:52 +000067 var focus = [];
68
69 // Get all tokens
70 if (tokens === undefined) {
Akrond67d45b2017-05-18 21:47:38 +020071 focus = this._match.getTokens();
Nils Diewald0e6992a2015-04-14 20:13:52 +000072 }
73
74 // Get only some tokens
75 else {
Akrond67d45b2017-05-18 21:47:38 +020076
77 // Push newly to focus array
78 for (var i = 0; i < tokens.length; i++) {
79 var term = tokens[i];
80 try {
81 // Create info layer objects
82 var layer = infoLayerClass.create(term);
83 layer.type = "tokens";
84 focus.push(layer);
85 }
86 catch (e) {
87 continue;
88 };
89 };
Nils Diewald0e6992a2015-04-14 20:13:52 +000090 };
91
92 // No tokens chosen
93 if (focus.length == 0)
Akrond67d45b2017-05-18 21:47:38 +020094 cb(null);
Nils Diewald0e6992a2015-04-14 20:13:52 +000095
Akron4f791442018-02-12 13:25:47 +010096 try {
97 // Get info (may be cached)
98 KorAP.API.getMatchInfo(
99 this._match,
100 { 'spans' : false, 'layer' : focus },
Akrond67d45b2017-05-18 21:47:38 +0200101
Akron4f791442018-02-12 13:25:47 +0100102 // Callback for retrieval
103 function (matchResponse) {
Akron3bb91bc2016-12-02 16:43:17 +0100104
Akron4f791442018-02-12 13:25:47 +0100105 if (matchResponse === undefined)
106 cb(null);
Akron515851a2017-05-02 12:53:17 +0200107
Akron4f791442018-02-12 13:25:47 +0100108 // Get snippet from match info
109 if (matchResponse["snippet"] !== undefined) {
110 this._table = matchTableClass.create(matchResponse["snippet"]);
111 cb(this._table);
112 };
113 }.bind(this)
114 );
115 }
116 catch (e) {
117 KorAP.log(0, e);
118 cb(null);
119 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000120
121 /*
122 // Todo: Store the table as a hash of the focus
123 return null;
124 */
125 },
Akronbd342982018-01-25 18:01:46 +0100126
127
Akron4f791442018-02-12 13:25:47 +0100128 /**
129 * Receive meta data from server.
130 */
Akron0ad7cd22018-02-08 18:03:06 +0100131 getMetaData : function (cb) {
Akronb5d05d72018-02-12 15:09:12 +0100132
133 var match = this._match;
134
Akron4f791442018-02-12 13:25:47 +0100135 try {
136 KorAP.API.getTextInfo(
Akronb5d05d72018-02-12 15:09:12 +0100137 match, {}, function (textResponse) {
138
Akron4f791442018-02-12 13:25:47 +0100139 if (textResponse === undefined) {
140 cb(null);
141 return;
142 };
Akron0ad7cd22018-02-08 18:03:06 +0100143
Akron4f791442018-02-12 13:25:47 +0100144 var doc = textResponse["document"];
Akron0ad7cd22018-02-08 18:03:06 +0100145
Akron4f791442018-02-12 13:25:47 +0100146 if (doc === undefined) {
147 cb(null);
148 return;
149 };
Akron0ad7cd22018-02-08 18:03:06 +0100150
Akron4f791442018-02-12 13:25:47 +0100151 var fields = doc["fields"];
152 if (fields === undefined) {
153 cb(null);
154 return;
155 };
Akron0ad7cd22018-02-08 18:03:06 +0100156
Akron4f791442018-02-12 13:25:47 +0100157 // Add metainfo to matchview
158 cb(matchMetaClass.create(
Akronb5d05d72018-02-12 15:09:12 +0100159 match, fields
Akron4f791442018-02-12 13:25:47 +0100160 ));
161 }
162 );
163 }
164 catch (e) {
165 KorAP.log(0, e);
166 cb(null);
167 };
Akronbd342982018-01-25 18:01:46 +0100168 },
Nils Diewald0e6992a2015-04-14 20:13:52 +0000169
170
171 /**
172 * Retrieve and parse snippet for tree representation
173 */
Akron151bc872018-02-02 14:04:15 +0100174 getTreeData : function (foundry, layer, type, cb) {
Nils Diewald0e6992a2015-04-14 20:13:52 +0000175 var focus = [];
Akron0ad7cd22018-02-08 18:03:06 +0100176
Akron4f791442018-02-12 13:25:47 +0100177 try {
178 // TODO: Support and cache multiple trees
179 KorAP.API.getMatchInfo(
180 this._match, {
181 'spans' : true,
182 'foundry' : foundry,
183 'layer' : layer
184 },
185 function (matchResponse) {
186 if (matchResponse === undefined) {
187 cb(null);
188 return;
189 };
Akronc56cf2d2016-11-09 22:02:38 +0100190
Akron4f791442018-02-12 13:25:47 +0100191 // Get snippet from match info
192 if (matchResponse["snippet"] !== undefined) {
193 // Todo: This should be cached somehow
194
195 if (type === "spans") {
196 cb(matchTreeHierarchyClass.create(matchResponse["snippet"]));
197 }
198 else if (type === "rels") {
199 cb(matchTreeArcClass.create(matchResponse["snippet"]));
200 }
201
202 // Unknown tree type
203 else {
204 cb(null);
205 };
Akron0988d882017-11-10 16:13:12 +0100206 }
Akron0988d882017-11-10 16:13:12 +0100207 else {
208 cb(null);
209 };
Akron4f791442018-02-12 13:25:47 +0100210 }.bind(this)
211 );
212 }
213 catch (e) {
214 KorAP.log(0, e);
215 cb(null);
216 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000217 },
218
Akron151bc872018-02-02 14:04:15 +0100219
Nils Diewald0e6992a2015-04-14 20:13:52 +0000220 /**
221 * Destroy this match information view.
222 */
223 destroy : function () {
224
225 // Remove circular reference
Akron8b592d42018-01-26 18:33:06 +0100226 /*
Nils Diewald0e6992a2015-04-14 20:13:52 +0000227 if (this._treeMenu !== undefined)
Akron99713ef2017-06-28 18:19:28 +0200228 delete this._treeMenu["info"];
Nils Diewald0e6992a2015-04-14 20:13:52 +0000229
230 this._treeMenu.destroy();
231 this._treeMenu = undefined;
Akron8b592d42018-01-26 18:33:06 +0100232 */
Nils Diewald0e6992a2015-04-14 20:13:52 +0000233 this._match = undefined;
Akron99713ef2017-06-28 18:19:28 +0200234 this._matchCreator = undefined;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000235 // Element destroy
236 },
237
Akron151bc872018-02-02 14:04:15 +0100238
Nils Diewald0e6992a2015-04-14 20:13:52 +0000239 /**
240 * Add a new tree view to the list
241 */
Akron151bc872018-02-02 14:04:15 +0100242 showTree : function (foundry, layer, type, cb) {
Akron0b489ad2018-02-02 16:49:32 +0100243 var matchtree = d.createElement('div');
Akronc8eb4a12018-02-03 00:39:58 +0100244 matchtree.classList.add('matchtree', 'loading');
245
246 this.element().appendChild(matchtree);
Akrond67d45b2017-05-18 21:47:38 +0200247
Akron151bc872018-02-02 14:04:15 +0100248 // Add title line
249 var h6 = matchtree.addE('h6');
250 h6.addE('span').addT(foundry);
251 h6.addE('span').addT(layer);
252
253 var tree = matchtree.addE('div');
Nils Diewald0e6992a2015-04-14 20:13:52 +0000254
Akron151bc872018-02-02 14:04:15 +0100255 // Add close action button
Akronc8eb4a12018-02-03 00:39:58 +0100256 var actions = this._addButton('close', matchtree, function (e) {
257 this.parentNode.removeChild(this);
258 e.halt();
259 });
Nils Diewald0e6992a2015-04-14 20:13:52 +0000260
Akronc8eb4a12018-02-03 00:39:58 +0100261 // tree.classList.add('loading'); // alternatively
Nils Diewald0ec142f2015-05-05 00:29:23 +0000262
Nils Diewald0e6992a2015-04-14 20:13:52 +0000263 // Get tree data async
Akron151bc872018-02-02 14:04:15 +0100264 this.getTreeData(foundry, layer, type, function (treeObj) {
Akronc8eb4a12018-02-03 00:39:58 +0100265 matchtree.classList.remove('loading');
Nils Diewald0ec142f2015-05-05 00:29:23 +0000266
Akrond67d45b2017-05-18 21:47:38 +0200267 // Something went wrong - probably log!!!
Nils Diewald0ec142f2015-05-05 00:29:23 +0000268
Akrond67d45b2017-05-18 21:47:38 +0200269 if (treeObj === null) {
Akron151bc872018-02-02 14:04:15 +0100270 tree.addT('No data available.');
Akrond67d45b2017-05-18 21:47:38 +0200271 }
272 else {
273 tree.appendChild(treeObj.element());
Akron0988d882017-11-10 16:13:12 +0100274 treeObj.show();
Akron151bc872018-02-02 14:04:15 +0100275
Akrond67d45b2017-05-18 21:47:38 +0200276 // Reposition the view to the center
277 // (This may in a future release be a reposition
Akron151bc872018-02-02 14:04:15 +0100278 // to move the root to the actual match)
Akronc56cf2d2016-11-09 22:02:38 +0100279
Akron0988d882017-11-10 16:13:12 +0100280 // This is currently not supported by relations
281 if (type === "spans") {
Akron0b489ad2018-02-02 16:49:32 +0100282 var dl = d.createElement('li');
Akron0988d882017-11-10 16:13:12 +0100283 dl.className = 'download';
284 dl.addEventListener(
285 'click', function (e) {
Akron151bc872018-02-02 14:04:15 +0100286 var a = treeObj.downloadLink();
Akron0b489ad2018-02-02 16:49:32 +0100287 d.body.appendChild(a);
Akron0988d882017-11-10 16:13:12 +0100288 a.click();
Akron0b489ad2018-02-02 16:49:32 +0100289 d.body.removeChild(a)
Akron0988d882017-11-10 16:13:12 +0100290 e.halt();
291 }
292 );
293
294 actions.appendChild(dl);
295 };
296
Akronc56cf2d2016-11-09 22:02:38 +0100297 treeObj.center();
Akrond67d45b2017-05-18 21:47:38 +0200298 };
299
300 if (cb !== undefined)
301 cb(treeObj);
Nils Diewald0e6992a2015-04-14 20:13:52 +0000302 });
Akronc8eb4a12018-02-03 00:39:58 +0100303 matchtree.classList.remove('loading');
Nils Diewald0e6992a2015-04-14 20:13:52 +0000304 },
Akronbd342982018-01-25 18:01:46 +0100305
306
Akrone7679692018-01-26 12:06:33 +0100307 // Add meta information to match
Akron151bc872018-02-02 14:04:15 +0100308 showMeta : function () {
Akronedbf33a2018-02-05 19:18:03 +0100309
310 // Already visible
311 if (this._visibleMeta)
312 return;
313
314 this._visibleMeta = true;
315
Akronaeceda72018-02-02 20:44:06 +0100316 var metaTable = document.createElement('div');
Akronc8eb4a12018-02-03 00:39:58 +0100317 metaTable.classList.add('metatable', 'loading');
318 this.element().appendChild(metaTable);
Akronbd342982018-01-25 18:01:46 +0100319
Akron0ad7cd22018-02-08 18:03:06 +0100320 /*
321 * This was temporary
Akronbd342982018-01-25 18:01:46 +0100322 var metaInfo = this._match.element().getAttribute('data-info');
Akronbd342982018-01-25 18:01:46 +0100323 if (metaInfo)
324 metaInfo = JSON.parse(metaInfo);
Akron0ad7cd22018-02-08 18:03:06 +0100325 */
Akronedbf33a2018-02-05 19:18:03 +0100326 var that = this;
327
Akron0ad7cd22018-02-08 18:03:06 +0100328 this.getMetaData(function (meta) {
Akronb5d05d72018-02-12 15:09:12 +0100329
330 if (meta === null)
331 return;
332
Akronc8eb4a12018-02-03 00:39:58 +0100333 // Load data
334 metaTable.classList.remove('loading');
335
Akron0ad7cd22018-02-08 18:03:06 +0100336 metaTable.appendChild(meta.element());
Akronaeceda72018-02-02 20:44:06 +0100337
338 // Add button
Akron0ad7cd22018-02-08 18:03:06 +0100339 that._addButton('close', metaTable, function (e) {
Akronaeceda72018-02-02 20:44:06 +0100340 this.parentNode.removeChild(this);
Akronedbf33a2018-02-05 19:18:03 +0100341 that._visibleMeta = false;
Akronaeceda72018-02-02 20:44:06 +0100342 e.halt();
343 });
Akron0ad7cd22018-02-08 18:03:06 +0100344 });
Akron41387d22018-02-02 18:10:06 +0100345
Akron0ad7cd22018-02-08 18:03:06 +0100346 // Do not load any longer
Akronaeceda72018-02-02 20:44:06 +0100347 metaTable.classList.remove('loading');
Akronbd342982018-01-25 18:01:46 +0100348 },
349
Akron151bc872018-02-02 14:04:15 +0100350
Akronbd342982018-01-25 18:01:46 +0100351 // Add table
Akron151bc872018-02-02 14:04:15 +0100352 showTable : function () {
Akronbd342982018-01-25 18:01:46 +0100353
Akronedbf33a2018-02-05 19:18:03 +0100354 // Already visible
355 if (this._visibleTable)
356 return;
357
358 this._visibleTable = true;
359
Nils Diewald0e6992a2015-04-14 20:13:52 +0000360 // Append default table
Akron0b489ad2018-02-02 16:49:32 +0100361 var matchtable = d.createElement('div');
Akronc8eb4a12018-02-03 00:39:58 +0100362 matchtable.classList.add('matchtable', 'loading');
Akronaeceda72018-02-02 20:44:06 +0100363 var info = this.element();
364 info.appendChild(matchtable);
365
Akronedbf33a2018-02-05 19:18:03 +0100366 var that = this;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000367
Akronb6685bb2018-02-04 00:44:47 +0100368 // TODO:
369 // Create try-catch-exception-handling
370
Nils Diewald0e6992a2015-04-14 20:13:52 +0000371 // Create the table asynchronous
Akron151bc872018-02-02 14:04:15 +0100372 this.getTableData(undefined, function (table) {
Akron3bb91bc2016-12-02 16:43:17 +0100373
Akronc8eb4a12018-02-03 00:39:58 +0100374 // Load data
375 matchtable.classList.remove('loading');
376
Akrond67d45b2017-05-18 21:47:38 +0200377 if (table !== null) {
Akron3bb91bc2016-12-02 16:43:17 +0100378 matchtable.appendChild(table.element());
379 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000380 });
Akronaeceda72018-02-02 20:44:06 +0100381
382 // Add button
383 this._addButton('close', matchtable, function (e) {
384 this.parentNode.removeChild(this);
Akronedbf33a2018-02-05 19:18:03 +0100385 that._visibleTable = false;
Akronaeceda72018-02-02 20:44:06 +0100386 e.halt();
387 });
388
389 // Load data
390 matchtable.classList.remove('loading');
Akronbd342982018-01-25 18:01:46 +0100391 },
392
Akronc8eb4a12018-02-03 00:39:58 +0100393 // Add action button
Akron537bc522018-07-13 19:06:27 +0200394 // TODO:
395 // These are view-buttons that should be added to
396 // the view and not to the panel!
Akronaeceda72018-02-02 20:44:06 +0100397 _addButton : function (buttonType, element, cb) {
398 // TODO: Unless existent
399 var actions = document.createElement('ul');
400 actions.classList.add('action', 'image');
401 var b = actions.addE('li');
402 b.className = buttonType;
403 b.addE('span').addT(buttonType);
404 b.addEventListener(
405 'click', cb.bind(element)
406 );
407
408 element.appendChild(actions);
409 return actions;
410 },
411
412
Akronbd342982018-01-25 18:01:46 +0100413 /**
414 * Create match information view.
415 */
416 element : function () {
417
418 if (this._element !== undefined)
419 return this._element;
420
421 // Create info table
Akron0b489ad2018-02-02 16:49:32 +0100422 var info = d.createElement('div');
Akronbd342982018-01-25 18:01:46 +0100423 info.classList.add('matchinfo');
Nils Diewald0e6992a2015-04-14 20:13:52 +0000424
425 this._element = info;
426
Akronbd342982018-01-25 18:01:46 +0100427 return this._element;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000428 }
429 };
430});