blob: b75e713585efff0097115fd92f415d3d2d46cc1f [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)
107 // TODO: Async
108 KorAP.API.getMatchInfo(
109 this._match,
110 { 'spans' : false, 'layer' : focus },
111
112 // Callback for retrieval
113 function (matchResponse) {
114 // Get snippet from match info
115 if (matchResponse["snippet"] !== undefined) {
116 this._table = matchTableClass.create(matchResponse["snippet"]);
117 cb(this._table);
118 };
119 }.bind(this)
120 );
121
122 /*
123 // Todo: Store the table as a hash of the focus
124 return null;
125 */
126 },
127
128
129 /**
130 * Retrieve and parse snippet for tree representation
131 */
132 getTree : function (foundry, layer, cb) {
133 var focus = [];
134
135 // TODO: Support and cache multiple trees
136 KorAP.API.getMatchInfo(
137 this._match, {
138 'spans' : true,
139 'foundry' : foundry,
140 'layer' : layer
141 },
142 function (matchResponse) {
143 // Get snippet from match info
144 if (matchResponse["snippet"] !== undefined) {
145 // Todo: This should be cached somehow
146 cb(matchTreeClass.create(matchResponse["snippet"]));
147 }
148 else {
149 cb(null);
150 };
151 }.bind(this)
152 );
153 },
154
155 /**
156 * Destroy this match information view.
157 */
158 destroy : function () {
159
160 // Remove circular reference
161 if (this._treeMenu !== undefined)
162 delete this._treeMenu["info"];
163
164 this._treeMenu.destroy();
165 this._treeMenu = undefined;
166 this._match = undefined;
167
168 // Element destroy
169 },
170
171 /**
172 * Add a new tree view to the list
173 */
174 addTree : function (foundry, layer, cb) {
175 var matchtree = document.createElement('div');
176 matchtree.classList.add('matchtree');
177
178 var h6 = matchtree.appendChild(document.createElement('h6'));
179 h6.appendChild(document.createElement('span'))
180 .appendChild(document.createTextNode(foundry));
181 h6.appendChild(document.createElement('span'))
182 .appendChild(document.createTextNode(layer));
183
184 var tree = matchtree.appendChild(
185 document.createElement('div')
186 );
187
188 this._element.insertBefore(matchtree, this._element.lastChild);
189
190 var close = tree.appendChild(document.createElement('em'));
191 close.addEventListener(
192 'click', function (e) {
193 matchtree.parentNode.removeChild(matchtree);
194 e.halt();
195 }
196 );
197
198 // Get tree data async
199 this.getTree(foundry, layer, function (treeObj) {
200 // Something went wrong - probably log!!!
201 if (treeObj === null) {
202 tree.appendChild(document.createTextNode('No data available.'));
203 }
204 else {
205 tree.appendChild(treeObj.element());
206 // Reposition the view to the center
207 // (This may in a future release be a reposition
208 // to move the root into the center or the actual
209 // match)
210 treeObj.center();
211 }
212
213 if (cb !== undefined)
214 cb(treeObj);
215 });
216 },
217
218 /**
219 * Create match information view.
220 */
221 element : function () {
222
223 if (this._element !== undefined)
224 return this._element;
225
226 // Create info table
227 var info = document.createElement('div');
228 info.classList.add('matchinfo');
229
230 // Append default table
231 var matchtable = document.createElement('div');
232 matchtable.classList.add('matchtable');
233 info.appendChild(matchtable);
234
235 // Create the table asynchronous
236 this.getTable(undefined, function (table) {
237 if (table !== null) {
238 matchtable.appendChild(table.element());
239 };
240 });
241
242 // Get spans
243 var spanLayers = this._match.getSpans().sort(
244 function (a, b) {
245 if (a.foundry < b.foundry) {
246 return -1;
247 }
248 else if (a.foundry > b.foundry) {
249 return 1;
250 }
251 else if (a.layer < b.layer) {
252 return -1;
253 }
254 else if (a.layer > b.layer) {
255 return 1;
256 };
257 return 0;
258 });
259
260 var menuList = [];
261
262 // Show tree views
263 for (var i = 0; i < spanLayers.length; i++) {
264 var span = spanLayers[i];
265
266 // Add foundry/layer to menu list
267 menuList.push([
268 span.foundry + '/' + span.layer,
269 span.foundry,
270 span.layer
271 ]);
272 };
273
274 // Create tree menu
275 var treemenu = this.treeMenu(menuList);
276 var span = info.appendChild(document.createElement('p'));
277 span.classList.add('addtree');
278 span.appendChild(document.createTextNode(loc.ADDTREE));
279
280 var treeElement = treemenu.element();
281 span.appendChild(treeElement);
282
283 span.addEventListener('click', function (e) {
284 treemenu.show('');
285 treemenu.focus();
286 });
287
288 this._element = info;
289
290 return info;
291 },
292
293
294 /**
295 * Get tree menu.
296 * There is only one menu rendered
297 * - no matter how many trees exist
298 */
299 treeMenu : function (list) {
300 if (this._treeMenu !== undefined)
301 return this._treeMenu;
302
303 return this._treeMenu = matchTreeMenuClass.create(this, list);
304 }
305 };
306});