blob: 63fa55a45c2c1b28ed250ebbd449f7f7c8712cb3 [file] [log] [blame]
Nils Diewalde8518f82015-03-18 22:41:49 +00001/**
Nils Diewalda297f062015-04-02 00:23:46 +00002 * Get information on matches,
3 * generate annotation tables and trees.
Nils Diewalde8518f82015-03-18 22:41:49 +00004 *
5 * @author Nils Diewald
6 */
7/*
Nils Diewald6e43ffd2015-03-25 18:55:39 +00008 * - Highlight (at least mark as bold) the match
9 * - Scroll to match vertically per default
Akron02360e42016-06-07 13:41:12 +020010 * - A click on a table field and a tree node should at the field description to the fragments list.
Nils Diewalde8518f82015-03-18 22:41:49 +000011 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000012define([
Akron24866cf2018-01-23 20:22:01 +010013 'match/info', // rename to anno
Akron8b592d42018-01-26 18:33:06 +010014 'match/treemenu',
15 'util'
16], function (infoClass,matchTreeMenuClass) { //, refClass) {
Nils Diewald4f6521a2015-03-20 21:30:13 +000017
Nils Diewald6e43ffd2015-03-25 18:55:39 +000018 // Localization values
Akron0b489ad2018-02-02 16:49:32 +010019 const loc = KorAP.Locale;
Akron24866cf2018-01-23 20:22:01 +010020 loc.ADDTREE = loc.ADDTREE || 'Add tree view';
21 loc.SHOWINFO = loc.SHOWINFO || 'Show information';
22 loc.CLOSE = loc.CLOSE || 'Close';
23 loc.SHOW_META = loc.SHOW_META || 'Show metadata';
Nils Diewald0e6992a2015-04-14 20:13:52 +000024
Akron0a6768f2016-07-13 18:00:43 +020025 // 'corpusID', 'docID', 'textID'
Akron0b489ad2018-02-02 16:49:32 +010026 const _matchTerms = ['textSigle', 'matchID', 'available'];
27
28 const d = document;
Nils Diewalda297f062015-04-02 00:23:46 +000029
30 /**
31 * Match object
32 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000033 return {
Nils Diewalde8518f82015-03-18 22:41:49 +000034
35 /**
36 * Create a new annotation object.
37 * Expects an array of available foundry/layer=type terms.
38 * Supported types are 'spans', 'tokens' and 'rels'.
39 */
Nils Diewalda297f062015-04-02 00:23:46 +000040 create : function (match) {
Nils Diewald0e6992a2015-04-14 20:13:52 +000041 return Object.create(this)._init(match);
Nils Diewalde8518f82015-03-18 22:41:49 +000042 },
43
Nils Diewald7c8ced22015-04-15 19:21:00 +000044
Nils Diewald6e43ffd2015-03-25 18:55:39 +000045 /**
Nils Diewalda297f062015-04-02 00:23:46 +000046 * Initialize match.
Nils Diewald6e43ffd2015-03-25 18:55:39 +000047 */
Nils Diewalda297f062015-04-02 00:23:46 +000048 _init : function (match) {
49 this._element = null;
Nils Diewald6e43ffd2015-03-25 18:55:39 +000050
Nils Diewalda297f062015-04-02 00:23:46 +000051 // No match defined
52 if (arguments.length < 1 ||
Akron19d97fe2016-09-06 20:47:05 +020053 match === null ||
54 match === undefined) {
55 throw new Error('Missing parameters');
Nils Diewalda297f062015-04-02 00:23:46 +000056 }
Nils Diewald6e43ffd2015-03-25 18:55:39 +000057
Nils Diewalda297f062015-04-02 00:23:46 +000058 // Match defined as a node
59 else if (match instanceof Node) {
Akron19d97fe2016-09-06 20:47:05 +020060 this._element = match;
Nils Diewald6e43ffd2015-03-25 18:55:39 +000061
Akron19d97fe2016-09-06 20:47:05 +020062 // Circular reference !!
63 match["_match"] = this;
Nils Diewalda297f062015-04-02 00:23:46 +000064
Akron19d97fe2016-09-06 20:47:05 +020065 /*
66 this.corpusID = match.getAttribute('data-corpus-id'),
67 this.docID = match.getAttribute('data-doc-id'),
68 this.textID = match.getAttribute('data-text-id'),
69 */
70 if (match.hasAttribute('data-text-sigle')) {
71 this.textSigle = match.getAttribute('data-text-sigle')
72 }
73 else {
74 this.textSigle = match.getAttribute('data-corpus-id') +
75 '/' +
76 match.getAttribute('data-doc-id') +
77 '/' +
78 match.getAttribute('data-text-id');
79 };
Akron0a6768f2016-07-13 18:00:43 +020080
Akron19d97fe2016-09-06 20:47:05 +020081 this.matchID = match.getAttribute('data-match-id');
Nils Diewalda297f062015-04-02 00:23:46 +000082
Akron19d97fe2016-09-06 20:47:05 +020083 // List of available annotations
84 this.available = match.getAttribute('data-available-info').split(' ');
Nils Diewalda297f062015-04-02 00:23:46 +000085 }
86
87 // Match as an object
88 else {
89
Akron19d97fe2016-09-06 20:47:05 +020090 // Iterate over allowed match terms
91 for (var i in _matchTerms) {
92 var term = _matchTerms[i];
93 this[term] = match[term] !== undefined ? match[term] : undefined;
94 };
Nils Diewalda297f062015-04-02 00:23:46 +000095 };
Nils Diewald0e6992a2015-04-14 20:13:52 +000096
Nils Diewald7c8ced22015-04-15 19:21:00 +000097 this._avail = {
Akron19d97fe2016-09-06 20:47:05 +020098 tokens : [],
99 spans : [],
100 rels : []
Nils Diewalde8518f82015-03-18 22:41:49 +0000101 };
Nils Diewalda297f062015-04-02 00:23:46 +0000102
103 // Iterate over info layers
104 for (var i = 0; i < this.available.length; i++) {
Akron19d97fe2016-09-06 20:47:05 +0200105 var term = this.available[i];
Nils Diewalda297f062015-04-02 00:23:46 +0000106
Akron19d97fe2016-09-06 20:47:05 +0200107 // Create info layer objects
108 try {
109 var layer = require('match/infolayer').create(term);
110 this._avail[layer.type].push(layer);
111 }
112 catch (e) {
113 continue;
114 };
Nils Diewalde8518f82015-03-18 22:41:49 +0000115 };
Akron3a4a08e2017-05-23 22:34:18 +0200116
Nils Diewalde8518f82015-03-18 22:41:49 +0000117 return this;
118 },
119
Nils Diewalde8518f82015-03-18 22:41:49 +0000120 /**
121 * Return a list of parseable tree annotations.
122 */
123 getSpans : function () {
Nils Diewald7c8ced22015-04-15 19:21:00 +0000124 return this._avail.spans;
Nils Diewalde8518f82015-03-18 22:41:49 +0000125 },
126
127
128 /**
129 * Return a list of parseable token annotations.
130 */
131 getTokens : function () {
Nils Diewald7c8ced22015-04-15 19:21:00 +0000132 return this._avail.tokens;
Nils Diewalde8518f82015-03-18 22:41:49 +0000133 },
134
135
136 /**
137 * Return a list of parseable relation annotations.
138 */
139 getRels : function () {
Nils Diewald7c8ced22015-04-15 19:21:00 +0000140 return this._avail.rels;
Nils Diewalde8518f82015-03-18 22:41:49 +0000141 },
142
Nils Diewald7c8ced22015-04-15 19:21:00 +0000143
Nils Diewalda297f062015-04-02 00:23:46 +0000144 /**
145 * Open match
146 */
147 open : function () {
148
149 // Add actions unless it's already activated
150 var element = this._element;
151
152 // There is an element to open
153 if (this._element === undefined || this._element === null)
Akron19d97fe2016-09-06 20:47:05 +0200154 return false;
Nils Diewalda297f062015-04-02 00:23:46 +0000155
156 // The element is already opened
157 if (element.classList.contains('active'))
Akron19d97fe2016-09-06 20:47:05 +0200158 return false;
Nils Diewalda297f062015-04-02 00:23:46 +0000159
160 // Add active class to element
161 element.classList.add('active');
162
Nils Diewald7c8ced22015-04-15 19:21:00 +0000163 // Already there
164 if (element.classList.contains('action'))
Akron19d97fe2016-09-06 20:47:05 +0200165 return true;
Nils Diewald7c8ced22015-04-15 19:21:00 +0000166
Nils Diewalda297f062015-04-02 00:23:46 +0000167 // Create action buttons
Akron0b489ad2018-02-02 16:49:32 +0100168 var ul = d.createElement('ul');
Nils Diewalda297f062015-04-02 00:23:46 +0000169 ul.classList.add('action', 'right');
Nils Diewalda297f062015-04-02 00:23:46 +0000170
Nils Diewald7c8ced22015-04-15 19:21:00 +0000171 element.appendChild(ul);
172 element.classList.add('action');
173
174 // Todo: Open in new frame
Nils Diewalda297f062015-04-02 00:23:46 +0000175
176 // Add close button
Akron0b489ad2018-02-02 16:49:32 +0100177 var close = d.createElement('li');
178 close.addE('span').addT(loc.CLOSE);
Nils Diewalda297f062015-04-02 00:23:46 +0000179 close.classList.add('close');
180 close.setAttribute('title', loc.CLOSE);
Nils Diewald0e6992a2015-04-14 20:13:52 +0000181
Nils Diewalda297f062015-04-02 00:23:46 +0000182 var that = this;
183
Akron24866cf2018-01-23 20:22:01 +0100184 // Add meta button
185 var refLine = element.querySelector("p.ref");
186
Akron0b489ad2018-02-02 16:49:32 +0100187 // No reference found
Akron151bc872018-02-02 14:04:15 +0100188 if (!refLine)
189 return;
190
Akron0b489ad2018-02-02 16:49:32 +0100191 var ops = d.createElement('div');
Akron151bc872018-02-02 14:04:15 +0100192 ops.classList.add('action', 'bottom', 'button-group');
193
Akron0b489ad2018-02-02 16:49:32 +0100194 var meta = ops.addE('span');
195 meta.addT('Meta');
Akron151bc872018-02-02 14:04:15 +0100196 meta.setAttribute('title', loc.SHOW_META);
197 meta.classList.add('meta');
Akron8b592d42018-01-26 18:33:06 +0100198
Akron0b489ad2018-02-02 16:49:32 +0100199 var info = ops.addE('span');
200 info.addT('Anno');
Akron151bc872018-02-02 14:04:15 +0100201 info.setAttribute('title', loc.SHOWINFO);
202 info.classList.add('info');
Akron8b592d42018-01-26 18:33:06 +0100203
Akron0b489ad2018-02-02 16:49:32 +0100204 var tree = ops.addE('span');
205 tree.addT('+ Tree');
Akron151bc872018-02-02 14:04:15 +0100206 tree.setAttribute('title', loc.ADDTREE);
207 tree.classList.add('tree');
Akron8b592d42018-01-26 18:33:06 +0100208
Akron151bc872018-02-02 14:04:15 +0100209 // Insert before reference line
210 refLine.insertBefore(
211 ops,
212 refLine.firstChild
213 );
Akron8b592d42018-01-26 18:33:06 +0100214
Akron151bc872018-02-02 14:04:15 +0100215 // Click on meta - add meta (unless already there)
216 meta.addEventListener(
217 'click', function (e) {
218 e.halt();
219 that.info().showMeta();
220 }
221 );
Akron8b592d42018-01-26 18:33:06 +0100222
Akron151bc872018-02-02 14:04:15 +0100223 // Click on token annotations - add token annotations (unless already there)
224 info.addEventListener(
225 'click', function (e) {
226 e.halt();
227 that.info().showTable();
228 }
229 );
Akron24866cf2018-01-23 20:22:01 +0100230
Akron151bc872018-02-02 14:04:15 +0100231 // Click to show tree menu
232 tree.addEventListener(
233 'click', function (e) {
234 e.halt();
Akron8b592d42018-01-26 18:33:06 +0100235
Akron151bc872018-02-02 14:04:15 +0100236 if (KorAP.TreeMenu === undefined) {
237 KorAP.TreeMenu = matchTreeMenuClass.create([]);
238 };
Akron8b592d42018-01-26 18:33:06 +0100239
Akron151bc872018-02-02 14:04:15 +0100240 var tm = KorAP.TreeMenu;
Akron8b592d42018-01-26 18:33:06 +0100241
Akron151bc872018-02-02 14:04:15 +0100242 // Reread list
243 tm.info(that.info());
244 tm.readItems(that.treeMenuList());
Akroneaba63e2018-01-26 19:49:30 +0100245
Akron151bc872018-02-02 14:04:15 +0100246 // Reposition and show menu
Akron151bc872018-02-02 14:04:15 +0100247 tm.show();
Akronc6967d72018-02-05 18:39:39 +0100248 tm.attachTo(this);
Akron151bc872018-02-02 14:04:15 +0100249 tm.focus();
250 }
251 );
Akron24866cf2018-01-23 20:22:01 +0100252
Nils Diewalda297f062015-04-02 00:23:46 +0000253 // Close match
254 close.addEventListener('click', function (e) {
Akron19d97fe2016-09-06 20:47:05 +0200255 e.halt();
256 that.close()
Nils Diewalda297f062015-04-02 00:23:46 +0000257 });
258
Nils Diewalda297f062015-04-02 00:23:46 +0000259 ul.appendChild(close);
Nils Diewalda297f062015-04-02 00:23:46 +0000260
261 return true;
262 },
263
Akron8c468a12016-11-13 23:57:41 +0100264
Akron6a535d42015-08-26 20:16:58 +0200265 // Todo: Test toggle
266 toggle : function () {
267 if (this._element.classList.contains('active'))
Akron19d97fe2016-09-06 20:47:05 +0200268 this.close();
Akron6a535d42015-08-26 20:16:58 +0200269 else
Akron19d97fe2016-09-06 20:47:05 +0200270 this.open();
Akron6a535d42015-08-26 20:16:58 +0200271 },
272
Nils Diewald7c8ced22015-04-15 19:21:00 +0000273
Nils Diewald8bc7e412015-03-19 22:08:27 +0000274 /**
Nils Diewalda297f062015-04-02 00:23:46 +0000275 * Close info view
276 */
277 close : function () {
278 this._element.classList.remove('active');
Akron151bc872018-02-02 14:04:15 +0100279 /*
280 if (this._info !== undefined) {
281 this._info.destroy();
282 };
283 */
Nils Diewalda297f062015-04-02 00:23:46 +0000284 },
285
286
Nils Diewalda297f062015-04-02 00:23:46 +0000287 /**
Akron151bc872018-02-02 14:04:15 +0100288 * Get and open associated match infos.
Nils Diewalda297f062015-04-02 00:23:46 +0000289 */
290 info : function () {
291
292 // Create match info
293 if (this._info === undefined)
Akron19d97fe2016-09-06 20:47:05 +0200294 this._info = infoClass.create(this);
Nils Diewalda297f062015-04-02 00:23:46 +0000295
296 // There is an element to append
297 if (this._element === undefined ||
Akron19d97fe2016-09-06 20:47:05 +0200298 this._element === null)
299 return this._info;
Nils Diewald7c8ced22015-04-15 19:21:00 +0000300
Nils Diewalda297f062015-04-02 00:23:46 +0000301 // Info is already activated
Nils Diewald5c5a7472015-04-02 22:13:38 +0000302 if (this._info._element !== undefined)
Akron19d97fe2016-09-06 20:47:05 +0200303 return this._info;
Nils Diewalda297f062015-04-02 00:23:46 +0000304
Akronbd342982018-01-25 18:01:46 +0100305 var refLine = this._element.querySelector("p.ref");
306 this._element.insertBefore(
307 this._info.element(),
308 refLine
309 );
310
Nils Diewalda297f062015-04-02 00:23:46 +0000311 return this._info;
312 },
313
Akron8b592d42018-01-26 18:33:06 +0100314
Akron151bc872018-02-02 14:04:15 +0100315 // Return tree menu list
Akroneaba63e2018-01-26 19:49:30 +0100316 treeMenuList : function () {
317
318 if (this._menuList)
319 return this._menuList;
Akron8b592d42018-01-26 18:33:06 +0100320
321 // Join spans and relations
322 var treeLayers = []
323 var spans = this.getSpans();
324 var rels = this.getRels();
325 var i;
326 for (i in spans) {
327 treeLayers.push(spans[i]);
328 };
329 for (i in rels) {
330 treeLayers.push(rels[i]);
331 };
332
333 // Get spans
334 treeLayers = treeLayers.sort(
335 function (a, b) {
336 if (a.foundry < b.foundry) {
337 return -1;
338 }
339 else if (a.foundry > b.foundry) {
340 return 1;
341 }
342 else if (a.layer < b.layer) {
343 return -1;
344 }
345 else if (a.layer > b.layer) {
346 return 1;
347 };
348 return 0;
349 });
350
351 var menuList = [];
352
353 // Show tree views
354 for (var i = 0; i < treeLayers.length; i++) {
355 var span = treeLayers[i];
356
357 // Add foundry/layer to menu list
358 menuList.push([
359 span.foundry + '/' + span.layer,
360 span.foundry,
361 span.layer,
362 span.type
363 ]);
364 };
365
366 // Create tree menu
Akroneaba63e2018-01-26 19:49:30 +0100367 this._menuList = menuList;
368 return menuList;
Akron8b592d42018-01-26 18:33:06 +0100369 },
370
Nils Diewald7c8ced22015-04-15 19:21:00 +0000371
Nils Diewalda297f062015-04-02 00:23:46 +0000372 /**
373 * Get match element.
374 */
375 element : function () {
Nils Diewald7c8ced22015-04-15 19:21:00 +0000376 return this._element; // May be null
Nils Diewalda297f062015-04-02 00:23:46 +0000377 }
378 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000379});