blob: 743fa2ca11c142f65ef85ca5a1e9ffd91de68694 [file] [log] [blame]
Nils Diewald0e6992a2015-04-14 20:13:52 +00001 /**
2 * Information about a match.
3 */
Nils Diewald7c8ced22015-04-15 19:21:00 +00004define([
5 'match/infolayer',
6 'match/table',
7 'match/tree',
8 'match/treemenu',
9 'util'
10], function (infoLayerClass,
Akron3bb91bc2016-12-02 16:43:17 +010011 matchTableClass,
12 matchTreeClass,
13 matchTreeMenuClass) {
14
Nils Diewald7148c6f2015-05-04 15:07:53 +000015 // Override
Nils Diewald0e6992a2015-04-14 20:13:52 +000016 KorAP.API.getMatchInfo = KorAP.API.getMatchInfo || function () {
17 KorAP.log(0, 'KorAP.API.getMatchInfo() not implemented')
18 return {};
19 };
20
21 var loc = KorAP.Locale;
22
Nils Diewald0e6992a2015-04-14 20:13:52 +000023 return {
Nils Diewald7148c6f2015-05-04 15:07:53 +000024
25 /**
26 * Create new match object
27 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000028 create : function (match) {
29 return Object.create(this)._init(match);
30 },
31
32 /**
33 * Initialize object
34 */
35 _init : function (match) {
36 this._match = match;
37 this.opened = false;
38 return this;
39 },
40
41 /**
42 * Get match object
43 */
44 match : function () {
45 return this._match;
46 },
47
Nils Diewald7148c6f2015-05-04 15:07:53 +000048
49 /**
50 * Open the information view,
51 * if closed, otherwise close.
52 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000053 toggle : function () {
Akron3bb91bc2016-12-02 16:43:17 +010054
Akron08b82d62016-12-05 15:06:05 +010055 var elem = this._match.element();
Akron3bb91bc2016-12-02 16:43:17 +010056
57 if (this.opened == true) {
58 elem.removeChild(
59 this.element()
60 );
61 this.opened = false;
Nils Diewald0e6992a2015-04-14 20:13:52 +000062 }
63 else {
Akron3bb91bc2016-12-02 16:43:17 +010064 // Append element to match
65 elem.appendChild(
66 this.element()
67 );
68 this.opened = true;
Nils Diewald0e6992a2015-04-14 20:13:52 +000069 };
70
71 return this.opened;
72 },
73
74
75 /**
Nils Diewald7148c6f2015-05-04 15:07:53 +000076 * Retrieve and parse snippet for table
77 * representation
Nils Diewald0e6992a2015-04-14 20:13:52 +000078 */
79 getTable : function (tokens, cb) {
80 var focus = [];
81
82 // Get all tokens
83 if (tokens === undefined) {
Akron3bb91bc2016-12-02 16:43:17 +010084 focus = this._match.getTokens();
Nils Diewald0e6992a2015-04-14 20:13:52 +000085 }
86
87 // Get only some tokens
88 else {
89
Akron3bb91bc2016-12-02 16:43:17 +010090 // Push newly to focus array
91 for (var i = 0; i < tokens.length; i++) {
92 var term = tokens[i];
93 try {
94 // Create info layer objects
95 var layer = infoLayerClass.create(term);
96 layer.type = "tokens";
97 focus.push(layer);
98 }
99 catch (e) {
100 continue;
101 };
102 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000103 };
104
105 // No tokens chosen
106 if (focus.length == 0)
Akron3bb91bc2016-12-02 16:43:17 +0100107 cb(null);
Nils Diewald0e6992a2015-04-14 20:13:52 +0000108
109 // Get info (may be cached)
Nils Diewald0e6992a2015-04-14 20:13:52 +0000110 KorAP.API.getMatchInfo(
Akron3bb91bc2016-12-02 16:43:17 +0100111 this._match,
112 { 'spans' : false, 'layer' : focus },
Nils Diewald0e6992a2015-04-14 20:13:52 +0000113
Akron3bb91bc2016-12-02 16:43:17 +0100114 // Callback for retrieval
115 function (matchResponse) {
116
Akron515851a2017-05-02 12:53:17 +0200117 if (matchResponse === undefined)
118 cb(null);
119
Akron3bb91bc2016-12-02 16:43:17 +0100120 // Get snippet from match info
121 if (matchResponse["snippet"] !== undefined) {
122 this._table = matchTableClass.create(matchResponse["snippet"]);
123 cb(this._table);
124 };
125 }.bind(this)
Nils Diewald0e6992a2015-04-14 20:13:52 +0000126 );
127
128 /*
129 // Todo: Store the table as a hash of the focus
130 return null;
131 */
132 },
133
134
135 /**
136 * Retrieve and parse snippet for tree representation
137 */
138 getTree : function (foundry, layer, cb) {
139 var focus = [];
140
141 // TODO: Support and cache multiple trees
142 KorAP.API.getMatchInfo(
Akronc56cf2d2016-11-09 22:02:38 +0100143 this._match, {
144 'spans' : true,
145 'foundry' : foundry,
146 'layer' : layer
147 },
148 function (matchResponse) {
149 // Get snippet from match info
150 if (matchResponse["snippet"] !== undefined) {
151 // Todo: This should be cached somehow
152
153 cb(matchTreeClass.create(matchResponse["snippet"]));
154 }
155 else {
156 cb(null);
157 };
158 }.bind(this)
Nils Diewald0e6992a2015-04-14 20:13:52 +0000159 );
160 },
161
162 /**
163 * Destroy this match information view.
164 */
165 destroy : function () {
166
167 // Remove circular reference
168 if (this._treeMenu !== undefined)
169 delete this._treeMenu["info"];
170
171 this._treeMenu.destroy();
172 this._treeMenu = undefined;
173 this._match = undefined;
174
175 // Element destroy
176 },
177
178 /**
179 * Add a new tree view to the list
180 */
181 addTree : function (foundry, layer, cb) {
182 var matchtree = document.createElement('div');
183 matchtree.classList.add('matchtree');
184
185 var h6 = matchtree.appendChild(document.createElement('h6'));
186 h6.appendChild(document.createElement('span'))
187 .appendChild(document.createTextNode(foundry));
188 h6.appendChild(document.createElement('span'))
189 .appendChild(document.createTextNode(layer));
190
191 var tree = matchtree.appendChild(
Akronc56cf2d2016-11-09 22:02:38 +0100192 document.createElement('div')
Nils Diewald0e6992a2015-04-14 20:13:52 +0000193 );
194
195 this._element.insertBefore(matchtree, this._element.lastChild);
196
Akronc56cf2d2016-11-09 22:02:38 +0100197 var actions = tree.appendChild(document.createElement('ul'));
198 actions.classList.add('action', 'image');
199 var close = actions.appendChild(document.createElement('li'));
200 close.className = 'close';
201 close.appendChild(document.createElement('span'));
Nils Diewald0e6992a2015-04-14 20:13:52 +0000202 close.addEventListener(
Akronc56cf2d2016-11-09 22:02:38 +0100203 'click', function (e) {
204 matchtree.parentNode.removeChild(matchtree);
205 e.halt();
206 }
Nils Diewald0e6992a2015-04-14 20:13:52 +0000207 );
208
Nils Diewald0ec142f2015-05-05 00:29:23 +0000209 tree.classList.add('loading');
210
Nils Diewald0e6992a2015-04-14 20:13:52 +0000211 // Get tree data async
212 this.getTree(foundry, layer, function (treeObj) {
Nils Diewald0ec142f2015-05-05 00:29:23 +0000213
Akronc56cf2d2016-11-09 22:02:38 +0100214 tree.classList.remove('loading');
Nils Diewald0ec142f2015-05-05 00:29:23 +0000215
Akronc56cf2d2016-11-09 22:02:38 +0100216 // Something went wrong - probably log!!!
Nils Diewald0ec142f2015-05-05 00:29:23 +0000217
Akronc56cf2d2016-11-09 22:02:38 +0100218 if (treeObj === null) {
219 tree.appendChild(document.createTextNode('No data available.'));
220 }
221 else {
222 tree.appendChild(treeObj.element());
223 // Reposition the view to the center
224 // (This may in a future release be a reposition
225 // to move the root into the center or the actual
226 // match)
227
228 var dl = document.createElement('li');
229 dl.className = 'download';
230 dl.addEventListener(
231 'click', function (e) {
232
233 var a = document.createElement('a');
234 a.setAttribute('href-lang', 'image/svg+xml');
235 a.setAttribute('href', 'data:image/svg+xml;base64,'+treeObj.toBase64());
236 a.setAttribute('download', 'tree.svg');
237 a.target = '_blank';
238
239 document.body.appendChild(a);
240 a.click();
241 document.body.removeChild(a)
242
243 e.halt();
244 }
245 );
246 actions.appendChild(dl);
247 treeObj.center();
248 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000249
Akronc56cf2d2016-11-09 22:02:38 +0100250 if (cb !== undefined)
251 cb(treeObj);
Nils Diewald0e6992a2015-04-14 20:13:52 +0000252 });
253 },
254
255 /**
256 * Create match information view.
257 */
258 element : function () {
259
260 if (this._element !== undefined)
Akronc56cf2d2016-11-09 22:02:38 +0100261 return this._element;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000262
263 // Create info table
264 var info = document.createElement('div');
265 info.classList.add('matchinfo');
266
267 // Append default table
268 var matchtable = document.createElement('div');
Nils Diewald0ec142f2015-05-05 00:29:23 +0000269 matchtable.classList.add('matchtable', 'loading');
Nils Diewald0e6992a2015-04-14 20:13:52 +0000270 info.appendChild(matchtable);
271
272 // Create the table asynchronous
273 this.getTable(undefined, function (table) {
Akron3bb91bc2016-12-02 16:43:17 +0100274
275 if (table !== null) {
Akron3bb91bc2016-12-02 16:43:17 +0100276 matchtable.appendChild(table.element());
277 };
Akron515851a2017-05-02 12:53:17 +0200278 matchtable.classList.remove('loading');
Nils Diewald0e6992a2015-04-14 20:13:52 +0000279 });
280
281 // Get spans
282 var spanLayers = this._match.getSpans().sort(
Akron3bb91bc2016-12-02 16:43:17 +0100283 function (a, b) {
284 if (a.foundry < b.foundry) {
285 return -1;
286 }
287 else if (a.foundry > b.foundry) {
288 return 1;
289 }
290 else if (a.layer < b.layer) {
291 return -1;
292 }
293 else if (a.layer > b.layer) {
294 return 1;
295 };
296 return 0;
297 });
Nils Diewald0e6992a2015-04-14 20:13:52 +0000298
299 var menuList = [];
300
301 // Show tree views
302 for (var i = 0; i < spanLayers.length; i++) {
Akron3bb91bc2016-12-02 16:43:17 +0100303 var span = spanLayers[i];
304
305 // Add foundry/layer to menu list
306 menuList.push([
307 span.foundry + '/' + span.layer,
308 span.foundry,
309 span.layer
310 ]);
Nils Diewald0e6992a2015-04-14 20:13:52 +0000311 };
312
313 // Create tree menu
314 var treemenu = this.treeMenu(menuList);
315 var span = info.appendChild(document.createElement('p'));
316 span.classList.add('addtree');
317 span.appendChild(document.createTextNode(loc.ADDTREE));
318
319 var treeElement = treemenu.element();
320 span.appendChild(treeElement);
321
322 span.addEventListener('click', function (e) {
Akron3bb91bc2016-12-02 16:43:17 +0100323 treemenu.show();
324 treemenu.focus();
Nils Diewald0e6992a2015-04-14 20:13:52 +0000325 });
326
327 this._element = info;
328
329 return info;
330 },
331
332
333 /**
334 * Get tree menu.
335 * There is only one menu rendered
336 * - no matter how many trees exist
337 */
338 treeMenu : function (list) {
339 if (this._treeMenu !== undefined)
Akron3bb91bc2016-12-02 16:43:17 +0100340 return this._treeMenu;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000341
342 return this._treeMenu = matchTreeMenuClass.create(this, list);
343 }
344 };
345});