blob: 46f2890903a834be20aa628fd1e8c6015a140640 [file] [log] [blame]
Nils Diewald7148c6f2015-05-04 15:07:53 +00001/**
2 * Table representation of morphological
3 * annotations of a match.
4 */
Akron0b489ad2018-02-02 16:49:32 +01005define(["util"], function () {
6 const _TermRE = new RegExp("^(?:([^\/]+?)\/)?([^:]+?):(.+?)$");
7 const d = document;
8
Nils Diewald0e6992a2015-04-14 20:13:52 +00009 return {
Nils Diewald7148c6f2015-05-04 15:07:53 +000010
11 /**
12 * Create new table view for a match
13 * based on a snippet string.
14 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000015 create : function (snippet) {
16 return Object.create(this)._init(snippet);
17 },
Nils Diewald7148c6f2015-05-04 15:07:53 +000018
19 // Initialize table based on snippet
Nils Diewald0e6992a2015-04-14 20:13:52 +000020 _init : function (snippet) {
21 // Create html for traversal
Akron0b489ad2018-02-02 16:49:32 +010022 var html = d.createElement("div");
Nils Diewald0e6992a2015-04-14 20:13:52 +000023 html.innerHTML = snippet;
24
25 this._pos = 0;
26 this._token = [];
27 this._info = [];
28 this._foundry = {};
29 this._layer = {};
30
31 // Parse the snippet
32 this._parse(html.childNodes);
33
34 html.innerHTML = '';
35 return this;
36 },
37
Nils Diewald7148c6f2015-05-04 15:07:53 +000038
39 /**
40 * Length of the table (columns),
41 * aka the number of tokens
42 * in the snippet.
43 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000044 length : function () {
45 return this._pos;
46 },
47
Nils Diewald7148c6f2015-05-04 15:07:53 +000048 /**
49 * Get the token in the snippet
50 * At a given position.
51 *
52 * @param pos
53 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000054 getToken : function (pos) {
55 if (pos === undefined)
Akron916ec252016-11-10 17:06:32 +010056 return this._token;
Nils Diewald0e6992a2015-04-14 20:13:52 +000057 return this._token[pos];
58 },
Nils Diewald7148c6f2015-05-04 15:07:53 +000059
60 /**
61 * Get the annotation of a token
62 * in the snippet based on the position,
63 * the foundry, and the layer.
64 *
65 * @param pos
66 * @param foundry
67 * @param layer
68 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000069 getValue : function (pos, foundry, layer) {
70 return this._info[pos][foundry + '/' + layer]
71 },
Nils Diewald0e6992a2015-04-14 20:13:52 +000072
73 // Parse the snippet
74 _parse : function (children) {
75
76 // Get all children
77 for (var i in children) {
Akron916ec252016-11-10 17:06:32 +010078 var c = children[i];
Nils Diewald0e6992a2015-04-14 20:13:52 +000079
Akron916ec252016-11-10 17:06:32 +010080 // Create object on position unless it exists
81 if (this._info[this._pos] === undefined) {
82 this._info[this._pos] = {};
83 };
Nils Diewald0e6992a2015-04-14 20:13:52 +000084
Akron916ec252016-11-10 17:06:32 +010085 // Store at position in foundry/layer as array
86 var found = this._info[this._pos];
Nils Diewald0e6992a2015-04-14 20:13:52 +000087
Akron916ec252016-11-10 17:06:32 +010088 // Element with title
89 if (c.nodeType === 1) {
90 if (c.getAttribute("title") &&
91 _TermRE.exec(c.getAttribute("title"))) {
Nils Diewald0e6992a2015-04-14 20:13:52 +000092
Akron916ec252016-11-10 17:06:32 +010093 // Fill position with info
94 var foundry, layer, value;
95 if (RegExp.$2) {
96 foundry = RegExp.$1;
97 layer = RegExp.$2;
98 }
99 else {
100 foundry = "base";
101 layer = RegExp.$1
102 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000103
Akron916ec252016-11-10 17:06:32 +0100104 value = RegExp.$3;
105
106 if (found[foundry + "/" + layer] === undefined) {
107 found[foundry + "/" + layer] = [value];
108 }
109 else {
110 if (found[foundry + "/" + layer].indexOf(value) === -1) {
111 // Push value to foundry/layer at correct position
112 found[foundry + "/" + layer].push(value);
113 };
114 }
Nils Diewald0e6992a2015-04-14 20:13:52 +0000115
Akron916ec252016-11-10 17:06:32 +0100116 // Set foundry
117 if (this._foundry[foundry] === undefined)
118 this._foundry[foundry] = {};
119 this._foundry[foundry][layer] = 1;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000120
Akron916ec252016-11-10 17:06:32 +0100121 // Set layer
122 if (this._layer[layer] === undefined)
123 this._layer[layer] = {};
124 this._layer[layer][foundry] = 1;
125 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000126
Akron916ec252016-11-10 17:06:32 +0100127 // depth search
128 if (c.hasChildNodes())
129 this._parse(c.childNodes);
130 }
Nils Diewald0e6992a2015-04-14 20:13:52 +0000131
Akron916ec252016-11-10 17:06:32 +0100132 // Leaf node
133 // store string on position and go to next string
134 else if (c.nodeType === 3) {
135 if (c.nodeValue.match(/[a-z0-9]/i))
136 this._token[this._pos++] = c.nodeValue;
137 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000138 };
139
140 delete this._info[this._pos];
141 },
142
143
144 /**
145 * Get HTML table view of annotations.
146 */
147 element : function () {
148 if (this._element !== undefined)
Akron916ec252016-11-10 17:06:32 +0100149 return this._element;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000150
151 // First the legend table
Nils Diewald0e6992a2015-04-14 20:13:52 +0000152 var table = d.createElement('table');
153
154 // Single row in head
Akron0b489ad2018-02-02 16:49:32 +0100155 var tr = table.addE('thead').addE('tr');
Nils Diewald0e6992a2015-04-14 20:13:52 +0000156
Akronf2279c42017-12-21 13:48:46 +0100157 var ah = KorAP.annotationHelper || { "getDesc" : function () {}};
158
Nils Diewald0e6992a2015-04-14 20:13:52 +0000159 // Add cell to row
Akronf2279c42017-12-21 13:48:46 +0100160 var addCell = function (type, key, value) {
Akron0b489ad2018-02-02 16:49:32 +0100161 var c = this.addE(type);
162
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++) {
Akron0b489ad2018-02-02 16:49:32 +0100171 var e = c.addE('div').addT(value[n]);
Akronf2279c42017-12-21 13:48:46 +0100172
173 var anno = ah.getDesc(key, value[n]);
174
175 if (anno)
176 e.setAttribute("title", anno);
Akron856af1e2017-07-03 19:57:46 +0200177 };
Akron916ec252016-11-10 17:06:32 +0100178 }
Akronf2279c42017-12-21 13:48:46 +0100179
Akron916ec252016-11-10 17:06:32 +0100180 else {
Akronf2279c42017-12-21 13:48:46 +0100181
182 if (value instanceof Array)
183 value = value[0];
184
Akron0b489ad2018-02-02 16:49:32 +0100185 c.addT(value);
Akronf2279c42017-12-21 13:48:46 +0100186
187 // Add tooltip
188 var anno = ah.getDesc(key, value);
189 if (anno)
190 c.setAttribute("title", anno);
Akron916ec252016-11-10 17:06:32 +0100191 };
Akron80055992017-12-20 16:30:52 +0100192
193 return c;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000194 };
195
196 tr.addCell = addCell;
197
198 // Add header information
Akronf2279c42017-12-21 13:48:46 +0100199 tr.addCell('th', undefined, 'Foundry');
200 tr.addCell('th', undefined, 'Layer');
Nils Diewald0e6992a2015-04-14 20:13:52 +0000201
202 // Add tokens
203 for (var i in this._token) {
Akronf2279c42017-12-21 13:48:46 +0100204 tr.addCell('th', undefined, this.getToken(i));
Nils Diewald0e6992a2015-04-14 20:13:52 +0000205 };
Akron916ec252016-11-10 17:06:32 +0100206
Akron0b489ad2018-02-02 16:49:32 +0100207 var tbody = table.addE('tbody');
Nils Diewald0e6992a2015-04-14 20:13:52 +0000208
209 var foundryList = Object.keys(this._foundry).sort();
210
211 for (var f = 0; f < foundryList.length; f++) {
Akron99713ef2017-06-28 18:19:28 +0200212 var foundry = foundryList[f];
213 var layerList =
214 Object.keys(this._foundry[foundry]).sort();
Nils Diewald0e6992a2015-04-14 20:13:52 +0000215
Akron99713ef2017-06-28 18:19:28 +0200216 for (var l = 0; l < layerList.length; l++) {
217 var layer = layerList[l];
Akron0b489ad2018-02-02 16:49:32 +0100218 tr = tbody.addE('tr');
Akron99713ef2017-06-28 18:19:28 +0200219 tr.setAttribute('tabindex', 0);
220 tr.addCell = addCell;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000221
Akronf2279c42017-12-21 13:48:46 +0100222 tr.addCell('th', undefined, foundry);
223 tr.addCell('th', undefined, layer);
Nils Diewald0e6992a2015-04-14 20:13:52 +0000224
Akron80055992017-12-20 16:30:52 +0100225 var key = foundry + '/' + layer + '=';
Akron80055992017-12-20 16:30:52 +0100226
Akron99713ef2017-06-28 18:19:28 +0200227 for (var v = 0; v < this.length(); v++) {
Akron80055992017-12-20 16:30:52 +0100228
229 // Get the cell value
230 var value = this.getValue(v, foundry, layer);
231
232 // Add cell to row
233 var cell = tr.addCell(
Akron99713ef2017-06-28 18:19:28 +0200234 'td',
Akronf2279c42017-12-21 13:48:46 +0100235 key,
Akron80055992017-12-20 16:30:52 +0100236 value
Akron99713ef2017-06-28 18:19:28 +0200237 );
238 };
239 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000240 };
241
242 return this._element = table;
243 }
244 };
245});