blob: a6ccbeced2d9ccfe8669723f7ad6c4d43ced4fb6 [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',
7 'match/tree',
Akronbd342982018-01-25 18:01:46 +01008 'match/reference', // rename to meta
Akron0988d882017-11-10 16:13:12 +01009 'match/relations',
Nils Diewald7c8ced22015-04-15 19:21:00 +000010 'match/treemenu',
Akron99713ef2017-06-28 18:19:28 +020011 'match/querycreator',
Nils Diewald7c8ced22015-04-15 19:21:00 +000012 'util'
13], function (infoLayerClass,
Akron3bb91bc2016-12-02 16:43:17 +010014 matchTableClass,
15 matchTreeClass,
Akronbd342982018-01-25 18:01:46 +010016 matchRefClass,
Akron0988d882017-11-10 16:13:12 +010017 matchRelClass,
Akron99713ef2017-06-28 18:19:28 +020018 matchTreeMenuClass,
Akron0988d882017-11-10 16:13:12 +010019 matchQueryCreator) {
Akron3bb91bc2016-12-02 16:43:17 +010020
Nils Diewald7148c6f2015-05-04 15:07:53 +000021 // Override
Nils Diewald0e6992a2015-04-14 20:13:52 +000022 KorAP.API.getMatchInfo = KorAP.API.getMatchInfo || function () {
23 KorAP.log(0, 'KorAP.API.getMatchInfo() not implemented')
24 return {};
25 };
26
27 var loc = KorAP.Locale;
28
Nils Diewald0e6992a2015-04-14 20:13:52 +000029 return {
Nils Diewald7148c6f2015-05-04 15:07:53 +000030
31 /**
32 * Create new match object
33 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000034 create : function (match) {
35 return Object.create(this)._init(match);
36 },
37
38 /**
39 * Initialize object
40 */
41 _init : function (match) {
42 this._match = match;
43 this.opened = false;
44 return this;
45 },
46
47 /**
48 * Get match object
49 */
50 match : function () {
51 return this._match;
52 },
53
Nils Diewald7148c6f2015-05-04 15:07:53 +000054
55 /**
56 * Open the information view,
57 * if closed, otherwise close.
58 */
Akronbd342982018-01-25 18:01:46 +010059 /*
Nils Diewald0e6992a2015-04-14 20:13:52 +000060 toggle : function () {
Akron3bb91bc2016-12-02 16:43:17 +010061
Akron08b82d62016-12-05 15:06:05 +010062 var elem = this._match.element();
Akron3bb91bc2016-12-02 16:43:17 +010063
64 if (this.opened == true) {
Akrond67d45b2017-05-18 21:47:38 +020065 elem.removeChild(
66 this.element()
67 );
68 this.opened = false;
Nils Diewald0e6992a2015-04-14 20:13:52 +000069 }
70 else {
Akrond67d45b2017-05-18 21:47:38 +020071 // Append element to match
Akron3bb91bc2016-12-02 16:43:17 +010072 elem.appendChild(
Akrond67d45b2017-05-18 21:47:38 +020073 this.element()
74 );
75 this.opened = true;
Nils Diewald0e6992a2015-04-14 20:13:52 +000076 };
77
78 return this.opened;
79 },
Akronbd342982018-01-25 18:01:46 +010080 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000081
82
83 /**
Nils Diewald7148c6f2015-05-04 15:07:53 +000084 * Retrieve and parse snippet for table
85 * representation
Nils Diewald0e6992a2015-04-14 20:13:52 +000086 */
87 getTable : function (tokens, cb) {
88 var focus = [];
89
90 // Get all tokens
91 if (tokens === undefined) {
Akrond67d45b2017-05-18 21:47:38 +020092 focus = this._match.getTokens();
Nils Diewald0e6992a2015-04-14 20:13:52 +000093 }
94
95 // Get only some tokens
96 else {
Akrond67d45b2017-05-18 21:47:38 +020097
98 // Push newly to focus array
99 for (var i = 0; i < tokens.length; i++) {
100 var term = tokens[i];
101 try {
102 // Create info layer objects
103 var layer = infoLayerClass.create(term);
104 layer.type = "tokens";
105 focus.push(layer);
106 }
107 catch (e) {
108 continue;
109 };
110 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000111 };
112
113 // No tokens chosen
114 if (focus.length == 0)
Akrond67d45b2017-05-18 21:47:38 +0200115 cb(null);
Nils Diewald0e6992a2015-04-14 20:13:52 +0000116
117 // Get info (may be cached)
Nils Diewald0e6992a2015-04-14 20:13:52 +0000118 KorAP.API.getMatchInfo(
Akrond67d45b2017-05-18 21:47:38 +0200119 this._match,
120 { 'spans' : false, 'layer' : focus },
121
122 // Callback for retrieval
123 function (matchResponse) {
Akron3bb91bc2016-12-02 16:43:17 +0100124
Akron515851a2017-05-02 12:53:17 +0200125 if (matchResponse === undefined)
126 cb(null);
127
Akrond67d45b2017-05-18 21:47:38 +0200128 // Get snippet from match info
129 if (matchResponse["snippet"] !== undefined) {
130 this._table = matchTableClass.create(matchResponse["snippet"]);
131 cb(this._table);
132 };
133 }.bind(this)
Nils Diewald0e6992a2015-04-14 20:13:52 +0000134 );
135
136 /*
137 // Todo: Store the table as a hash of the focus
138 return null;
139 */
140 },
Akronbd342982018-01-25 18:01:46 +0100141
142
143 getMeta : function (metaInfo, cb) {
144
145 },
Nils Diewald0e6992a2015-04-14 20:13:52 +0000146
147
148 /**
149 * Retrieve and parse snippet for tree representation
150 */
Akron0988d882017-11-10 16:13:12 +0100151 getTree : function (foundry, layer, type, cb) {
Nils Diewald0e6992a2015-04-14 20:13:52 +0000152 var focus = [];
153
154 // TODO: Support and cache multiple trees
155 KorAP.API.getMatchInfo(
Akrond67d45b2017-05-18 21:47:38 +0200156 this._match, {
157 'spans' : true,
158 'foundry' : foundry,
159 'layer' : layer
160 },
161 function (matchResponse) {
162 // Get snippet from match info
163 if (matchResponse["snippet"] !== undefined) {
164 // Todo: This should be cached somehow
Akronc56cf2d2016-11-09 22:02:38 +0100165
Akron0988d882017-11-10 16:13:12 +0100166 if (type === "spans") {
167 cb(matchTreeClass.create(matchResponse["snippet"]));
168 }
169 else if (type === "rels") {
170 cb(matchRelClass.create(matchResponse["snippet"]));
171 }
172
173 // Unknown tree type
174 else {
175 cb(null);
176 };
Akrond67d45b2017-05-18 21:47:38 +0200177 }
178 else {
179 cb(null);
180 };
181 }.bind(this)
Nils Diewald0e6992a2015-04-14 20:13:52 +0000182 );
183 },
184
185 /**
186 * Destroy this match information view.
187 */
188 destroy : function () {
189
190 // Remove circular reference
191 if (this._treeMenu !== undefined)
Akron99713ef2017-06-28 18:19:28 +0200192 delete this._treeMenu["info"];
Nils Diewald0e6992a2015-04-14 20:13:52 +0000193
194 this._treeMenu.destroy();
195 this._treeMenu = undefined;
196 this._match = undefined;
Akron99713ef2017-06-28 18:19:28 +0200197 this._matchCreator = undefined;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000198 // Element destroy
199 },
200
201 /**
202 * Add a new tree view to the list
203 */
Akron0988d882017-11-10 16:13:12 +0100204 addTree : function (foundry, layer, type, cb) {
Nils Diewald0e6992a2015-04-14 20:13:52 +0000205 var matchtree = document.createElement('div');
206 matchtree.classList.add('matchtree');
207
208 var h6 = matchtree.appendChild(document.createElement('h6'));
209 h6.appendChild(document.createElement('span'))
Akron99713ef2017-06-28 18:19:28 +0200210 .appendChild(document.createTextNode(foundry));
Nils Diewald0e6992a2015-04-14 20:13:52 +0000211 h6.appendChild(document.createElement('span'))
Akrond67d45b2017-05-18 21:47:38 +0200212 .appendChild(document.createTextNode(layer));
213
Nils Diewald0e6992a2015-04-14 20:13:52 +0000214 var tree = matchtree.appendChild(
Akrond67d45b2017-05-18 21:47:38 +0200215 document.createElement('div')
Nils Diewald0e6992a2015-04-14 20:13:52 +0000216 );
217
218 this._element.insertBefore(matchtree, this._element.lastChild);
219
Akronc56cf2d2016-11-09 22:02:38 +0100220 var actions = tree.appendChild(document.createElement('ul'));
221 actions.classList.add('action', 'image');
222 var close = actions.appendChild(document.createElement('li'));
223 close.className = 'close';
224 close.appendChild(document.createElement('span'));
Nils Diewald0e6992a2015-04-14 20:13:52 +0000225 close.addEventListener(
Akrond67d45b2017-05-18 21:47:38 +0200226 'click', function (e) {
227 matchtree.parentNode.removeChild(matchtree);
228 e.halt();
229 }
Nils Diewald0e6992a2015-04-14 20:13:52 +0000230 );
231
Nils Diewald0ec142f2015-05-05 00:29:23 +0000232 tree.classList.add('loading');
233
Nils Diewald0e6992a2015-04-14 20:13:52 +0000234 // Get tree data async
Akron0988d882017-11-10 16:13:12 +0100235 this.getTree(foundry, layer, type, function (treeObj) {
Nils Diewald0ec142f2015-05-05 00:29:23 +0000236
Akrond67d45b2017-05-18 21:47:38 +0200237 tree.classList.remove('loading');
Nils Diewald0ec142f2015-05-05 00:29:23 +0000238
Akrond67d45b2017-05-18 21:47:38 +0200239 // Something went wrong - probably log!!!
Nils Diewald0ec142f2015-05-05 00:29:23 +0000240
Akrond67d45b2017-05-18 21:47:38 +0200241 if (treeObj === null) {
242 tree.appendChild(document.createTextNode('No data available.'));
243 }
244 else {
245 tree.appendChild(treeObj.element());
Akron0988d882017-11-10 16:13:12 +0100246 treeObj.show();
Akrond67d45b2017-05-18 21:47:38 +0200247 // Reposition the view to the center
248 // (This may in a future release be a reposition
249 // to move the root into the center or the actual
250 // match)
Akronc56cf2d2016-11-09 22:02:38 +0100251
Akron0988d882017-11-10 16:13:12 +0100252 // This is currently not supported by relations
253 if (type === "spans") {
254 var dl = document.createElement('li');
255 dl.className = 'download';
256 dl.addEventListener(
257 'click', function (e) {
Akronc56cf2d2016-11-09 22:02:38 +0100258
Akron0988d882017-11-10 16:13:12 +0100259 var a = document.createElement('a');
260 a.setAttribute('href-lang', 'image/svg+xml');
261 a.setAttribute('href', 'data:image/svg+xml;base64,'+treeObj.toBase64());
262 a.setAttribute('download', 'tree.svg');
263 a.target = '_blank';
Akrona27f0d42017-11-13 14:08:41 +0100264 a.setAttribute('rel', 'noopener noreferrer');
Akron0988d882017-11-10 16:13:12 +0100265
266 document.body.appendChild(a);
267 a.click();
268 document.body.removeChild(a)
269 e.halt();
270 }
271 );
272
273 actions.appendChild(dl);
274 };
275
Akronc56cf2d2016-11-09 22:02:38 +0100276 treeObj.center();
Akrond67d45b2017-05-18 21:47:38 +0200277 };
278
279 if (cb !== undefined)
280 cb(treeObj);
Nils Diewald0e6992a2015-04-14 20:13:52 +0000281 });
282 },
Akronbd342982018-01-25 18:01:46 +0100283
284
285 addMeta : function () {
286 var matchmeta = document.createElement('div');
287 // matchRefClass.create();
288
289 // TODO: This is part of the getMeta!
290 var metaInfo = this._match.element().getAttribute('data-info');
291
292 if (metaInfo)
293 metaInfo = JSON.parse(metaInfo);
294
295 // There is metainfo
296 if (metaInfo) {
297
298 // Add metainfo to matchview
299 var metaElem = matchRefClass.create(this._match).element(metaInfo);
300 this.element().appendChild(metaElem);
301
302 console.log(this.element());
303 };
304 },
305
306 // Add table
307 addTable : function () {
308
309 var info = this.element();
Nils Diewald0e6992a2015-04-14 20:13:52 +0000310
311 // Append default table
312 var matchtable = document.createElement('div');
Nils Diewald0ec142f2015-05-05 00:29:23 +0000313 matchtable.classList.add('matchtable', 'loading');
Nils Diewald0e6992a2015-04-14 20:13:52 +0000314 info.appendChild(matchtable);
315
316 // Create the table asynchronous
317 this.getTable(undefined, function (table) {
Akron3bb91bc2016-12-02 16:43:17 +0100318
Akrond67d45b2017-05-18 21:47:38 +0200319 if (table !== null) {
Akron3bb91bc2016-12-02 16:43:17 +0100320 matchtable.appendChild(table.element());
321 };
Akron515851a2017-05-02 12:53:17 +0200322 matchtable.classList.remove('loading');
Akron99713ef2017-06-28 18:19:28 +0200323
324 // Add query creator
Akrone8ea0002017-06-28 18:51:52 +0200325 this._matchCreator = matchQueryCreator.create(info);
Nils Diewald0e6992a2015-04-14 20:13:52 +0000326 });
327
Akronbd342982018-01-25 18:01:46 +0100328
329 info.appendChild(this.addTreeMenu());
330 },
331
332
333 addTreeMenu : function () {
334
Akrond67d45b2017-05-18 21:47:38 +0200335 // Join spans and relations
336 var treeLayers = []
337 var spans = this._match.getSpans();
338 var rels = this._match.getRels();
339 var i;
340 for (i in spans) {
341 treeLayers.push(spans[i]);
342 };
343 for (i in rels) {
344 treeLayers.push(rels[i]);
345 };
346
Nils Diewald0e6992a2015-04-14 20:13:52 +0000347 // Get spans
Akrond67d45b2017-05-18 21:47:38 +0200348 treeLayers = treeLayers.sort(
349 function (a, b) {
350 if (a.foundry < b.foundry) {
351 return -1;
352 }
353 else if (a.foundry > b.foundry) {
354 return 1;
355 }
356 else if (a.layer < b.layer) {
357 return -1;
358 }
359 else if (a.layer > b.layer) {
360 return 1;
361 };
362 return 0;
363 });
Nils Diewald0e6992a2015-04-14 20:13:52 +0000364
365 var menuList = [];
366
367 // Show tree views
Akrond67d45b2017-05-18 21:47:38 +0200368 for (var i = 0; i < treeLayers.length; i++) {
369 var span = treeLayers[i];
370
371 // Add foundry/layer to menu list
372 menuList.push([
373 span.foundry + '/' + span.layer,
374 span.foundry,
Akron0988d882017-11-10 16:13:12 +0100375 span.layer,
376 span.type
Akrond67d45b2017-05-18 21:47:38 +0200377 ]);
Nils Diewald0e6992a2015-04-14 20:13:52 +0000378 };
379
380 // Create tree menu
381 var treemenu = this.treeMenu(menuList);
Akronbd342982018-01-25 18:01:46 +0100382 var span = document.createElement('p');
Nils Diewald0e6992a2015-04-14 20:13:52 +0000383 span.classList.add('addtree');
384 span.appendChild(document.createTextNode(loc.ADDTREE));
385
386 var treeElement = treemenu.element();
387 span.appendChild(treeElement);
388
389 span.addEventListener('click', function (e) {
Akrond67d45b2017-05-18 21:47:38 +0200390 treemenu.show();
391 treemenu.focus();
Nils Diewald0e6992a2015-04-14 20:13:52 +0000392 });
Akronbd342982018-01-25 18:01:46 +0100393
394 return span;
395 },
396
397 /**
398 * Create match information view.
399 */
400 element : function () {
401
402 if (this._element !== undefined)
403 return this._element;
404
405 // Create info table
406 var info = document.createElement('div');
407 info.classList.add('matchinfo');
Nils Diewald0e6992a2015-04-14 20:13:52 +0000408
409 this._element = info;
410
Akronbd342982018-01-25 18:01:46 +0100411 return this._element;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000412 },
413
414
415 /**
416 * Get tree menu.
417 * There is only one menu rendered
418 * - no matter how many trees exist
419 */
420 treeMenu : function (list) {
421 if (this._treeMenu !== undefined)
Akrond67d45b2017-05-18 21:47:38 +0200422 return this._treeMenu;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000423
424 return this._treeMenu = matchTreeMenuClass.create(this, list);
425 }
426 };
427});