blob: a0b7424031ba32d0702cfa92ade7462964134cab [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',
Akron99713ef2017-06-28 18:19:28 +020010 'match/querycreator',
Nils Diewald7c8ced22015-04-15 19:21:00 +000011 'util'
12], function (infoLayerClass,
Akron3bb91bc2016-12-02 16:43:17 +010013 matchTableClass,
14 matchTreeClass,
Akronbd342982018-01-25 18:01:46 +010015 matchRefClass,
Akron0988d882017-11-10 16:13:12 +010016 matchRelClass,
Akron0988d882017-11-10 16:13:12 +010017 matchQueryCreator) {
Akron3bb91bc2016-12-02 16:43:17 +010018
Nils Diewald7148c6f2015-05-04 15:07:53 +000019 // Override
Nils Diewald0e6992a2015-04-14 20:13:52 +000020 KorAP.API.getMatchInfo = KorAP.API.getMatchInfo || function () {
21 KorAP.log(0, 'KorAP.API.getMatchInfo() not implemented')
22 return {};
23 };
24
25 var loc = KorAP.Locale;
26
Nils Diewald0e6992a2015-04-14 20:13:52 +000027 return {
Nils Diewald7148c6f2015-05-04 15:07:53 +000028
29 /**
30 * Create new match object
31 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000032 create : function (match) {
33 return Object.create(this)._init(match);
34 },
35
36 /**
37 * Initialize object
38 */
39 _init : function (match) {
40 this._match = match;
41 this.opened = false;
42 return this;
43 },
44
45 /**
46 * Get match object
47 */
48 match : function () {
49 return this._match;
50 },
51
Nils Diewald7148c6f2015-05-04 15:07:53 +000052
53 /**
54 * Open the information view,
55 * if closed, otherwise close.
56 */
Akronbd342982018-01-25 18:01:46 +010057 /*
Nils Diewald0e6992a2015-04-14 20:13:52 +000058 toggle : function () {
Akron3bb91bc2016-12-02 16:43:17 +010059
Akron08b82d62016-12-05 15:06:05 +010060 var elem = this._match.element();
Akron3bb91bc2016-12-02 16:43:17 +010061
62 if (this.opened == true) {
Akrond67d45b2017-05-18 21:47:38 +020063 elem.removeChild(
64 this.element()
65 );
66 this.opened = false;
Nils Diewald0e6992a2015-04-14 20:13:52 +000067 }
68 else {
Akrond67d45b2017-05-18 21:47:38 +020069 // Append element to match
Akron3bb91bc2016-12-02 16:43:17 +010070 elem.appendChild(
Akrond67d45b2017-05-18 21:47:38 +020071 this.element()
72 );
73 this.opened = true;
Nils Diewald0e6992a2015-04-14 20:13:52 +000074 };
75
76 return this.opened;
77 },
Akronbd342982018-01-25 18:01:46 +010078 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000079
80
81 /**
Nils Diewald7148c6f2015-05-04 15:07:53 +000082 * Retrieve and parse snippet for table
83 * representation
Nils Diewald0e6992a2015-04-14 20:13:52 +000084 */
85 getTable : function (tokens, cb) {
86 var focus = [];
87
88 // Get all tokens
89 if (tokens === undefined) {
Akrond67d45b2017-05-18 21:47:38 +020090 focus = this._match.getTokens();
Nils Diewald0e6992a2015-04-14 20:13:52 +000091 }
92
93 // Get only some tokens
94 else {
Akrond67d45b2017-05-18 21:47:38 +020095
96 // Push newly to focus array
97 for (var i = 0; i < tokens.length; i++) {
98 var term = tokens[i];
99 try {
100 // Create info layer objects
101 var layer = infoLayerClass.create(term);
102 layer.type = "tokens";
103 focus.push(layer);
104 }
105 catch (e) {
106 continue;
107 };
108 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000109 };
110
111 // No tokens chosen
112 if (focus.length == 0)
Akrond67d45b2017-05-18 21:47:38 +0200113 cb(null);
Nils Diewald0e6992a2015-04-14 20:13:52 +0000114
115 // Get info (may be cached)
Nils Diewald0e6992a2015-04-14 20:13:52 +0000116 KorAP.API.getMatchInfo(
Akrond67d45b2017-05-18 21:47:38 +0200117 this._match,
118 { 'spans' : false, 'layer' : focus },
119
120 // Callback for retrieval
121 function (matchResponse) {
Akron3bb91bc2016-12-02 16:43:17 +0100122
Akron515851a2017-05-02 12:53:17 +0200123 if (matchResponse === undefined)
124 cb(null);
125
Akrond67d45b2017-05-18 21:47:38 +0200126 // Get snippet from match info
127 if (matchResponse["snippet"] !== undefined) {
128 this._table = matchTableClass.create(matchResponse["snippet"]);
129 cb(this._table);
130 };
131 }.bind(this)
Nils Diewald0e6992a2015-04-14 20:13:52 +0000132 );
133
134 /*
135 // Todo: Store the table as a hash of the focus
136 return null;
137 */
138 },
Akronbd342982018-01-25 18:01:46 +0100139
140
141 getMeta : function (metaInfo, cb) {
142
143 },
Nils Diewald0e6992a2015-04-14 20:13:52 +0000144
145
146 /**
147 * Retrieve and parse snippet for tree representation
148 */
Akron0988d882017-11-10 16:13:12 +0100149 getTree : function (foundry, layer, type, cb) {
Nils Diewald0e6992a2015-04-14 20:13:52 +0000150 var focus = [];
151
152 // TODO: Support and cache multiple trees
153 KorAP.API.getMatchInfo(
Akrond67d45b2017-05-18 21:47:38 +0200154 this._match, {
155 'spans' : true,
156 'foundry' : foundry,
157 'layer' : layer
158 },
159 function (matchResponse) {
160 // Get snippet from match info
161 if (matchResponse["snippet"] !== undefined) {
162 // Todo: This should be cached somehow
Akronc56cf2d2016-11-09 22:02:38 +0100163
Akron0988d882017-11-10 16:13:12 +0100164 if (type === "spans") {
165 cb(matchTreeClass.create(matchResponse["snippet"]));
166 }
167 else if (type === "rels") {
168 cb(matchRelClass.create(matchResponse["snippet"]));
169 }
170
171 // Unknown tree type
172 else {
173 cb(null);
174 };
Akrond67d45b2017-05-18 21:47:38 +0200175 }
176 else {
177 cb(null);
178 };
179 }.bind(this)
Nils Diewald0e6992a2015-04-14 20:13:52 +0000180 );
181 },
182
183 /**
184 * Destroy this match information view.
185 */
186 destroy : function () {
187
188 // Remove circular reference
Akron8b592d42018-01-26 18:33:06 +0100189 /*
Nils Diewald0e6992a2015-04-14 20:13:52 +0000190 if (this._treeMenu !== undefined)
Akron99713ef2017-06-28 18:19:28 +0200191 delete this._treeMenu["info"];
Nils Diewald0e6992a2015-04-14 20:13:52 +0000192
193 this._treeMenu.destroy();
194 this._treeMenu = undefined;
Akron8b592d42018-01-26 18:33:06 +0100195 */
Nils Diewald0e6992a2015-04-14 20:13:52 +0000196 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
Akrone7679692018-01-26 12:06:33 +0100285 // Add meta information to match
Akronbd342982018-01-25 18:01:46 +0100286 addMeta : function () {
287 var matchmeta = document.createElement('div');
288 // matchRefClass.create();
289
290 // TODO: This is part of the getMeta!
291 var metaInfo = this._match.element().getAttribute('data-info');
292
293 if (metaInfo)
294 metaInfo = JSON.parse(metaInfo);
295
296 // There is metainfo
297 if (metaInfo) {
298
299 // Add metainfo to matchview
300 var metaElem = matchRefClass.create(this._match).element(metaInfo);
Akrone7679692018-01-26 12:06:33 +0100301 var elem = this.element();
Akronbd342982018-01-25 18:01:46 +0100302
Akrone7679692018-01-26 12:06:33 +0100303 elem.insertBefore(
304 metaElem,
305 elem.firstChild
306 );
Akronbd342982018-01-25 18:01:46 +0100307 };
308 },
309
310 // Add table
311 addTable : function () {
312
313 var info = this.element();
Nils Diewald0e6992a2015-04-14 20:13:52 +0000314
315 // Append default table
316 var matchtable = document.createElement('div');
Nils Diewald0ec142f2015-05-05 00:29:23 +0000317 matchtable.classList.add('matchtable', 'loading');
Nils Diewald0e6992a2015-04-14 20:13:52 +0000318 info.appendChild(matchtable);
319
320 // Create the table asynchronous
321 this.getTable(undefined, function (table) {
Akron3bb91bc2016-12-02 16:43:17 +0100322
Akrond67d45b2017-05-18 21:47:38 +0200323 if (table !== null) {
Akron3bb91bc2016-12-02 16:43:17 +0100324 matchtable.appendChild(table.element());
325 };
Akron515851a2017-05-02 12:53:17 +0200326 matchtable.classList.remove('loading');
Akron99713ef2017-06-28 18:19:28 +0200327
328 // Add query creator
Akrone8ea0002017-06-28 18:51:52 +0200329 this._matchCreator = matchQueryCreator.create(info);
Nils Diewald0e6992a2015-04-14 20:13:52 +0000330 });
331
Akron8b592d42018-01-26 18:33:06 +0100332 // info.appendChild(this.addTreeMenu());
Akronbd342982018-01-25 18:01:46 +0100333 },
334
335 /**
336 * Create match information view.
337 */
338 element : function () {
339
340 if (this._element !== undefined)
341 return this._element;
342
343 // Create info table
344 var info = document.createElement('div');
345 info.classList.add('matchinfo');
Nils Diewald0e6992a2015-04-14 20:13:52 +0000346
347 this._element = info;
348
Akronbd342982018-01-25 18:01:46 +0100349 return this._element;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000350 }
351 };
352});