blob: 9d1922ad389b0e66f9e0a91c72660cc2011317fc [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,
11 matchTableClass,
12 matchTreeClass,
13 matchTreeMenuClass) {
Nils Diewald0e6992a2015-04-14 20:13:52 +000014
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 () {
54 if (this.opened == true) {
55 this._match.element().children[0].removeChild(
56 this.element()
57 );
58 this.opened = false;
59 }
60 else {
61 // Append element to match
62 this._match.element().children[0].appendChild(
63 this.element()
64 );
65 this.opened = true;
66 };
67
68 return this.opened;
69 },
70
71
72 /**
Nils Diewald7148c6f2015-05-04 15:07:53 +000073 * Retrieve and parse snippet for table
74 * representation
Nils Diewald0e6992a2015-04-14 20:13:52 +000075 */
76 getTable : function (tokens, cb) {
77 var focus = [];
78
79 // Get all tokens
80 if (tokens === undefined) {
81 focus = this._match.getTokens();
82 }
83
84 // Get only some tokens
85 else {
86
87 // Push newly to focus array
88 for (var i = 0; i < tokens.length; i++) {
89 var term = tokens[i];
90 try {
91 // Create info layer objects
92 var layer = infoLayerClass.create(term);
93 layer.type = "tokens";
94 focus.push(layer);
95 }
96 catch (e) {
97 continue;
98 };
99 };
100 };
101
102 // No tokens chosen
103 if (focus.length == 0)
104 cb(null);
105
106 // Get info (may be cached)
Nils Diewald0e6992a2015-04-14 20:13:52 +0000107 KorAP.API.getMatchInfo(
108 this._match,
109 { 'spans' : false, 'layer' : focus },
110
111 // Callback for retrieval
112 function (matchResponse) {
113 // Get snippet from match info
114 if (matchResponse["snippet"] !== undefined) {
115 this._table = matchTableClass.create(matchResponse["snippet"]);
116 cb(this._table);
117 };
118 }.bind(this)
119 );
120
121 /*
122 // Todo: Store the table as a hash of the focus
123 return null;
124 */
125 },
126
127
128 /**
129 * Retrieve and parse snippet for tree representation
130 */
131 getTree : function (foundry, layer, cb) {
132 var focus = [];
133
134 // TODO: Support and cache multiple trees
135 KorAP.API.getMatchInfo(
136 this._match, {
137 'spans' : true,
138 'foundry' : foundry,
139 'layer' : layer
140 },
141 function (matchResponse) {
142 // Get snippet from match info
143 if (matchResponse["snippet"] !== undefined) {
144 // Todo: This should be cached somehow
145 cb(matchTreeClass.create(matchResponse["snippet"]));
146 }
147 else {
148 cb(null);
149 };
150 }.bind(this)
151 );
152 },
153
154 /**
155 * Destroy this match information view.
156 */
157 destroy : function () {
158
159 // Remove circular reference
160 if (this._treeMenu !== undefined)
161 delete this._treeMenu["info"];
162
163 this._treeMenu.destroy();
164 this._treeMenu = undefined;
165 this._match = undefined;
166
167 // Element destroy
168 },
169
170 /**
171 * Add a new tree view to the list
172 */
173 addTree : function (foundry, layer, cb) {
174 var matchtree = document.createElement('div');
175 matchtree.classList.add('matchtree');
176
177 var h6 = matchtree.appendChild(document.createElement('h6'));
178 h6.appendChild(document.createElement('span'))
179 .appendChild(document.createTextNode(foundry));
180 h6.appendChild(document.createElement('span'))
181 .appendChild(document.createTextNode(layer));
182
183 var tree = matchtree.appendChild(
184 document.createElement('div')
185 );
186
187 this._element.insertBefore(matchtree, this._element.lastChild);
188
189 var close = tree.appendChild(document.createElement('em'));
190 close.addEventListener(
191 'click', function (e) {
192 matchtree.parentNode.removeChild(matchtree);
193 e.halt();
194 }
195 );
196
Nils Diewald0ec142f2015-05-05 00:29:23 +0000197 tree.classList.add('loading');
198
Nils Diewald0e6992a2015-04-14 20:13:52 +0000199 // Get tree data async
200 this.getTree(foundry, layer, function (treeObj) {
Nils Diewald0ec142f2015-05-05 00:29:23 +0000201
202 tree.classList.remove('loading');
203
Nils Diewald0e6992a2015-04-14 20:13:52 +0000204 // Something went wrong - probably log!!!
Nils Diewald0ec142f2015-05-05 00:29:23 +0000205
Nils Diewald0e6992a2015-04-14 20:13:52 +0000206 if (treeObj === null) {
207 tree.appendChild(document.createTextNode('No data available.'));
208 }
209 else {
210 tree.appendChild(treeObj.element());
211 // Reposition the view to the center
212 // (This may in a future release be a reposition
213 // to move the root into the center or the actual
214 // match)
215 treeObj.center();
Nils Diewald0ec142f2015-05-05 00:29:23 +0000216 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000217
218 if (cb !== undefined)
219 cb(treeObj);
Nils Diewald0ec142f2015-05-05 00:29:23 +0000220
Nils Diewald0e6992a2015-04-14 20:13:52 +0000221 });
222 },
223
224 /**
225 * Create match information view.
226 */
227 element : function () {
228
229 if (this._element !== undefined)
230 return this._element;
231
232 // Create info table
233 var info = document.createElement('div');
234 info.classList.add('matchinfo');
235
236 // Append default table
237 var matchtable = document.createElement('div');
Nils Diewald0ec142f2015-05-05 00:29:23 +0000238 matchtable.classList.add('matchtable', 'loading');
Nils Diewald0e6992a2015-04-14 20:13:52 +0000239 info.appendChild(matchtable);
240
241 // Create the table asynchronous
242 this.getTable(undefined, function (table) {
243 if (table !== null) {
Nils Diewald0ec142f2015-05-05 00:29:23 +0000244 matchtable.classList.remove('loading');
Nils Diewald0e6992a2015-04-14 20:13:52 +0000245 matchtable.appendChild(table.element());
246 };
247 });
248
249 // Get spans
250 var spanLayers = this._match.getSpans().sort(
251 function (a, b) {
252 if (a.foundry < b.foundry) {
253 return -1;
254 }
255 else if (a.foundry > b.foundry) {
256 return 1;
257 }
258 else if (a.layer < b.layer) {
259 return -1;
260 }
261 else if (a.layer > b.layer) {
262 return 1;
263 };
264 return 0;
265 });
266
267 var menuList = [];
268
269 // Show tree views
270 for (var i = 0; i < spanLayers.length; i++) {
271 var span = spanLayers[i];
272
273 // Add foundry/layer to menu list
274 menuList.push([
275 span.foundry + '/' + span.layer,
276 span.foundry,
277 span.layer
278 ]);
279 };
280
281 // Create tree menu
282 var treemenu = this.treeMenu(menuList);
283 var span = info.appendChild(document.createElement('p'));
284 span.classList.add('addtree');
285 span.appendChild(document.createTextNode(loc.ADDTREE));
286
287 var treeElement = treemenu.element();
288 span.appendChild(treeElement);
289
290 span.addEventListener('click', function (e) {
Akron6ed13992016-05-23 18:06:05 +0200291 treemenu.show();
Nils Diewald0e6992a2015-04-14 20:13:52 +0000292 treemenu.focus();
293 });
294
295 this._element = info;
296
297 return info;
298 },
299
300
301 /**
302 * Get tree menu.
303 * There is only one menu rendered
304 * - no matter how many trees exist
305 */
306 treeMenu : function (list) {
307 if (this._treeMenu !== undefined)
308 return this._treeMenu;
309
310 return this._treeMenu = matchTreeMenuClass.create(this, list);
311 }
312 };
313});