annotate test_create/test_create.html @ 869:02ca9ef612c3

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