blob: b24bed5ad7682e4b396adaacbc9f4cdcc2b0862a [file] [log] [blame]
Nils Diewald0e6992a2015-04-14 20:13:52 +00001 /**
2 * Information about a match.
3 */
4define(['match/infolayer','match/table','match/tree', 'match/treemenu', 'util'], function (infoLayerClass, matchTableClass, matchTreeClass, matchTreeMenuClass) {
5
6 // TODO: Make this async
7 KorAP.API.getMatchInfo = KorAP.API.getMatchInfo || function () {
8 KorAP.log(0, 'KorAP.API.getMatchInfo() not implemented')
9 return {};
10 };
11
12 var loc = KorAP.Locale;
13
14 /**
15 * Create new object
16 */
17 return {
18 create : function (match) {
19 return Object.create(this)._init(match);
20 },
21
22 /**
23 * Initialize object
24 */
25 _init : function (match) {
26 this._match = match;
27 this.opened = false;
28 return this;
29 },
30
31 /**
32 * Get match object
33 */
34 match : function () {
35 return this._match;
36 },
37
38 toggle : function () {
39 if (this.opened == true) {
40 this._match.element().children[0].removeChild(
41 this.element()
42 );
43 this.opened = false;
44 }
45 else {
46 // Append element to match
47 this._match.element().children[0].appendChild(
48 this.element()
49 );
50 this.opened = true;
51 };
52
53 return this.opened;
54 },
55
56
57 /**
58 * Retrieve and parse snippet for table representation
59 */
60 getTable : function (tokens, cb) {
61 var focus = [];
62
63 // Get all tokens
64 if (tokens === undefined) {
65 focus = this._match.getTokens();
66 }
67
68 // Get only some tokens
69 else {
70
71 // Push newly to focus array
72 for (var i = 0; i < tokens.length; i++) {
73 var term = tokens[i];
74 try {
75 // Create info layer objects
76 var layer = infoLayerClass.create(term);
77 layer.type = "tokens";
78 focus.push(layer);
79 }
80 catch (e) {
81 continue;
82 };
83 };
84 };
85
86 // No tokens chosen
87 if (focus.length == 0)
88 cb(null);
89
90 // Get info (may be cached)
91 // TODO: Async
92 KorAP.API.getMatchInfo(
93 this._match,
94 { 'spans' : false, 'layer' : focus },
95
96 // Callback for retrieval
97 function (matchResponse) {
98 // Get snippet from match info
99 if (matchResponse["snippet"] !== undefined) {
100 this._table = matchTableClass.create(matchResponse["snippet"]);
101 cb(this._table);
102 };
103 }.bind(this)
104 );
105
106 /*
107 // Todo: Store the table as a hash of the focus
108 return null;
109 */
110 },
111
112
113 /**
114 * Retrieve and parse snippet for tree representation
115 */
116 getTree : function (foundry, layer, cb) {
117 var focus = [];
118
119 // TODO: Support and cache multiple trees
120 KorAP.API.getMatchInfo(
121 this._match, {
122 'spans' : true,
123 'foundry' : foundry,
124 'layer' : layer
125 },
126 function (matchResponse) {
127 // Get snippet from match info
128 if (matchResponse["snippet"] !== undefined) {
129 // Todo: This should be cached somehow
130 cb(matchTreeClass.create(matchResponse["snippet"]));
131 }
132 else {
133 cb(null);
134 };
135 }.bind(this)
136 );
137 },
138
139 /**
140 * Destroy this match information view.
141 */
142 destroy : function () {
143
144 // Remove circular reference
145 if (this._treeMenu !== undefined)
146 delete this._treeMenu["info"];
147
148 this._treeMenu.destroy();
149 this._treeMenu = undefined;
150 this._match = undefined;
151
152 // Element destroy
153 },
154
155 /**
156 * Add a new tree view to the list
157 */
158 addTree : function (foundry, layer, cb) {
159 var matchtree = document.createElement('div');
160 matchtree.classList.add('matchtree');
161
162 var h6 = matchtree.appendChild(document.createElement('h6'));
163 h6.appendChild(document.createElement('span'))
164 .appendChild(document.createTextNode(foundry));
165 h6.appendChild(document.createElement('span'))
166 .appendChild(document.createTextNode(layer));
167
168 var tree = matchtree.appendChild(
169 document.createElement('div')
170 );
171
172 this._element.insertBefore(matchtree, this._element.lastChild);
173
174 var close = tree.appendChild(document.createElement('em'));
175 close.addEventListener(
176 'click', function (e) {
177 matchtree.parentNode.removeChild(matchtree);
178 e.halt();
179 }
180 );
181
182 // Get tree data async
183 this.getTree(foundry, layer, function (treeObj) {
184 // Something went wrong - probably log!!!
185 if (treeObj === null) {
186 tree.appendChild(document.createTextNode('No data available.'));
187 }
188 else {
189 tree.appendChild(treeObj.element());
190 // Reposition the view to the center
191 // (This may in a future release be a reposition
192 // to move the root into the center or the actual
193 // match)
194 treeObj.center();
195 }
196
197 if (cb !== undefined)
198 cb(treeObj);
199 });
200 },
201
202 /**
203 * Create match information view.
204 */
205 element : function () {
206
207 if (this._element !== undefined)
208 return this._element;
209
210 // Create info table
211 var info = document.createElement('div');
212 info.classList.add('matchinfo');
213
214 // Append default table
215 var matchtable = document.createElement('div');
216 matchtable.classList.add('matchtable');
217 info.appendChild(matchtable);
218
219 // Create the table asynchronous
220 this.getTable(undefined, function (table) {
221 if (table !== null) {
222 matchtable.appendChild(table.element());
223 };
224 });
225
226 // Get spans
227 var spanLayers = this._match.getSpans().sort(
228 function (a, b) {
229 if (a.foundry < b.foundry) {
230 return -1;
231 }
232 else if (a.foundry > b.foundry) {
233 return 1;
234 }
235 else if (a.layer < b.layer) {
236 return -1;
237 }
238 else if (a.layer > b.layer) {
239 return 1;
240 };
241 return 0;
242 });
243
244 var menuList = [];
245
246 // Show tree views
247 for (var i = 0; i < spanLayers.length; i++) {
248 var span = spanLayers[i];
249
250 // Add foundry/layer to menu list
251 menuList.push([
252 span.foundry + '/' + span.layer,
253 span.foundry,
254 span.layer
255 ]);
256 };
257
258 // Create tree menu
259 var treemenu = this.treeMenu(menuList);
260 var span = info.appendChild(document.createElement('p'));
261 span.classList.add('addtree');
262 span.appendChild(document.createTextNode(loc.ADDTREE));
263
264 var treeElement = treemenu.element();
265 span.appendChild(treeElement);
266
267 span.addEventListener('click', function (e) {
268 treemenu.show('');
269 treemenu.focus();
270 });
271
272 this._element = info;
273
274 return info;
275 },
276
277
278 /**
279 * Get tree menu.
280 * There is only one menu rendered
281 * - no matter how many trees exist
282 */
283 treeMenu : function (list) {
284 if (this._treeMenu !== undefined)
285 return this._treeMenu;
286
287 return this._treeMenu = matchTreeMenuClass.create(this, list);
288 }
289 };
290});