blob: a8ae51dda283c4c9f8f26250a5ad0ede6910dac9 [file] [log] [blame]
Nils Diewald7148c6f2015-05-04 15:07:53 +00001/**
2 * Table representation of morphological
3 * annotations of a match.
4 */
Nils Diewald0e6992a2015-04-14 20:13:52 +00005define(function () {
6 var _TermRE = new RegExp("^(?:([^\/]+?)\/)?([^:]+?):(.+?)$");
7
8 return {
Nils Diewald7148c6f2015-05-04 15:07:53 +00009
10 /**
11 * Create new table view for a match
12 * based on a snippet string.
13 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000014 create : function (snippet) {
15 return Object.create(this)._init(snippet);
16 },
Nils Diewald7148c6f2015-05-04 15:07:53 +000017
18 // Initialize table based on snippet
Nils Diewald0e6992a2015-04-14 20:13:52 +000019 _init : function (snippet) {
20 // Create html for traversal
21 var html = document.createElement("div");
22 html.innerHTML = snippet;
23
24 this._pos = 0;
25 this._token = [];
26 this._info = [];
27 this._foundry = {};
28 this._layer = {};
29
30 // Parse the snippet
31 this._parse(html.childNodes);
32
33 html.innerHTML = '';
34 return this;
35 },
36
Nils Diewald7148c6f2015-05-04 15:07:53 +000037
38 /**
39 * Length of the table (columns),
40 * aka the number of tokens
41 * in the snippet.
42 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000043 length : function () {
44 return this._pos;
45 },
46
Nils Diewald7148c6f2015-05-04 15:07:53 +000047 /**
48 * Get the token in the snippet
49 * At a given position.
50 *
51 * @param pos
52 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000053 getToken : function (pos) {
54 if (pos === undefined)
Akron916ec252016-11-10 17:06:32 +010055 return this._token;
Nils Diewald0e6992a2015-04-14 20:13:52 +000056 return this._token[pos];
57 },
Nils Diewald7148c6f2015-05-04 15:07:53 +000058
59 /**
60 * Get the annotation of a token
61 * in the snippet based on the position,
62 * the foundry, and the layer.
63 *
64 * @param pos
65 * @param foundry
66 * @param layer
67 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000068 getValue : function (pos, foundry, layer) {
69 return this._info[pos][foundry + '/' + layer]
70 },
Nils Diewald0e6992a2015-04-14 20:13:52 +000071
72 // Parse the snippet
73 _parse : function (children) {
74
75 // Get all children
76 for (var i in children) {
Akron916ec252016-11-10 17:06:32 +010077 var c = children[i];
Nils Diewald0e6992a2015-04-14 20:13:52 +000078
Akron916ec252016-11-10 17:06:32 +010079 // Create object on position unless it exists
80 if (this._info[this._pos] === undefined) {
81 this._info[this._pos] = {};
82 };
Nils Diewald0e6992a2015-04-14 20:13:52 +000083
Akron916ec252016-11-10 17:06:32 +010084 // Store at position in foundry/layer as array
85 var found = this._info[this._pos];
Nils Diewald0e6992a2015-04-14 20:13:52 +000086
Akron916ec252016-11-10 17:06:32 +010087 // Element with title
88 if (c.nodeType === 1) {
89 if (c.getAttribute("title") &&
90 _TermRE.exec(c.getAttribute("title"))) {
Nils Diewald0e6992a2015-04-14 20:13:52 +000091
Akron916ec252016-11-10 17:06:32 +010092 // Fill position with info
93 var foundry, layer, value;
94 if (RegExp.$2) {
95 foundry = RegExp.$1;
96 layer = RegExp.$2;
97 }
98 else {
99 foundry = "base";
100 layer = RegExp.$1
101 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000102
Akron916ec252016-11-10 17:06:32 +0100103 value = RegExp.$3;
104
105 if (found[foundry + "/" + layer] === undefined) {
106 found[foundry + "/" + layer] = [value];
107 }
108 else {
109 if (found[foundry + "/" + layer].indexOf(value) === -1) {
110 // Push value to foundry/layer at correct position
111 found[foundry + "/" + layer].push(value);
112 };
113 }
Nils Diewald0e6992a2015-04-14 20:13:52 +0000114
Akron916ec252016-11-10 17:06:32 +0100115 // Set foundry
116 if (this._foundry[foundry] === undefined)
117 this._foundry[foundry] = {};
118 this._foundry[foundry][layer] = 1;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000119
Akron916ec252016-11-10 17:06:32 +0100120 // Set layer
121 if (this._layer[layer] === undefined)
122 this._layer[layer] = {};
123 this._layer[layer][foundry] = 1;
124 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000125
Akron916ec252016-11-10 17:06:32 +0100126 // depth search
127 if (c.hasChildNodes())
128 this._parse(c.childNodes);
129 }
Nils Diewald0e6992a2015-04-14 20:13:52 +0000130
Akron916ec252016-11-10 17:06:32 +0100131 // Leaf node
132 // store string on position and go to next string
133 else if (c.nodeType === 3) {
134 if (c.nodeValue.match(/[a-z0-9]/i))
135 this._token[this._pos++] = c.nodeValue;
136 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000137 };
138
139 delete this._info[this._pos];
140 },
141
142
143 /**
144 * Get HTML table view of annotations.
145 */
146 element : function () {
147 if (this._element !== undefined)
Akron916ec252016-11-10 17:06:32 +0100148 return this._element;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000149
150 // First the legend table
151 var d = document;
152 var table = d.createElement('table');
153
154 // Single row in head
155 var tr = table.appendChild(d.createElement('thead'))
Akron916ec252016-11-10 17:06:32 +0100156 .appendChild(d.createElement('tr'));
Nils Diewald0e6992a2015-04-14 20:13:52 +0000157
Akronf2279c42017-12-21 13:48:46 +0100158 var ah = KorAP.annotationHelper || { "getDesc" : function () {}};
159
Nils Diewald0e6992a2015-04-14 20:13:52 +0000160 // Add cell to row
Akronf2279c42017-12-21 13:48:46 +0100161 var addCell = function (type, key, value) {
Akron916ec252016-11-10 17:06:32 +0100162 var c = this.appendChild(d.createElement(type))
Akronf2279c42017-12-21 13:48:46 +0100163 if (value === undefined)
Akron916ec252016-11-10 17:06:32 +0100164 return c;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000165
Akronf2279c42017-12-21 13:48:46 +0100166 if (key && value instanceof Array && value[1] !== undefined) {
Akron4e47d0b2017-07-03 17:58:37 +0200167
168 // There are multiple values to add
Akron856af1e2017-07-03 19:57:46 +0200169 c.classList.add('matchkeyvalues');
Akronf2279c42017-12-21 13:48:46 +0100170 for (var n = 0; n < value.length; n++) {
171 var text = d.createTextNode(value[n]);
Akron856af1e2017-07-03 19:57:46 +0200172 var e = c.appendChild(d.createElement('div'));
173 e.appendChild(text);
Akronf2279c42017-12-21 13:48:46 +0100174
175 var anno = ah.getDesc(key, value[n]);
176
177 if (anno)
178 e.setAttribute("title", anno);
Akron856af1e2017-07-03 19:57:46 +0200179 };
Akron916ec252016-11-10 17:06:32 +0100180 }
Akronf2279c42017-12-21 13:48:46 +0100181
Akron916ec252016-11-10 17:06:32 +0100182 else {
Akronf2279c42017-12-21 13:48:46 +0100183
184 if (value instanceof Array)
185 value = value[0];
186
187 c.appendChild(d.createTextNode(value));
188
189 // Add tooltip
190 var anno = ah.getDesc(key, value);
191 if (anno)
192 c.setAttribute("title", anno);
Akron916ec252016-11-10 17:06:32 +0100193 };
Akron80055992017-12-20 16:30:52 +0100194
195 return c;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000196 };
197
198 tr.addCell = addCell;
199
200 // Add header information
Akronf2279c42017-12-21 13:48:46 +0100201 tr.addCell('th', undefined, 'Foundry');
202 tr.addCell('th', undefined, 'Layer');
Nils Diewald0e6992a2015-04-14 20:13:52 +0000203
204 // Add tokens
205 for (var i in this._token) {
Akronf2279c42017-12-21 13:48:46 +0100206 tr.addCell('th', undefined, this.getToken(i));
Nils Diewald0e6992a2015-04-14 20:13:52 +0000207 };
Akron916ec252016-11-10 17:06:32 +0100208
Nils Diewald0e6992a2015-04-14 20:13:52 +0000209 var tbody = table.appendChild(
Akron916ec252016-11-10 17:06:32 +0100210 d.createElement('tbody')
Nils Diewald0e6992a2015-04-14 20:13:52 +0000211 );
212
213 var foundryList = Object.keys(this._foundry).sort();
214
215 for (var f = 0; f < foundryList.length; f++) {
Akron99713ef2017-06-28 18:19:28 +0200216 var foundry = foundryList[f];
217 var layerList =
218 Object.keys(this._foundry[foundry]).sort();
Nils Diewald0e6992a2015-04-14 20:13:52 +0000219
Akron99713ef2017-06-28 18:19:28 +0200220 for (var l = 0; l < layerList.length; l++) {
221 var layer = layerList[l];
222 tr = tbody.appendChild(
223 d.createElement('tr')
224 );
225 tr.setAttribute('tabindex', 0);
226 tr.addCell = addCell;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000227
Akronf2279c42017-12-21 13:48:46 +0100228 tr.addCell('th', undefined, foundry);
229 tr.addCell('th', undefined, layer);
Nils Diewald0e6992a2015-04-14 20:13:52 +0000230
Akron80055992017-12-20 16:30:52 +0100231 var key = foundry + '/' + layer + '=';
Akron80055992017-12-20 16:30:52 +0100232
Akron99713ef2017-06-28 18:19:28 +0200233 for (var v = 0; v < this.length(); v++) {
Akron80055992017-12-20 16:30:52 +0100234
235 // Get the cell value
236 var value = this.getValue(v, foundry, layer);
237
238 // Add cell to row
239 var cell = tr.addCell(
Akron99713ef2017-06-28 18:19:28 +0200240 'td',
Akronf2279c42017-12-21 13:48:46 +0100241 key,
Akron80055992017-12-20 16:30:52 +0100242 value
Akron99713ef2017-06-28 18:19:28 +0200243 );
244 };
245 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000246 };
247
248 return this._element = table;
249 }
250 };
251});