blob: ad9a5b3dcda2ea586770a0df4001405d45bf6eec [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
Akron52ed22d2018-07-11 17:05:19 +020014 'match/treeitem',
Akron13448c22018-07-10 13:05:46 +020015 'buttongroup',
Akron52ed22d2018-07-11 17:05:19 +020016 'buttongroup/menu',
Akron8b592d42018-01-26 18:33:06 +010017 'util'
Akron52ed22d2018-07-11 17:05:19 +020018], function (infoClass,treeItemClass,buttonGroupClass,buttonGroupMenuClass) { //, refClass) {
Nils Diewald4f6521a2015-03-20 21:30:13 +000019
Nils Diewald6e43ffd2015-03-25 18:55:39 +000020 // Localization values
Akron0b489ad2018-02-02 16:49:32 +010021 const loc = KorAP.Locale;
Akron24866cf2018-01-23 20:22:01 +010022 loc.SHOWINFO = loc.SHOWINFO || 'Show information';
Akrond5436a42018-02-09 11:09:16 +010023 loc.ADDTREE = loc.ADDTREE || 'Relations';
24 loc.SHOWANNO = loc.SHOWANNO || 'Tokens';
Akron24866cf2018-01-23 20:22:01 +010025 loc.CLOSE = loc.CLOSE || 'Close';
Akrond5436a42018-02-09 11:09:16 +010026 loc.SHOW_META = loc.SHOW_META || 'Metadata';
Nils Diewald0e6992a2015-04-14 20:13:52 +000027
Akron0a6768f2016-07-13 18:00:43 +020028 // 'corpusID', 'docID', 'textID'
Akron0b489ad2018-02-02 16:49:32 +010029 const _matchTerms = ['textSigle', 'matchID', 'available'];
30
31 const d = document;
Nils Diewalda297f062015-04-02 00:23:46 +000032
33 /**
34 * Match object
35 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000036 return {
Nils Diewalde8518f82015-03-18 22:41:49 +000037
38 /**
39 * Create a new annotation object.
40 * Expects an array of available foundry/layer=type terms.
41 * Supported types are 'spans', 'tokens' and 'rels'.
42 */
Nils Diewalda297f062015-04-02 00:23:46 +000043 create : function (match) {
Nils Diewald0e6992a2015-04-14 20:13:52 +000044 return Object.create(this)._init(match);
Nils Diewalde8518f82015-03-18 22:41:49 +000045 },
46
Nils Diewald7c8ced22015-04-15 19:21:00 +000047
Nils Diewald6e43ffd2015-03-25 18:55:39 +000048 /**
Nils Diewalda297f062015-04-02 00:23:46 +000049 * Initialize match.
Nils Diewald6e43ffd2015-03-25 18:55:39 +000050 */
Nils Diewalda297f062015-04-02 00:23:46 +000051 _init : function (match) {
52 this._element = null;
Nils Diewald6e43ffd2015-03-25 18:55:39 +000053
Nils Diewalda297f062015-04-02 00:23:46 +000054 // No match defined
55 if (arguments.length < 1 ||
Akron19d97fe2016-09-06 20:47:05 +020056 match === null ||
57 match === undefined) {
58 throw new Error('Missing parameters');
Nils Diewalda297f062015-04-02 00:23:46 +000059 }
Nils Diewald6e43ffd2015-03-25 18:55:39 +000060
Nils Diewalda297f062015-04-02 00:23:46 +000061 // Match defined as a node
62 else if (match instanceof Node) {
Akron19d97fe2016-09-06 20:47:05 +020063 this._element = match;
Nils Diewald6e43ffd2015-03-25 18:55:39 +000064
Akron19d97fe2016-09-06 20:47:05 +020065 // Circular reference !!
66 match["_match"] = this;
Nils Diewalda297f062015-04-02 00:23:46 +000067
Akron19d97fe2016-09-06 20:47:05 +020068 /*
69 this.corpusID = match.getAttribute('data-corpus-id'),
70 this.docID = match.getAttribute('data-doc-id'),
71 this.textID = match.getAttribute('data-text-id'),
72 */
73 if (match.hasAttribute('data-text-sigle')) {
74 this.textSigle = match.getAttribute('data-text-sigle')
75 }
76 else {
77 this.textSigle = match.getAttribute('data-corpus-id') +
78 '/' +
79 match.getAttribute('data-doc-id') +
80 '/' +
81 match.getAttribute('data-text-id');
82 };
Akron0a6768f2016-07-13 18:00:43 +020083
Akron19d97fe2016-09-06 20:47:05 +020084 this.matchID = match.getAttribute('data-match-id');
Nils Diewalda297f062015-04-02 00:23:46 +000085
Akron19d97fe2016-09-06 20:47:05 +020086 // List of available annotations
87 this.available = match.getAttribute('data-available-info').split(' ');
Nils Diewalda297f062015-04-02 00:23:46 +000088 }
89
90 // Match as an object
91 else {
92
Akron19d97fe2016-09-06 20:47:05 +020093 // Iterate over allowed match terms
94 for (var i in _matchTerms) {
95 var term = _matchTerms[i];
96 this[term] = match[term] !== undefined ? match[term] : undefined;
97 };
Nils Diewalda297f062015-04-02 00:23:46 +000098 };
Nils Diewald0e6992a2015-04-14 20:13:52 +000099
Nils Diewald7c8ced22015-04-15 19:21:00 +0000100 this._avail = {
Akron19d97fe2016-09-06 20:47:05 +0200101 tokens : [],
102 spans : [],
103 rels : []
Nils Diewalde8518f82015-03-18 22:41:49 +0000104 };
Nils Diewalda297f062015-04-02 00:23:46 +0000105
106 // Iterate over info layers
107 for (var i = 0; i < this.available.length; i++) {
Akron19d97fe2016-09-06 20:47:05 +0200108 var term = this.available[i];
Nils Diewalda297f062015-04-02 00:23:46 +0000109
Akron19d97fe2016-09-06 20:47:05 +0200110 // Create info layer objects
111 try {
112 var layer = require('match/infolayer').create(term);
113 this._avail[layer.type].push(layer);
114 }
115 catch (e) {
116 continue;
117 };
Nils Diewalde8518f82015-03-18 22:41:49 +0000118 };
Akron3a4a08e2017-05-23 22:34:18 +0200119
Nils Diewalde8518f82015-03-18 22:41:49 +0000120 return this;
121 },
122
Nils Diewalde8518f82015-03-18 22:41:49 +0000123 /**
124 * Return a list of parseable tree annotations.
125 */
126 getSpans : function () {
Nils Diewald7c8ced22015-04-15 19:21:00 +0000127 return this._avail.spans;
Nils Diewalde8518f82015-03-18 22:41:49 +0000128 },
129
130
131 /**
132 * Return a list of parseable token annotations.
133 */
134 getTokens : function () {
Nils Diewald7c8ced22015-04-15 19:21:00 +0000135 return this._avail.tokens;
Nils Diewalde8518f82015-03-18 22:41:49 +0000136 },
137
138
139 /**
140 * Return a list of parseable relation annotations.
141 */
142 getRels : function () {
Nils Diewald7c8ced22015-04-15 19:21:00 +0000143 return this._avail.rels;
Nils Diewalde8518f82015-03-18 22:41:49 +0000144 },
145
Nils Diewald7c8ced22015-04-15 19:21:00 +0000146
Nils Diewalda297f062015-04-02 00:23:46 +0000147 /**
148 * Open match
149 */
150 open : function () {
151
152 // Add actions unless it's already activated
153 var element = this._element;
154
155 // There is an element to open
156 if (this._element === undefined || this._element === null)
Akron19d97fe2016-09-06 20:47:05 +0200157 return false;
Nils Diewalda297f062015-04-02 00:23:46 +0000158
159 // The element is already opened
160 if (element.classList.contains('active'))
Akron19d97fe2016-09-06 20:47:05 +0200161 return false;
Nils Diewalda297f062015-04-02 00:23:46 +0000162
163 // Add active class to element
164 element.classList.add('active');
165
Nils Diewald7c8ced22015-04-15 19:21:00 +0000166 // Already there
167 if (element.classList.contains('action'))
Akron19d97fe2016-09-06 20:47:05 +0200168 return true;
Nils Diewald7c8ced22015-04-15 19:21:00 +0000169
Nils Diewalda297f062015-04-02 00:23:46 +0000170 // Create action buttons
Akron0b489ad2018-02-02 16:49:32 +0100171 var ul = d.createElement('ul');
Nils Diewalda297f062015-04-02 00:23:46 +0000172 ul.classList.add('action', 'right');
Nils Diewalda297f062015-04-02 00:23:46 +0000173
Nils Diewald7c8ced22015-04-15 19:21:00 +0000174 element.appendChild(ul);
175 element.classList.add('action');
176
177 // Todo: Open in new frame
Nils Diewalda297f062015-04-02 00:23:46 +0000178
179 // Add close button
Akron0b489ad2018-02-02 16:49:32 +0100180 var close = d.createElement('li');
181 close.addE('span').addT(loc.CLOSE);
Nils Diewalda297f062015-04-02 00:23:46 +0000182 close.classList.add('close');
183 close.setAttribute('title', loc.CLOSE);
Nils Diewald0e6992a2015-04-14 20:13:52 +0000184
Nils Diewalda297f062015-04-02 00:23:46 +0000185 var that = this;
186
Akron537bc522018-07-13 19:06:27 +0200187 // TODO:
188 // Introduce panel object here!
189
Akron24866cf2018-01-23 20:22:01 +0100190 // Add meta button
191 var refLine = element.querySelector("p.ref");
192
Akron0b489ad2018-02-02 16:49:32 +0100193 // No reference found
Akron151bc872018-02-02 14:04:15 +0100194 if (!refLine)
195 return;
Akron0ad7cd22018-02-08 18:03:06 +0100196
Akron4d926f12018-07-16 15:30:25 +0200197 var btns = buttonGroupClass.create(['action', 'bottom','button-panel']);
Akron8b592d42018-01-26 18:33:06 +0100198
Akron13448c22018-07-10 13:05:46 +0200199 // Add meta button
200 btns.add(
201 loc.SHOW_META, ['meta'], function (e) {
Akron151bc872018-02-02 14:04:15 +0100202 that.info().showMeta();
203 }
204 );
Akron8b592d42018-01-26 18:33:06 +0100205
Akron13448c22018-07-10 13:05:46 +0200206 // Add token annotation button
207 btns.add(
208 loc.SHOWANNO, ['info'], function (e) {
Akron151bc872018-02-02 14:04:15 +0100209 that.info().showTable();
210 }
211 );
Akron24866cf2018-01-23 20:22:01 +0100212
Akron13448c22018-07-10 13:05:46 +0200213 // Add tree view button
214 btns.add(
215 loc.ADDTREE, ['tree'], function (e) {
Akron151bc872018-02-02 14:04:15 +0100216 if (KorAP.TreeMenu === undefined) {
Akron52ed22d2018-07-11 17:05:19 +0200217 KorAP.TreeMenu = buttonGroupMenuClass.create([], treeItemClass);
Akron1801c5c2018-07-16 18:15:48 +0200218 KorAP.TreeMenu.element().setAttribute('id', 'treeMenu');
Akron151bc872018-02-02 14:04:15 +0100219 };
Akron8b592d42018-01-26 18:33:06 +0100220
Akron151bc872018-02-02 14:04:15 +0100221 var tm = KorAP.TreeMenu;
Akron8b592d42018-01-26 18:33:06 +0100222
Akron151bc872018-02-02 14:04:15 +0100223 // Reread list
224 tm.info(that.info());
225 tm.readItems(that.treeMenuList());
Akroneaba63e2018-01-26 19:49:30 +0100226
Akron151bc872018-02-02 14:04:15 +0100227 // Reposition and show menu
Akron151bc872018-02-02 14:04:15 +0100228 tm.show();
Akron52ed22d2018-07-11 17:05:19 +0200229 tm.button(this);
Akron151bc872018-02-02 14:04:15 +0100230 tm.focus();
231 }
232 );
Akron24866cf2018-01-23 20:22:01 +0100233
Akron13448c22018-07-10 13:05:46 +0200234
235 // Insert before reference line
236 refLine.insertBefore(
237 btns.element(),
238 refLine.firstChild
239 );
240
241
Nils Diewalda297f062015-04-02 00:23:46 +0000242 // Close match
243 close.addEventListener('click', function (e) {
Akron19d97fe2016-09-06 20:47:05 +0200244 e.halt();
245 that.close()
Nils Diewalda297f062015-04-02 00:23:46 +0000246 });
247
Nils Diewalda297f062015-04-02 00:23:46 +0000248 ul.appendChild(close);
Nils Diewalda297f062015-04-02 00:23:46 +0000249
250 return true;
251 },
252
Akron8c468a12016-11-13 23:57:41 +0100253
Akron6a535d42015-08-26 20:16:58 +0200254 // Todo: Test toggle
255 toggle : function () {
256 if (this._element.classList.contains('active'))
Akron19d97fe2016-09-06 20:47:05 +0200257 this.close();
Akron6a535d42015-08-26 20:16:58 +0200258 else
Akron19d97fe2016-09-06 20:47:05 +0200259 this.open();
Akron6a535d42015-08-26 20:16:58 +0200260 },
261
Nils Diewald7c8ced22015-04-15 19:21:00 +0000262
Nils Diewald8bc7e412015-03-19 22:08:27 +0000263 /**
Nils Diewalda297f062015-04-02 00:23:46 +0000264 * Close info view
265 */
266 close : function () {
267 this._element.classList.remove('active');
Akron151bc872018-02-02 14:04:15 +0100268 /*
269 if (this._info !== undefined) {
270 this._info.destroy();
271 };
272 */
Nils Diewalda297f062015-04-02 00:23:46 +0000273 },
274
275
Nils Diewalda297f062015-04-02 00:23:46 +0000276 /**
Akron151bc872018-02-02 14:04:15 +0100277 * Get and open associated match infos.
Nils Diewalda297f062015-04-02 00:23:46 +0000278 */
279 info : function () {
280
Akron537bc522018-07-13 19:06:27 +0200281 // TODO:
282 // Rename info() to panel()
283
Nils Diewalda297f062015-04-02 00:23:46 +0000284 // Create match info
285 if (this._info === undefined)
Akron19d97fe2016-09-06 20:47:05 +0200286 this._info = infoClass.create(this);
Nils Diewalda297f062015-04-02 00:23:46 +0000287
288 // There is an element to append
289 if (this._element === undefined ||
Akron19d97fe2016-09-06 20:47:05 +0200290 this._element === null)
291 return this._info;
Nils Diewald7c8ced22015-04-15 19:21:00 +0000292
Nils Diewalda297f062015-04-02 00:23:46 +0000293 // Info is already activated
Nils Diewald5c5a7472015-04-02 22:13:38 +0000294 if (this._info._element !== undefined)
Akron19d97fe2016-09-06 20:47:05 +0200295 return this._info;
Nils Diewalda297f062015-04-02 00:23:46 +0000296
Akronbd342982018-01-25 18:01:46 +0100297 var refLine = this._element.querySelector("p.ref");
298 this._element.insertBefore(
299 this._info.element(),
300 refLine
301 );
302
Nils Diewalda297f062015-04-02 00:23:46 +0000303 return this._info;
304 },
305
Akron8b592d42018-01-26 18:33:06 +0100306
Akron151bc872018-02-02 14:04:15 +0100307 // Return tree menu list
Akroneaba63e2018-01-26 19:49:30 +0100308 treeMenuList : function () {
309
310 if (this._menuList)
311 return this._menuList;
Akron8b592d42018-01-26 18:33:06 +0100312
313 // Join spans and relations
314 var treeLayers = []
315 var spans = this.getSpans();
316 var rels = this.getRels();
317 var i;
318 for (i in spans) {
319 treeLayers.push(spans[i]);
320 };
321 for (i in rels) {
322 treeLayers.push(rels[i]);
323 };
324
325 // Get spans
326 treeLayers = treeLayers.sort(
327 function (a, b) {
328 if (a.foundry < b.foundry) {
329 return -1;
330 }
331 else if (a.foundry > b.foundry) {
332 return 1;
333 }
334 else if (a.layer < b.layer) {
335 return -1;
336 }
337 else if (a.layer > b.layer) {
338 return 1;
339 };
340 return 0;
341 });
342
343 var menuList = [];
344
345 // Show tree views
346 for (var i = 0; i < treeLayers.length; i++) {
347 var span = treeLayers[i];
348
349 // Add foundry/layer to menu list
350 menuList.push([
351 span.foundry + '/' + span.layer,
352 span.foundry,
353 span.layer,
354 span.type
355 ]);
356 };
357
358 // Create tree menu
Akroneaba63e2018-01-26 19:49:30 +0100359 this._menuList = menuList;
360 return menuList;
Akron8b592d42018-01-26 18:33:06 +0100361 },
362
Nils Diewald7c8ced22015-04-15 19:21:00 +0000363
Nils Diewalda297f062015-04-02 00:23:46 +0000364 /**
365 * Get match element.
366 */
367 element : function () {
Nils Diewald7c8ced22015-04-15 19:21:00 +0000368 return this._element; // May be null
Nils Diewalda297f062015-04-02 00:23:46 +0000369 }
370 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000371});