n@156
|
1 <!DOCTYPE html>
|
n@156
|
2 <html lang="en">
|
n@156
|
3 <head>
|
n@156
|
4 <meta charset="utf-8">
|
n@156
|
5
|
n@156
|
6 <!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
|
n@156
|
7 Remove this if you use the .htaccess -->
|
n@156
|
8 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
n@156
|
9
|
n@156
|
10 <title>WAET Create Test</title>
|
n@156
|
11 <meta name="description" content="">
|
n@156
|
12 <meta name="author" content="">
|
n@156
|
13
|
n@156
|
14 <meta name="viewport" content="width=device-width; initial-scale=1.0">
|
n@157
|
15
|
n@157
|
16 <script type="text/javascript">
|
n@157
|
17 // To aid 'one-page set-up' all scripts and CSS must be included directly in this file!
|
n@157
|
18 var topLevel;
|
n@157
|
19 window.onload = function() {
|
n@157
|
20 // Initialise page
|
n@157
|
21 topLevel = document.getElementById('topLevelBody');
|
n@157
|
22 var setup = document.createElement('div');
|
n@157
|
23 setup.id = 'setupTagDiv';
|
n@157
|
24
|
n@168
|
25 // Setup drag/drop handles
|
n@168
|
26 var dropBody = document.getElementById('dragFile');
|
n@168
|
27 dropBody.addEventListener('dragover', handleDragOver, false);
|
n@168
|
28 dropBody.addEventListener('dragenter',handleDragEnter,false);
|
n@168
|
29 dropBody.addEventListener('dragleave',handleDragLeave,false);
|
n@168
|
30 dropBody.addEventListener('drop', handleDrop,false);
|
n@157
|
31 };
|
n@157
|
32
|
n@162
|
33 function attributePair(string, type, mandatory){
|
n@157
|
34 var id = document.createElement("span");
|
n@157
|
35 id.textContent = string;
|
n@157
|
36 var input = document.createElement("input");
|
n@157
|
37 input.type = type;
|
n@162
|
38 if (type == 'text') {
|
n@162
|
39 if (mandatory == true) {
|
n@162
|
40 input.setAttribute('mandatory','true');
|
n@162
|
41 }
|
n@162
|
42 else {
|
n@162
|
43 input.setAttribute('mandatory','false');
|
n@162
|
44 }
|
n@162
|
45 }
|
n@157
|
46 return [id, input];
|
n@157
|
47 }
|
n@157
|
48
|
n@159
|
49 function removeNode(event) {
|
n@159
|
50 event.srcElement.parentElement.parentElement.removeChild(event.srcElement.parentElement);
|
n@159
|
51 }
|
n@159
|
52
|
n@162
|
53 function buttonClickedValidate() {
|
n@162
|
54 var ready = validate();
|
n@162
|
55 if (ready == false) {
|
n@162
|
56 var errMsg = document.getElementById('errorMessage');
|
n@163
|
57 errMsg.textContent = "There were some errors with your XML. Any input boxes highlighted in red are invalid because they are empty or because its ID matches another elements ID. Please fill these in correctly. Any boxes which are yellow are not-invalid but will use the default value.";
|
n@162
|
58 errMsg.style.visibility = 'visible';
|
n@162
|
59 document.getElementById('createXML').disabled = true;
|
n@162
|
60
|
n@162
|
61 } else {
|
n@162
|
62 var errMsg = document.getElementById('errorMessage');
|
n@162
|
63 errMsg.textContent = "";
|
n@162
|
64 errMsg.style.visiblity = 'hidden';
|
n@162
|
65 document.getElementById('createXML').disabled = false;
|
n@162
|
66 }
|
n@162
|
67 }
|
n@162
|
68
|
n@163
|
69 function buttonClickedSubmit() {
|
n@163
|
70 var ready = validate();
|
n@163
|
71 if (ready == true) {
|
n@167
|
72 var xmlDoc = buildXML();
|
n@167
|
73 var inject = document.getElementById('errorMessage');
|
n@167
|
74 createProjectSave(xmlDoc, inject);
|
n@167
|
75 }
|
n@167
|
76 }
|
n@167
|
77
|
n@167
|
78 function createProjectSave(xmlDoc, injectPoint) {
|
n@167
|
79 var parent = document.createElement("div");
|
n@167
|
80 parent.appendChild(xmlDoc);
|
n@167
|
81 var file = [parent.innerHTML];
|
n@167
|
82 var bb = new Blob(file,{type : 'application/xml'});
|
n@167
|
83 var dnlk = window.URL.createObjectURL(bb);
|
n@167
|
84 var a = document.createElement("a");
|
n@167
|
85 a.hidden = '';
|
n@167
|
86 a.href = dnlk;
|
n@167
|
87 a.download = "save.xml";
|
n@167
|
88 a.textContent = "Save File";
|
n@167
|
89 injectPoint.appendChild(a);
|
n@167
|
90 }
|
n@167
|
91
|
n@167
|
92 function buildXML() {
|
n@167
|
93 var xmlDoc = document.createElement('BrowserEvalProjectDocument');
|
n@167
|
94 var setup = document.createElement('setup');
|
n@167
|
95 setup.setAttribute('interface',document.getElementById('interface').value);
|
n@167
|
96 if (document.getElementById('projectReturn').value == "") {
|
n@167
|
97 setup.setAttribute('projectReturn',"null");
|
n@167
|
98 } else {
|
n@167
|
99 setup.setAttribute('projectReturn',document.getElementById('projectReturn').value);
|
n@167
|
100 }
|
n@167
|
101 setup.setAttribute('randomiseOrder',document.getElementById('randomisePageOrder').checked);
|
n@167
|
102 setup.setAttribute('collectMetrics',document.getElementById('collectMetrics').checked);
|
n@167
|
103
|
n@167
|
104 var globalPreTest = document.createElement('preTest');
|
n@167
|
105 var options = document.getElementById('globalPreTest').getElementsByClassName('head');
|
n@167
|
106 constructPrePost(globalPreTest, options);
|
n@167
|
107
|
n@167
|
108 var globalPostTest = document.createElement('postTest');
|
n@167
|
109 options = document.getElementById('globalPostTest').getElementsByClassName('head');
|
n@167
|
110 constructPrePost(globalPostTest, options);
|
n@167
|
111
|
n@167
|
112 var globalMetrics = document.createElement('metric');
|
n@167
|
113 options = document.getElementById('globalMetric').getElementsByClassName('attrib')[0].getElementsByTagName('input');
|
n@167
|
114 for (var i=0; i<options.length; i++) {
|
n@167
|
115 if (options[i].checked) {
|
n@167
|
116 var metric = document.createElement('metricEnable');
|
n@167
|
117 metric.textContent = options[i].id;
|
n@167
|
118 globalMetrics.appendChild(metric);
|
n@163
|
119 }
|
n@167
|
120 }
|
n@167
|
121 setup.appendChild(globalPreTest);
|
n@167
|
122 setup.appendChild(globalPostTest);
|
n@167
|
123 setup.appendChild(globalMetrics);
|
n@167
|
124 xmlDoc.appendChild(setup);
|
n@167
|
125
|
n@167
|
126 var audioHolders = document.getElementsByName('audio-holder');
|
n@167
|
127 for (var i=0; i<audioHolders.length; i++) {
|
n@167
|
128 var audioHolder = document.createElement('audioHolder');
|
n@167
|
129 var audioHolderDOM = audioHolders[i];
|
n@167
|
130 var attribs = audioHolderDOM.getElementsByClassName('attrib')[0].getElementsByTagName('input');
|
n@167
|
131 audioHolder.id = attribs[0].value;
|
n@167
|
132 if (attribs[1].value != "") {audioHolder.setAttribute('sampleRate',attribs[1].value);}
|
n@167
|
133 if (attribs[2].value != "") {audioHolder.setAttribute('hostURL',attribs[2].value);}
|
n@167
|
134 audioHolder.setAttribute('randomiseOrder',attribs[3].checked);
|
n@167
|
135 audioHolder.setAttribute('repeatCount',attribs[4].checked);
|
n@167
|
136 audioHolder.setAttribute('loop',attribs[5].checked);
|
n@167
|
137 audioHolder.setAttribute('elementComments',attribs[6].checked);
|
n@163
|
138
|
n@167
|
139 // Audio-Holder PreTests
|
n@167
|
140 var audioHolderPreTest = document.createElement('preTest');
|
n@167
|
141 var audioHolderPostTest = document.createElement('postTest');
|
n@167
|
142 options = audioHolderDOM.childNodes[2].getElementsByClassName('head');
|
n@167
|
143 constructPrePost(audioHolderPreTest, options);
|
n@167
|
144 options = audioHolderDOM.childNodes[3].getElementsByClassName('head');
|
n@167
|
145 constructPrePost(audioHolderPostTest, options);
|
n@163
|
146
|
n@167
|
147 audioHolder.appendChild(audioHolderPreTest);
|
n@167
|
148 audioHolder.appendChild(audioHolderPostTest);
|
n@163
|
149
|
n@172
|
150 // Interface Nodes
|
n@172
|
151
|
n@167
|
152 // audio-Elements
|
n@167
|
153 var audioElementsDOM = [];
|
n@167
|
154 var commentQuestionDOM = [];
|
n@172
|
155 var interfacesDOM = [];
|
n@167
|
156 for (var j=0; j<audioHolderDOM.childElementCount; j++) {
|
n@167
|
157 var child = audioHolderDOM.childNodes[j];
|
n@167
|
158 var name = child.getAttribute('name');
|
n@167
|
159 if (name == 'audio-element') {audioElementsDOM.push(child);}
|
n@167
|
160 else if (name == 'comment-question') {commentQuestionDOM.push(child);}
|
n@172
|
161 else if (name == 'interface-options') {interfacesDOM.push(child);}
|
n@172
|
162 }
|
n@172
|
163
|
n@172
|
164 for (var j=0; j<interfacesDOM.length; j++) {
|
n@172
|
165 var interfaceNode = document.createElement('interface');
|
n@172
|
166 attribs = interfacesDOM[j].getElementsByClassName('attrib')[0].getElementsByTagName('input');
|
n@172
|
167 var title = document.createElement('title');
|
n@172
|
168 title.textContent = attribs[0].value;
|
n@172
|
169 interfaceNode.appendChild(title);
|
n@172
|
170
|
n@172
|
171
|
n@172
|
172 var markers = interfacesDOM[j].getElementsByClassName('head');
|
n@172
|
173 for (var k=0; k<markers.length; k++) {
|
n@172
|
174 var markerNode = document.createElement('scale');
|
n@172
|
175 attribs = markers[k].getElementsByClassName('attrib')[0].getElementsByTagName('input');
|
n@172
|
176 markerNode.textContent = attribs[0].value;
|
n@172
|
177 markerNode.setAttribute('position',attribs[1].value);
|
n@172
|
178 interfaceNode.appendChild(markerNode);
|
n@172
|
179 }
|
n@172
|
180 audioHolder.appendChild(interfaceNode);
|
n@163
|
181 }
|
n@163
|
182
|
n@167
|
183 for (var j=0; j<audioElementsDOM.length; j++) {
|
n@167
|
184 var audioElement = document.createElement('audioElement');
|
n@167
|
185 attribs = audioElementsDOM[j].getElementsByClassName('attrib')[0].getElementsByTagName('input');
|
n@167
|
186 audioElement.id = attribs[0].value;
|
n@167
|
187 audioElement.setAttribute('url',attribs[1].value);
|
n@167
|
188 audioHolder.appendChild(audioElement);
|
n@166
|
189 }
|
n@167
|
190
|
n@167
|
191 for (var j=0; j<commentQuestionDOM.length; j++) {
|
n@167
|
192 var commentQuestion = document.createElement('commentQuestion');
|
n@167
|
193 attribs = commentQuestionDOM[j].getElementsByClassName('attrib')[0].getElementsByTagName('input');
|
n@167
|
194 commentQuestion.id = attribs[0].value;
|
n@167
|
195 commentQuestion.textContent = attribs[1].value;
|
n@167
|
196 audioHolder.appendChild(commentQuestion);
|
n@167
|
197 }
|
n@167
|
198 xmlDoc.appendChild(audioHolder);
|
n@163
|
199 }
|
n@167
|
200 return xmlDoc;
|
n@163
|
201 }
|
n@163
|
202
|
n@163
|
203 function constructPrePost(parent, options) {
|
n@163
|
204 for (var i=0; i<options.length; i++) {
|
n@163
|
205 var elem = options[i];
|
n@163
|
206 var attributes = elem.getElementsByClassName('attrib')[0].getElementsByTagName('input');
|
n@163
|
207 if (elem.getAttribute('name') == 'question-node') {
|
n@163
|
208 var node = document.createElement('question');
|
n@163
|
209 node.setAttribute('id',attributes[0].value);
|
n@163
|
210 node.textContent = attributes[1].value;
|
n@169
|
211 node.setAttribute('mandatory',attributes[2].checked);
|
n@163
|
212 } else if (elem.getAttribute('name') == 'statement-node') {
|
n@169
|
213 var node = document.createElement('statement');
|
n@163
|
214 node.textContent = attributes[0].value;
|
n@163
|
215 }
|
n@163
|
216 parent.appendChild(node);
|
n@163
|
217 }
|
n@163
|
218 }
|
n@163
|
219
|
n@162
|
220 function validate() {
|
n@162
|
221 var canExport = true;
|
n@162
|
222 // Checks if the XML can be created from the given entries
|
n@162
|
223 var inputs = document.getElementsByTagName('input');
|
n@162
|
224 for (var i=0; i<inputs.length; i++) {
|
n@162
|
225 if (inputs[i].type == 'text') {
|
n@162
|
226 if (inputs[i].value == "") {
|
n@162
|
227 var mandatory = inputs[i].getAttribute('mandatory');
|
n@162
|
228 if (mandatory == "true") {
|
n@162
|
229 errorInput(inputs[i]);
|
n@162
|
230 canExport = false;
|
n@162
|
231 } else {
|
n@162
|
232 warningInput(inputs[i]);
|
n@162
|
233 }
|
n@162
|
234 } else {
|
n@162
|
235 goodInput(inputs[i]);
|
n@162
|
236 }
|
n@162
|
237 }
|
n@162
|
238 }
|
n@163
|
239
|
n@163
|
240 var audioHolders = document.getElementsByName('audio-holder');
|
n@163
|
241 for (var i=0; i<audioHolders.length; i++) {
|
n@163
|
242 var divs = audioHolders[i].getElementsByClassName('head');
|
n@163
|
243 var IDs = [];
|
n@163
|
244 for (var j=0; j<divs.length; j++) {
|
n@163
|
245 if (divs[j].getAttribute('name') == 'audio-element') {
|
n@163
|
246 var obj = divs[j].getElementsByClassName('attrib')[0].children[1];
|
n@163
|
247 var aeID = obj.value;
|
n@163
|
248 if (aeID != "") {
|
n@163
|
249 var unique = true;
|
n@163
|
250 for (var k=0; k<IDs.length; k++) {
|
n@163
|
251 if (aeID == IDs[k]) {
|
n@163
|
252 unique = false;
|
n@163
|
253 break;
|
n@163
|
254 }
|
n@163
|
255 }
|
n@163
|
256 if (unique == true) {
|
n@163
|
257 IDs.push(aeID);
|
n@163
|
258 } else {
|
n@163
|
259 errorInput(obj);
|
n@163
|
260 canExport = false;
|
n@163
|
261 }
|
n@163
|
262 }
|
n@163
|
263 }
|
n@163
|
264 }
|
n@163
|
265 }
|
n@162
|
266 return canExport;
|
n@162
|
267 };
|
n@162
|
268
|
n@162
|
269 function errorInput(node) {
|
n@162
|
270 node.style.backgroundColor = "#FF0000";
|
n@162
|
271 }
|
n@162
|
272
|
n@162
|
273 function warningInput(node) {
|
n@162
|
274 node.style.backgroundColor = "#FFFF00";
|
n@162
|
275 }
|
n@162
|
276
|
n@162
|
277 function goodInput(node) {
|
n@162
|
278 node.style.backgroundColor = "#FFFFFF";
|
n@162
|
279 }
|
n@162
|
280
|
n@157
|
281 function questionNode() {
|
n@157
|
282 var node = document.createElement("div");
|
n@157
|
283 node.setAttribute('class','head');
|
n@157
|
284 node.setAttribute('name','question-node');
|
n@157
|
285 var nodeTitle = document.createElement("span");
|
n@157
|
286 nodeTitle.textContent = "Question";
|
n@157
|
287 var attributes = document.createElement("div");
|
n@157
|
288 attributes.setAttribute('class','attrib');
|
n@162
|
289 var id = attributePair("ID:","text", true);
|
n@162
|
290 var question = attributePair("Question:","text", false);
|
n@169
|
291 question[1].style.width = "500px";
|
n@169
|
292 var mandatory = attributePair("Mandatory:","checkbox", false);
|
n@157
|
293 node.appendChild(nodeTitle);
|
n@157
|
294 id.forEach(function(item){attributes.appendChild(item);},false);
|
n@157
|
295 question.forEach(function(item){attributes.appendChild(item);},false);
|
n@169
|
296 mandatory.forEach(function(item){attributes.appendChild(item);},false);
|
n@157
|
297 node.appendChild(attributes);
|
n@159
|
298
|
n@159
|
299 var removeButton = document.createElement("button");
|
n@159
|
300 removeButton.textContent = "Remove";
|
n@159
|
301 removeButton.onclick = removeNode;
|
n@159
|
302 node.appendChild(removeButton);
|
n@157
|
303 return node;
|
n@157
|
304 }
|
n@157
|
305
|
n@157
|
306 function statementNode() {
|
n@157
|
307 var node = document.createElement("div");
|
n@157
|
308 node.setAttribute('class','head');
|
n@162
|
309 node.setAttribute('name','statement-node');
|
n@157
|
310 var nodeTitle = document.createElement("span");
|
n@157
|
311 nodeTitle.textContent = "Statement";
|
n@157
|
312 var attributes = document.createElement("div");
|
n@157
|
313 attributes.setAttribute('class','attrib');
|
n@162
|
314 var statement = attributePair("Statement:","text",false);
|
n@169
|
315 statement[1].style.width = "500px";
|
n@157
|
316 node.appendChild(nodeTitle);
|
n@157
|
317 statement.forEach(function(item){attributes.appendChild(item);},false);
|
n@157
|
318 node.appendChild(attributes);
|
n@159
|
319
|
n@159
|
320 var removeButton = document.createElement("button");
|
n@159
|
321 removeButton.textContent = "Remove";
|
n@159
|
322 removeButton.onclick = removeNode;
|
n@159
|
323 node.appendChild(removeButton);
|
n@157
|
324 return node;
|
n@157
|
325 }
|
n@157
|
326
|
n@157
|
327 function audioHolderNode() {
|
n@157
|
328 var audioHolderCounts = document.getElementsByName("audio-holder").length;
|
n@157
|
329 var node = document.createElement("div");
|
n@157
|
330 node.setAttribute("class","head");
|
n@157
|
331 node.setAttribute("name","audio-holder");
|
n@159
|
332 node.setAttribute("id","audio-holder-"+audioHolderCounts);
|
n@157
|
333 var nodeTitle = document.createElement("span");
|
n@159
|
334 nodeTitle.textContent = "Audio Holder "+(audioHolderCounts+1);
|
n@157
|
335
|
n@157
|
336 var attributes = document.createElement("div");
|
n@157
|
337 attributes.setAttribute('class','attrib');
|
n@162
|
338 var id = attributePair("ID:","text",true);
|
n@159
|
339 id[1].value=audioHolderCounts;
|
n@162
|
340 var hostURL = attributePair("Host URL:", "text",false);
|
n@162
|
341 var sampleRate = attributePair("Sample Rate:","text",false);
|
n@159
|
342 var randomiseOrder = attributePair("Randomise Element Order:","checkbox");
|
n@159
|
343 var repeatCount = attributePair("Repeat Page Count:","number");
|
n@159
|
344 repeatCount[1].value = 0;
|
n@159
|
345 var loop = attributePair("Loop Element Playback","checkbox");
|
n@159
|
346 var elementComments = attributePair("Enable Comment Boxes","checkbox");
|
n@159
|
347 id.forEach(function(item){attributes.appendChild(item);},false);
|
n@159
|
348 hostURL.forEach(function(item){attributes.appendChild(item);},false);
|
n@159
|
349 sampleRate.forEach(function(item){attributes.appendChild(item);},false);
|
n@159
|
350 hostURL.forEach(function(item){attributes.appendChild(item);},false);
|
n@159
|
351 randomiseOrder.forEach(function(item){attributes.appendChild(item);},false);
|
n@159
|
352 repeatCount.forEach(function(item){attributes.appendChild(item);},false);
|
n@159
|
353 loop.forEach(function(item){attributes.appendChild(item);},false);
|
n@159
|
354 elementComments.forEach(function(item){attributes.appendChild(item);},false);
|
n@159
|
355
|
n@159
|
356 node.appendChild(nodeTitle);
|
n@159
|
357 node.appendChild(attributes);
|
n@159
|
358
|
n@159
|
359 var pretest = document.createElement("div");
|
n@159
|
360 pretest.setAttribute('class','head');
|
n@159
|
361 pretest.setAttribute('name','pre-test');
|
n@159
|
362 var pretestTitle = document.createElement("h4");
|
n@159
|
363 pretestTitle.textContent = "Pre Test";
|
n@159
|
364 var buttonAddQ = document.createElement("button");
|
n@159
|
365 buttonAddQ.textContent = "Add Pre Test Question";
|
n@159
|
366 buttonAddQ.onclick = function(){event.srcElement.parentElement.appendChild(questionNode());};
|
n@159
|
367 var buttonAddS = document.createElement("button");
|
n@159
|
368 buttonAddS.textContent = "Add Pre Test Statement";
|
n@159
|
369 buttonAddS.onclick = function(){event.srcElement.parentElement.appendChild(statementNode());};
|
n@159
|
370 pretest.appendChild(pretestTitle);
|
n@159
|
371 pretest.appendChild(buttonAddQ);
|
n@159
|
372 pretest.appendChild(buttonAddS);
|
n@159
|
373
|
n@159
|
374 var posttest = document.createElement("div");
|
n@159
|
375 posttest.setAttribute('class','head');
|
n@159
|
376 posttest.setAttribute('name','post-test');
|
n@159
|
377 var posttestTitle = document.createElement("h4");
|
n@159
|
378 posttestTitle.textContent = "Post Test";
|
n@159
|
379 var buttonAddQ = document.createElement("button");
|
n@159
|
380 buttonAddQ.textContent = "Add Post Test Question";
|
n@159
|
381 buttonAddQ.onclick = function(){event.srcElement.parentElement.appendChild(questionNode());};
|
n@159
|
382 var buttonAddS = document.createElement("button");
|
n@159
|
383 buttonAddS.textContent = "Add Post Test Statement";
|
n@159
|
384 buttonAddS.onclick = function(){event.srcElement.parentElement.appendChild(statementNode());};
|
n@159
|
385 posttest.appendChild(posttestTitle);
|
n@159
|
386 posttest.appendChild(buttonAddQ);
|
n@159
|
387 posttest.appendChild(buttonAddS);
|
n@159
|
388
|
n@159
|
389 node.appendChild(pretest);
|
n@159
|
390 node.appendChild(posttest);
|
n@159
|
391
|
n@159
|
392 var newAudioElementButton = document.createElement("button");
|
n@159
|
393 newAudioElementButton.textContent = "Add audio element";
|
n@159
|
394 newAudioElementButton.onclick = function(){
|
n@159
|
395 event.srcElement.parentElement.appendChild(audioElementNode());
|
n@159
|
396 };
|
n@159
|
397 node.appendChild(newAudioElementButton);
|
n@159
|
398
|
n@159
|
399 var newCommentButton = document.createElement("button");
|
n@159
|
400 newCommentButton.textContent = "Add Comment Box";
|
n@159
|
401 newCommentButton.onclick = function() {
|
n@159
|
402 event.srcElement.parentElement.appendChild(commentBox());
|
n@159
|
403 };
|
n@159
|
404 node.appendChild(newCommentButton);
|
n@159
|
405
|
n@172
|
406 var newInterface = document.createElement("button");
|
n@172
|
407 newInterface.textContent = "Add Interface";
|
n@172
|
408 newInterface.onclick = function() {
|
n@172
|
409 event.srcElement.parentElement.appendChild(interfaceNode());
|
n@172
|
410 };
|
n@172
|
411 node.appendChild(newInterface);
|
n@172
|
412
|
n@159
|
413 var removeButton = document.createElement("button");
|
n@159
|
414 removeButton.textContent = "Remove Audio Holder";
|
n@159
|
415 removeButton.onclick = removeNode;
|
n@159
|
416 node.appendChild(removeButton);
|
n@159
|
417 return node;
|
n@159
|
418 }
|
n@159
|
419
|
n@159
|
420 function audioElementNode() {
|
n@159
|
421 var node = document.createElement('div');
|
n@159
|
422 node.setAttribute('class','head');
|
n@159
|
423 node.setAttribute('name','audio-element');
|
n@159
|
424 var nodeTitle = document.createElement('span');
|
n@169
|
425 nodeTitle.textContent = 'Audio Element';
|
n@159
|
426
|
n@159
|
427 var attributes = document.createElement("div");
|
n@159
|
428 attributes.setAttribute('class','attrib');
|
n@162
|
429 var id = attributePair("ID:","text",true);
|
n@162
|
430 var url = attributePair("URL:","text",true);
|
n@159
|
431 id.forEach(function(item){attributes.appendChild(item);},false);
|
n@159
|
432 url.forEach(function(item){attributes.appendChild(item);},false);
|
n@159
|
433
|
n@159
|
434 node.appendChild(nodeTitle);
|
n@159
|
435 node.appendChild(attributes);
|
n@159
|
436
|
n@159
|
437 var removeButton = document.createElement("button");
|
n@159
|
438 removeButton.textContent = "Remove Audio Element";
|
n@159
|
439 removeButton.onclick = removeNode;
|
n@159
|
440 node.appendChild(removeButton);
|
n@159
|
441 return node;
|
n@159
|
442 }
|
n@159
|
443
|
n@159
|
444 function commentBox() {
|
n@159
|
445 var node = document.createElement('div');
|
n@159
|
446 node.setAttribute('class','head');
|
n@159
|
447 node.setAttribute('name','comment-question');
|
n@159
|
448 var nodeTitle = document.createElement('h4');
|
n@159
|
449 nodeTitle.textContent = "Comment Box";
|
n@159
|
450
|
n@159
|
451 var attributes = document.createElement('div');
|
n@159
|
452 attributes.setAttribute('class','attrib');
|
n@162
|
453 var id = attributePair("ID:",'text',true);
|
n@162
|
454 var question = attributePair("Question:",'text',true);
|
n@169
|
455 question[1].style.width = "500px";
|
n@159
|
456 id.forEach(function(item){attributes.appendChild(item);},false);
|
n@159
|
457 question.forEach(function(item){attributes.appendChild(item);},false);
|
n@159
|
458
|
n@159
|
459 var removeButton = document.createElement("button");
|
n@159
|
460 removeButton.textContent = "Remove Comment Box";
|
n@159
|
461 removeButton.onclick = removeNode;
|
n@159
|
462
|
n@159
|
463 node.appendChild(nodeTitle);
|
n@159
|
464 node.appendChild(attributes);
|
n@159
|
465 node.appendChild(removeButton);
|
n@159
|
466 return node;
|
n@157
|
467 }
|
n@168
|
468
|
n@172
|
469 function interfaceNode() {
|
n@172
|
470 var selectedInterface = document.getElementById('interface').value;
|
n@172
|
471 var node = document.createElement('div');
|
n@172
|
472 node.setAttribute('class','head');
|
n@172
|
473 node.setAttribute('name','interface-options');
|
n@172
|
474 var nodeTitle = document.createElement('h4');
|
n@172
|
475 nodeTitle.textContent = "Interface";
|
n@172
|
476
|
n@172
|
477 var attributes = document.createElement('div');
|
n@172
|
478 attributes.setAttribute('class','attrib');
|
n@172
|
479 var title = attributePair('Title: ','text',false);
|
n@172
|
480 title[1].style.width = "500px";
|
n@172
|
481
|
n@172
|
482 var addMarker = document.createElement('button');
|
n@172
|
483 addMarker.textContent = "Add Scale Marker";
|
n@172
|
484 addMarker.onclick = function() {
|
n@172
|
485 event.srcElement.parentElement.appendChild(newScaleMarker());
|
n@172
|
486 };
|
n@172
|
487
|
n@172
|
488 title.forEach(function(item){attributes.appendChild(item);},false);
|
n@172
|
489
|
n@172
|
490 var removeButton = document.createElement("button");
|
n@172
|
491 removeButton.textContent = "Remove Interface";
|
n@172
|
492 removeButton.onclick = removeNode;
|
n@172
|
493
|
n@172
|
494 node.appendChild(nodeTitle);
|
n@172
|
495 node.appendChild(attributes);
|
n@172
|
496 node.appendChild(addMarker);
|
n@172
|
497 node.appendChild(removeButton);
|
n@172
|
498 return node;
|
n@172
|
499 }
|
n@172
|
500
|
n@172
|
501 function newScaleMarker() {
|
n@172
|
502 var node = document.createElement('div');
|
n@172
|
503 node.setAttribute('class','head');
|
n@172
|
504 node.setAttribute('name','interface-options');
|
n@172
|
505 var nodeTitle = document.createElement('span');
|
n@172
|
506 nodeTitle.textContent = "Marker";
|
n@172
|
507 var attributes = document.createElement('div');
|
n@172
|
508 attributes.setAttribute('class','attrib');
|
n@172
|
509 var text = attributePair('Text: ','text',true);
|
n@172
|
510 var position = attributePair('Positon','number',true);
|
n@172
|
511
|
n@172
|
512 text.forEach(function(item){attributes.appendChild(item);},false);
|
n@172
|
513 position.forEach(function(item){attributes.appendChild(item);},false);
|
n@172
|
514
|
n@172
|
515 var removeButton = document.createElement("button");
|
n@172
|
516 removeButton.textContent = "Remove Marker";
|
n@172
|
517 removeButton.onclick = removeNode;
|
n@172
|
518
|
n@172
|
519 node.appendChild(nodeTitle);
|
n@172
|
520 node.appendChild(attributes);
|
n@172
|
521 node.appendChild(removeButton);
|
n@172
|
522 return node;
|
n@172
|
523 }
|
n@168
|
524
|
n@168
|
525 function handleDragOver(e) {
|
n@168
|
526 e.stopPropagation();
|
n@168
|
527 e.preventDefault();
|
n@168
|
528 }
|
n@168
|
529 function handleDragEnter(e) {
|
n@168
|
530 e.stopPropagation();
|
n@168
|
531 e.preventDefault();
|
n@168
|
532 this.style.backgroundColor = '#AAFFAA';
|
n@168
|
533 }
|
n@168
|
534 function handleDragLeave(e) {
|
n@168
|
535 e.stopPropagation();
|
n@168
|
536 e.preventDefault();
|
n@168
|
537 this.style.backgroundColor = "#FFFFFF";
|
n@168
|
538 }
|
n@168
|
539 function handleDrop(e) {
|
n@168
|
540 e.stopPropagation();
|
n@168
|
541 e.preventDefault();
|
n@168
|
542
|
n@168
|
543 var file = e.dataTransfer.files[0];
|
n@168
|
544
|
n@168
|
545 // Uses HTML5 FileAPI - https://w3c.github.io/FileAPI/#filereader-interface
|
n@168
|
546 var reader = new FileReader();
|
n@169
|
547 reader.onload = function() {
|
n@169
|
548 var parse = new DOMParser();
|
n@169
|
549 var xml = parse.parseFromString(reader.result,'text/xml');
|
n@169
|
550 importXML(xml);
|
n@169
|
551 };
|
n@168
|
552 reader.readAsText(file);
|
n@169
|
553
|
n@168
|
554 }
|
n@169
|
555 var g_XML;
|
n@168
|
556
|
n@168
|
557 function importXML(xml) {
|
n@169
|
558 g_XML = xml;
|
n@169
|
559
|
n@169
|
560 var root = xml.getElementsByTagName('BrowserEvalProjectDocument')[0];
|
n@169
|
561 var setup = xml.getElementsByTagName('setup')[0];
|
n@169
|
562 document.getElementById('interface').value = setup.getAttribute('interface');
|
n@169
|
563 document.getElementById('projectReturn').value = setup.getAttribute('projectReturn');
|
n@169
|
564 document.getElementById('randomisePageOrder').checked = setup.getAttribute('randomiseOrder');
|
n@169
|
565 document.getElementById('collectMetrics').checked = setup.getAttribute('collectMetrics');
|
n@169
|
566
|
n@169
|
567 var globalPreTest = setup.getElementsByTagName('PreTest')[0];
|
n@169
|
568 var globalPostTest = setup.getElementsByTagName('PostTest')[0];
|
n@169
|
569 for (var i=0; i<globalPreTest.childElementCount; i++) {
|
n@169
|
570 var child = globalPreTest.children[i];
|
n@169
|
571 var node;
|
n@169
|
572 if (child.nodeName == "question") {
|
n@169
|
573 node = questionNode();
|
n@169
|
574 var attribs = node.getElementsByClassName('attrib')[0].getElementsByTagName('input');
|
n@169
|
575 attribs[0].value = child.id;
|
n@169
|
576 attribs[1].value = child.textContent;
|
n@169
|
577 attribs[2].checked = child.getAttribute('mandatory');
|
n@169
|
578 } else if (child.nodeName == "statement") {
|
n@169
|
579 node = statementNode();
|
n@169
|
580 var attribs = node.getElementsByClassName('attrib')[0].getElementsByTagName('input');
|
n@169
|
581 attribs[0].value = child.textContent;
|
n@169
|
582 }
|
n@169
|
583 document.getElementById('globalPreTest').appendChild(node);
|
n@169
|
584 }
|
n@169
|
585
|
n@169
|
586 for (var i=0; i<globalPostTest.childElementCount; i++) {
|
n@169
|
587 var child = globalPostTest.children[i];
|
n@169
|
588 var node;
|
n@169
|
589 if (child.nodeName == "question") {
|
n@169
|
590 node = questionNode();
|
n@169
|
591 var attribs = node.getElementsByClassName('attrib')[0].getElementsByTagName('input');
|
n@169
|
592 attribs[0].value = child.id;
|
n@169
|
593 attribs[1].value = child.textContent;
|
n@169
|
594 attribs[2].checked = child.getAttribute('mandatory');
|
n@169
|
595 } else if (child.nodeName == "statement") {
|
n@169
|
596 node = statementNode();
|
n@169
|
597 var attribs = node.getElementsByClassName('attrib')[0].getElementsByTagName('input');
|
n@169
|
598 attribs[0].value = child.textContent;
|
n@169
|
599 }
|
n@169
|
600 document.getElementById('globalPostTest').appendChild(node);
|
n@169
|
601 }
|
n@169
|
602
|
n@170
|
603 // Metric Enable Flags
|
n@170
|
604 var mEnable = setup.getElementsByTagName('Metric')[0].getElementsByTagName('metricEnable');
|
n@170
|
605 for (var i=0; i<mEnable.length; i++) {
|
n@170
|
606 var node = mEnable[i];
|
n@170
|
607 var enabled = node.textContent;
|
n@170
|
608 document.getElementById(enabled).checked = true;
|
n@170
|
609 }
|
n@170
|
610
|
n@169
|
611 var audioHolders = root.getElementsByTagName('audioHolder');
|
n@169
|
612 for (var i=0; i<audioHolders.length; i++) {
|
n@169
|
613 var audioHolderDOM = audioHolderNode();
|
n@169
|
614 var attribs = audioHolderDOM.getElementsByClassName('attrib')[0].getElementsByTagName('input');
|
n@169
|
615 attribs[0].value = audioHolders[i].id;
|
n@169
|
616 attribs[1].value = audioHolders[i].getAttribute('sampleRate');
|
n@169
|
617 attribs[2].value = audioHolders[i].getAttribute('hostURL');
|
n@169
|
618 attribs[3].checked = audioHolders[i].getAttribute('randomiseOrder');
|
n@169
|
619 attribs[4].value = audioHolders[i].getAttribute('repeatCount');
|
n@169
|
620 attribs[5].checked = audioHolders[i].getAttribute('loop');
|
n@169
|
621 attribs[6].checked = audioHolders[i].getAttribute('elementComments');
|
n@169
|
622
|
n@169
|
623 var PreTest = audioHolders[i].getElementsByTagName('PreTest');
|
n@169
|
624 var PostTest = audioHolders[i].getElementsByTagName('PostTest');
|
n@169
|
625 if (PreTest.length != 0) {
|
n@169
|
626 PreTest = PreTest[0];
|
n@169
|
627 for (var j=0; j<PreTest.childElementCount; j++) {
|
n@169
|
628 var child = PreTest.children[j];
|
n@169
|
629 var node;
|
n@169
|
630 if (child.nodeName == "question") {
|
n@169
|
631 node = questionNode();
|
n@169
|
632 var attribs = node.getElementsByClassName('attrib')[0].getElementsByTagName('input');
|
n@169
|
633 attribs[0].value = child.id;
|
n@169
|
634 attribs[1].value = child.textContent;
|
n@169
|
635 attribs[2].checked = child.getAttribute('mandatory');
|
n@169
|
636 } else if (child.nodeName == "statement") {
|
n@169
|
637 node = statementNode();
|
n@169
|
638 var attribs = node.getElementsByClassName('attrib')[0].getElementsByTagName('input');
|
n@169
|
639 attribs[0].value = child.textContent;
|
n@169
|
640 }
|
n@169
|
641 audioHolderDOM.children[2].appendChild(node);
|
n@169
|
642 }
|
n@169
|
643 }
|
n@169
|
644 if (PostTest.length != 0) {
|
n@169
|
645 PostTest = PostTest[0];
|
n@169
|
646 for (var j=0; j<PostTest.childElementCount; j++) {
|
n@169
|
647 var child = PostTest.children[j];
|
n@169
|
648 var node;
|
n@169
|
649 if (child.nodeName == "question") {
|
n@169
|
650 node = questionNode();
|
n@169
|
651 var attribs = node.getElementsByClassName('attrib')[0].getElementsByTagName('input');
|
n@169
|
652 attribs[0].value = child.id;
|
n@169
|
653 attribs[1].value = child.textContent;
|
n@169
|
654 attribs[2].checked = child.getAttribute('mandatory');
|
n@169
|
655 } else if (child.nodeName == "statement") {
|
n@169
|
656 node = statementNode();
|
n@169
|
657 var attribs = node.getElementsByClassName('attrib')[0].getElementsByTagName('input');
|
n@169
|
658 attribs[0].value = child.textContent;
|
n@169
|
659 }
|
n@169
|
660 audioHolderDOM.children[3].appendChild(node);
|
n@169
|
661 }
|
n@169
|
662 }
|
n@172
|
663 // Process interface
|
n@172
|
664 var interfaceNodes = audioHolders[i].getElementsByTagName('interface');
|
n@172
|
665 for (var j=0; j<interfaceNodes.length; j++) {
|
n@172
|
666 var node = interfaceNode();
|
n@172
|
667 var child = interfaceNodes[j];
|
n@172
|
668 var attribs = node.getElementsByClassName('attrib')[0].getElementsByTagName('input');
|
n@172
|
669 attribs[0].value = child.getElementsByTagName('title')[0].textContent;
|
n@172
|
670
|
n@172
|
671 var markers = child.getElementsByTagName('scale');
|
n@172
|
672 for (var k=0; k<markers.length; k++) {
|
n@172
|
673 var markerNode = newScaleMarker();
|
n@172
|
674 attribs = markerNode.getElementsByClassName('attrib')[0].getElementsByTagName('input');
|
n@172
|
675 attribs[0].value = markers[k].textContent;
|
n@172
|
676 attribs[1].value = markers[k].getAttribute('position');
|
n@172
|
677 node.appendChild(markerNode);
|
n@172
|
678 }
|
n@172
|
679 audioHolderDOM.appendChild(node);
|
n@172
|
680 }
|
n@172
|
681
|
n@169
|
682
|
n@169
|
683 // Process audio-element
|
n@169
|
684 var audioElements = audioHolders[i].getElementsByTagName('audioElements');
|
n@169
|
685 for (var j=0; j<audioElements.length; j++) {
|
n@169
|
686 var node = audioElementNode();
|
n@169
|
687 var child = audioElements[j];
|
n@169
|
688 var attribs = node.getElementsByClassName('attrib')[0].getElementsByTagName('input');
|
n@169
|
689 attribs[0].value = child.id;
|
n@169
|
690 attribs[1].value = child.getAttribute('url');
|
n@169
|
691 audioHolderDOM.appendChild(node);
|
n@169
|
692 }
|
n@169
|
693
|
n@169
|
694 // Process comment-question
|
n@169
|
695 var commentQuestion = audioHolders[0].getElementsByTagName('CommentQuestion');
|
n@169
|
696 for (var j=0; j<commentQuestion.length; j++) {
|
n@169
|
697 var node = commentBox();
|
n@169
|
698 var child = commentQuestion[j];
|
n@169
|
699 var attribs = node.getElementsByClassName('attrib')[0].getElementsByTagName('input');
|
n@169
|
700 attribs[0].value = child.id;
|
n@169
|
701 attribs[1].value = child.textContent;
|
n@169
|
702 audioHolderDOM.appendChild(node);
|
n@169
|
703 }
|
n@169
|
704
|
n@169
|
705 document.getElementById('setup').appendChild(audioHolderDOM);
|
n@169
|
706 }
|
n@168
|
707 }
|
n@157
|
708 </script>
|
n@157
|
709 <style>
|
n@157
|
710 div {
|
n@157
|
711 padding: 2px;
|
n@157
|
712 margin-top: 2px;
|
n@157
|
713 margin-bottom: 2px;
|
n@157
|
714 }
|
n@157
|
715 div.head{
|
n@157
|
716 margin-left: 10px;
|
n@157
|
717 border: black;
|
n@157
|
718 border-width: 2px;
|
n@157
|
719 border-style: solid;
|
n@157
|
720 }
|
n@157
|
721 div.attrib{
|
n@157
|
722 margin-left:25px;
|
n@157
|
723 border: black;
|
n@157
|
724 border-width: 2px;
|
n@157
|
725 border-style: dashed;
|
n@157
|
726 margin-bottom: 10px;
|
n@157
|
727 }
|
n@168
|
728 div#dragFile{
|
n@168
|
729 height:100px;
|
n@168
|
730 border-width: 2px;
|
n@168
|
731 border-style: dashed;
|
n@168
|
732 margin-bottom: 10px;
|
n@168
|
733 }
|
n@157
|
734 </style>
|
n@157
|
735
|
n@156
|
736 </head>
|
n@156
|
737
|
n@156
|
738 <body>
|
n@157
|
739 <h1>Create Test Setup XML</h1>
|
n@168
|
740 <div id="dragFile">
|
n@168
|
741 <span>Drag and Drop an XML specification file here to auto-load.</span>
|
n@168
|
742 </div>
|
n@162
|
743 <button id="validateXML" onclick="buttonClickedValidate();">Validate</button>
|
n@167
|
744 <button id="createXML" onclick="buttonClickedSubmit();" disabled>Submit</button>
|
n@162
|
745 <span id="errorMessage" visibility="hidden"></span>
|
n@157
|
746 <div id="topLevelBody" align="left">
|
n@156
|
747 <!-- Interface goes here -->
|
n@157
|
748 <div name='test-setup'>
|
n@157
|
749 <div id="setup" class="head">
|
n@157
|
750 <h2>Setup Tag</h2>
|
n@157
|
751 <div id="setup-attribs" class="attrib">
|
n@157
|
752 <span>Interface</span>
|
n@157
|
753 <select id="interface">
|
n@157
|
754 <option value='APE'>APE</option>
|
n@157
|
755 </select>
|
n@157
|
756 <span>Project Return</span>
|
n@162
|
757 <input type="text" id="projectReturn" mandatory="false">
|
n@157
|
758 <span>Randomise Test Page Order</span>
|
n@157
|
759 <input id="randomisePageOrder" type="checkbox" value="false">
|
n@157
|
760 <span>Collect Session Metrics</span>
|
n@157
|
761 <input id="collectMetrics" type="checkbox">
|
n@157
|
762 </div>
|
n@157
|
763 <div id="globalPreTest" class="head">
|
n@157
|
764 <h3>Pre Test</h3>
|
n@157
|
765 <button id="addPreTestQ" onclick="event.srcElement.parentElement.appendChild(questionNode());">Add Pre Test Question</button>
|
n@157
|
766 <button id="addPreTestS" onclick="event.srcElement.parentElement.appendChild(statementNode());">Add Pre Test Statement</button>
|
n@157
|
767 </div>
|
n@157
|
768 <div id="globalPostTest" class="head">
|
n@157
|
769 <h3>Post Test</h3>
|
n@157
|
770 <button id="addPreTestQ" onclick="event.srcElement.parentElement.appendChild(questionNode());">Add Post Test Question</button>
|
n@157
|
771 <button id="addPreTestS" onclick="event.srcElement.parentElement.appendChild(statementNode());">Add Post Test Statement</button>
|
n@157
|
772 </div>
|
n@157
|
773 <div id="globalMetric" class="head">
|
n@157
|
774 <h3>Global Metrics</h3>
|
n@157
|
775 <div id="globalMetric-attrib" class="attrib">
|
n@157
|
776 <span>Test Timer</span>
|
n@157
|
777 <input type="checkbox" id="testTimer" />
|
n@157
|
778 <span>Element Playback Timer</span>
|
n@157
|
779 <input type="checkbox" id="elementTimer" />
|
n@157
|
780 <span>Element Initial Position</span>
|
n@157
|
781 <input type="checkbox" id="elementInitialPosition" />
|
n@157
|
782 <span>Element Tracker</span>
|
n@157
|
783 <input type="checkbox" id="elementTracker" />
|
n@170
|
784 <span>Element Listen Tracker</span>
|
n@170
|
785 <input type="checkbox" id="elementListenTracker" />
|
n@157
|
786 <span>Element Flag Listened To</span>
|
n@163
|
787 <input type="checkbox" id="elementFlagListenedTo" />
|
n@157
|
788 <span>Element Flag Moved</span>
|
n@157
|
789 <input type="checkbox" id="elementFlagMoved" />
|
n@157
|
790 </div>
|
n@157
|
791 </div>
|
n@159
|
792 <button id="addAudioHolder" onclick="event.srcElement.parentElement.appendChild(audioHolderNode());">Add AudioHolder / Test Page</button>
|
n@157
|
793 </div>
|
n@157
|
794 </div>
|
n@156
|
795 </div>
|
n@156
|
796 </body>
|
n@156
|
797 </html>
|