annotate test_create/test_create.html @ 311:f46398fdf56c Dev_main

Updating test create using questions
author Nicholas Jillings <n.g.r.jillings@se14.qmul.ac.uk>
date Wed, 23 Sep 2015 11:42:11 +0100
parents 0518fc661e7b
children f73d9333ab0d
rev   line source
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@311 10 <title>WAET: Test Creator</title>
n@156 11
n@156 12 <meta name="viewport" content="width=device-width; initial-scale=1.0">
n@311 13 <script type="text/javascript">
n@157 14
n@311 15 var APEInterfaceOptions = [["playhead","page-count"],["Show the playhead/scrubber bar", "Show test page count"]];
n@311 16 var APEInterfaceChecks = [["fragmentPlayed","fragmentFullPlayback","fragmentMoved","fragmentComments"],["All Fragments Played","All Fragments Played in entirety","All sliders moved","All fragments have comments"]];
n@311 17 var MUSHRAInterfaceOptions = [[],[]];
n@311 18 var MUSHRAInterfaceChecks = [["fragmentPlayed","fragmentMoved","fragmentComments"],["All Fragments Played","All sliders moved","All fragments have comments"]];
n@311 19 var popupInstance;
n@311 20 var specificationNode;
n@311 21 var audioContext;
n@311 22 window.onload = function()
n@311 23 {
n@311 24 var AudioContext = window.AudioContext || window.webkitAudioContext;
n@311 25 audioContext = new AudioContext;
n@311 26 popupInstance = new popup();
n@311 27 popupInstance.advanceState();
n@311 28 specificationNode = new Specification();
n@157 29 };
n@157 30
n@311 31 function popup()
n@311 32 {
n@311 33 var x = window.innerWidth;
n@311 34 var y = window.innerHeight;
n@311 35 this.popupHolder = document.createElement('div');
n@311 36 this.popupHolder.style.visibility = 'hidden';
n@311 37 this.popupContent = document.createElement('div');
n@311 38 this.popupTitle = document.createElement('div');
n@311 39 this.popupBody = document.createElement('div');
n@311 40 this.popupFooter = document.createElement('div');
n@311 41 this.popupTitleText = document.createElement('span');
n@311 42 this.popupTitle.appendChild(this.popupTitleText);
n@311 43
n@311 44 this.popupHolder.className = "popup";
n@311 45 this.popupHolder.style.left = (x-500)/2 +'px';
n@311 46 this.popupHolder.style.top = (y-400)/2 + 'px';
n@311 47 this.popupContent.style.padding = "20px";
n@311 48 this.popupHolder.appendChild(this.popupContent);
n@311 49
n@311 50 this.popupTitle.style.width = "100%";
n@311 51 this.popupTitle.style.height = "50px";
n@311 52 this.popupTitle.style.fontSize = "xx-large";
n@311 53 this.popupContent.appendChild(this.popupTitle);
n@311 54
n@311 55 this.popupBody.style.width = "100%";
n@311 56 this.popupBody.style.height = "280px";
n@311 57 this.popupContent.appendChild(this.popupBody);
n@311 58
n@311 59 this.popupFooter.style.width = "100%";
n@311 60 this.popupFooter.style.height = "30px";
n@311 61 this.popupContent.appendChild(this.popupFooter);
n@311 62 var body = document.getElementsByTagName('body')[0];
n@311 63 body.appendChild(this.popupHolder);
n@311 64
n@311 65 this.pageBlank = document.createElement('div');
n@311 66 body.appendChild(this.pageBlank);
n@311 67 this.pageBlank.style.width = "100%";
n@311 68 this.pageBlank.style.height = "100%";
n@311 69 this.pageBlank.style.position = "absolute";
n@311 70 this.pageBlank.style.left = "0px";
n@311 71 this.pageBlank.style.top = "0px";
n@311 72 this.pageBlank.style.backgroundColor = "rgba(0,0,0,0.5)";
n@311 73 this.pageBlank.style.visibility = 'hidden';
n@311 74
n@311 75 this.state = 0;
n@311 76
n@311 77 this.showPopup = function()
n@311 78 {
n@311 79 this.popupHolder.style.visibility = 'visible';
n@311 80 this.popupHolder.style.zIndex = "3";
n@311 81 this.pageBlank.style.visibility = 'visible';
n@311 82 this.pageBlank.style.zIndex = "2";
n@311 83 };
n@311 84
n@311 85 this.hidePopup = function()
n@311 86 {
n@311 87 this.popupHolder.style.visibility = 'hidden';
n@311 88 this.popupHolder.style.zIndex = "-1";
n@311 89 this.pageBlank.style.visibility = 'hidden';
n@311 90 this.pageBlank.style.zIndex = "-2";
n@311 91 };
n@311 92
n@311 93 this.init = function()
n@311 94 {
n@311 95 this.popupTitleText.textContent = "Welcome";
n@311 96 var text = document.createElement('span');
n@311 97 text.textContent = "Thank you for downloading the Web Audio Evaluation Toolbox. This page will help guide you through creating the documents required to run a test. If you have an existing XML file you wish to edit, please drag and drop it into the box below";
n@311 98 var dnd = document.createElement('div');
n@311 99 dnd.style.width = "100%";
n@311 100 dnd.style.height = "50px";
n@311 101 dnd.className = "dragndrop";
n@311 102 this.popupBody.appendChild(text);
n@311 103 this.popupBody.appendChild(dnd);
n@311 104 this.showPopup();
n@311 105
n@311 106 var button = document.createElement('button');
n@311 107 button.className = "popupButton";
n@311 108 button.textContent = "New File";
n@311 109 button.onclick = function(event) {
n@311 110 popupInstance.advanceState();
n@311 111 };
n@311 112 this.popupFooter.appendChild(button);
n@311 113 };
n@311 114
n@311 115 this.advanceState = function()
n@311 116 {
n@311 117 this.popupBody.innerHTML = null;
n@311 118 this.popupFooter.innerHTML = null;
n@311 119 this.popupTitleText.textContent = null;
n@311 120 switch(this.state)
n@311 121 {
n@311 122 case 0:
n@311 123 this.init();
n@311 124 break;
n@311 125 case 1:
n@311 126 this.popupTitleText.textContent = "Test Type";
n@311 127 var text = document.createElement("span");
n@311 128 text.textContent = "What type of test would you like to use. Currently APE (Audio Perceptual Evaluation) and MUSHRA style interfaces are available";
n@311 129 this.popupBody.appendChild(text);
n@311 130 var select = document.createElement("select");
n@311 131 select.id="interface-select";
n@311 132 var opt1 = document.createElement("option");
n@311 133 opt1.value = "APE";
n@311 134 opt1.textContent = "APE";
n@311 135 select.appendChild(opt1);
n@311 136 var opt2 = document.createElement("option");
n@311 137 opt2.value = "MUSHRA";
n@311 138 opt2.textContent = "MUSHRA";
n@311 139 select.appendChild(opt2);
n@311 140 this.popupBody.appendChild(select);
n@311 141
n@311 142 var button = document.createElement('button');
n@311 143 button.className = "popupButton";
n@311 144 button.textContent = "Submit";
n@311 145 button.onclick = function(event) {
n@311 146 var select = document.getElementById("interface-select");
n@311 147 specificationNode.interfaceType = select.value;
n@311 148 specificationNode.collectMetrics = true;
n@311 149 popupInstance.advanceState();
n@311 150 };
n@311 151 this.popupFooter.appendChild(button);
n@311 152 break;
n@311 153 case 2:
n@311 154 this.popupTitleText.textContent = "Test Options";
n@311 155 var holder = document.createElement('div');
n@311 156 holder.style.margin = "5px";
n@311 157 var checkbox = document.createElement('input');
n@311 158 checkbox.type = 'checkbox';
n@311 159 checkbox.id = "Randomise-Page";
n@311 160 var text = document.createElement('span');
n@311 161 text.textContent = "Randomise Page Order";
n@311 162 holder.appendChild(checkbox);
n@311 163 holder.appendChild(text);
n@311 164 this.popupBody.appendChild(holder);
n@311 165 switch(specificationNode.interfaceType)
n@311 166 {
n@311 167 case "APE":
n@311 168 for (var i=0; i<APEInterfaceOptions[0].length; i++)
n@311 169 {
n@311 170 holder = document.createElement('div');
n@311 171 holder.style.margin = "5px";
n@311 172 checkbox = document.createElement('input');
n@311 173 checkbox.type = 'checkbox';
n@311 174 checkbox.setAttribute("name","option");
n@311 175 checkbox.id = APEInterfaceOptions[0][i];
n@311 176 text = document.createElement('span');
n@311 177 text.textContent = APEInterfaceOptions[1][i];
n@311 178 holder.appendChild(checkbox);
n@311 179 holder.appendChild(text);
n@311 180 this.popupBody.appendChild(holder);
n@311 181 }
n@311 182 for (var i=0; i<APEInterfaceChecks[0].length; i++)
n@311 183 {
n@311 184 holder = document.createElement('div');
n@311 185 holder.style.margin = "5px";
n@311 186 checkbox = document.createElement('input');
n@311 187 checkbox.type = 'checkbox';
n@311 188 checkbox.setAttribute("name","check");
n@311 189 checkbox.id = APEInterfaceChecks[0][i];
n@311 190 text = document.createElement('span');
n@311 191 text.textContent = APEInterfaceChecks[1][i];
n@311 192 holder.appendChild(checkbox);
n@311 193 holder.appendChild(text);
n@311 194 this.popupBody.appendChild(holder);
n@311 195 }
n@311 196 break;
n@311 197 case "MUSHRA":
n@311 198 for (var i=0; i<MUSHRAInterfaceOptions[0].length; i++)
n@311 199 {
n@311 200 holder = document.createElement('div');
n@311 201 holder.style.margin = "5px";
n@311 202 checkbox = document.createElement('input');
n@311 203 checkbox.type = 'checkbox';
n@311 204 checkbox.setAttribute("name","option");
n@311 205 checkbox.id = MUSHRAInterfaceOptions[0][i];
n@311 206 text = document.createElement('span');
n@311 207 text.textContent = MUSHRAInterfaceOptions[1][i];
n@311 208 holder.appendChild(checkbox);
n@311 209 holder.appendChild(text);
n@311 210 this.popupBody.appendChild(holder);
n@311 211 }
n@311 212 for (var i=0; i<MUSHRAInterfaceChecks[0].length; i++)
n@311 213 {
n@311 214 holder = document.createElement('div');
n@311 215 holder.style.margin = "5px";
n@311 216 checkbox = document.createElement('input');
n@311 217 checkbox.type = 'checkbox';
n@311 218 checkbox.setAttribute("name","check");
n@311 219 checkbox.id = MUSHRAInterfaceChecks[0][i];
n@311 220 text = document.createElement('span');
n@311 221 text.textContent = MUSHRAInterfaceChecks[1][i];
n@311 222 holder.appendChild(checkbox);
n@311 223 holder.appendChild(text);
n@311 224 this.popupBody.appendChild(holder);
n@311 225 }
n@311 226 }
n@311 227 var button = document.createElement('button');
n@311 228 button.className = "popupButton";
n@311 229 button.textContent = "Submit";
n@311 230 button.onclick = function(event) {
n@311 231 var optHold = popupInstance.popupBody;
n@311 232 var opt = optHold.firstChild;
n@311 233 var input = opt.getElementsByTagName('input')[0];
n@311 234 specificationNode.randomiseOrder = input.checked;
n@311 235 while(opt.nextSibling != null)
n@311 236 {
n@311 237 opt = opt.nextSibling;
n@311 238 input = opt.getElementsByTagName('input')[0];
n@311 239 if (input.checked)
n@311 240 {
n@311 241 specificationNode.commonInterface.options.push(new specificationNode.commonInterface.optionNode(input));
n@311 242 }
n@311 243
n@311 244 }
n@311 245 popupInstance.advanceState();
n@311 246 };
n@311 247 this.popupFooter.appendChild(button);
n@311 248 break;
n@311 249 case 3:
n@311 250 this.popupTitleText.textContent = "Test Page";
n@311 251 var span = document.createElement('span');
n@311 252 span.textContent = "Drag and drop your audio files into the box below to add them to a test page";
n@311 253 this.popupBody.appendChild(span);
n@311 254 var dnd = document.createElement('div');
n@311 255 dnd.id = "audio-holder-drop";
n@311 256 dnd.style.width = "100%";
n@311 257 dnd.style.minHeight = "50px";
n@311 258 dnd.style.maxHeight = "220px";
n@311 259 dnd.style.overflow = 'auto';
n@311 260 dnd.className = "dragndrop";
n@311 261 dnd.ondragover = function(e) {
n@311 262 if(e.preventDefault) {e.preventDefault();}
n@311 263 return false;
n@311 264 };
n@311 265 dnd.ondragenter = function(e) {
n@311 266 if(e.preventDefault) {e.preventDefault();}
n@311 267 return false;
n@311 268 };
n@311 269 dnd.ondrop = function(e) {
n@311 270 if(e.preventDefault) {e.preventDefault();}
n@311 271 var dt = e.dataTransfer;
n@311 272 var body = document.getElementById("audio-holder-drop");
n@311 273 var files = dt.files;
n@311 274 for (var i = 0, f; f = files[i]; i++)
n@311 275 {
n@311 276 var dndHeader = document.createElement('div');
n@311 277 dndHeader.style.width = "100%";
n@311 278 dndHeader.style.height = "20px";
n@311 279 dndHeader.style.borderBottom = "#DDD";
n@311 280 dndHeader.style.borderBottomWidth = "1px";
n@311 281 dndHeader.style.borderBottomStyle = "solid";
n@311 282 var dndHInclude = document.createElement('div');
n@311 283 dndHInclude.style.width = "30px";
n@311 284 dndHInclude.className = "dndheaderelement";
n@311 285 var includeCheck = document.createElement('input');
n@311 286 includeCheck.type = "checkbox";
n@311 287 includeCheck.name = "include-check";
n@311 288 includeCheck.checked = true;
n@311 289 dndHInclude.appendChild(includeCheck);
n@311 290 dndHeader.appendChild(dndHInclude);
n@311 291 var dndHTitle = document.createElement('div');
n@311 292 dndHTitle.style.width = "180px";
n@311 293 dndHTitle.className = "dndheaderelement";
n@311 294 var text = document.createElement('span');
n@311 295 text.textContent = f.name;
n@311 296 dndHTitle.appendChild(text);
n@311 297 dndHeader.appendChild(dndHTitle);
n@311 298 var dndHID = document.createElement('div');
n@311 299 dndHID.style.width = "100px";
n@311 300 dndHID.className = "dndheaderelement";
n@311 301 var IDInput = document.createElement('input');
n@311 302 IDInput.name = "ID";
n@311 303 IDInput.value = f.name.split('.')[0];
n@311 304 IDInput.style.width = "96px";
n@311 305 // TODO: Automatic checking for common ID;
n@311 306 dndHID.appendChild(IDInput);
n@311 307 dndHeader.appendChild(dndHID);
n@311 308 var dndHPlay = document.createElement('div');
n@311 309 dndHPlay.style.width = "100px";
n@311 310 dndHPlay.className = "dndheaderelement";
n@311 311 var audio = document.createElement('audio');
n@311 312 dndHPlay.appendChild(audio);
n@311 313 dndHeader.appendChild(dndHPlay);
n@311 314 dnd.appendChild(dndHeader);
n@311 315 }
n@311 316 };
n@311 317 var dndHeader = document.createElement('div');
n@311 318 dndHeader.style.width = "100%";
n@311 319 dndHeader.style.height = "15px";
n@311 320 dndHeader.style.borderBottom = "#DDD";
n@311 321 dndHeader.style.borderBottomWidth = "1px";
n@311 322 dndHeader.style.borderBottomStyle = "solid";
n@311 323 var dndHInclude = document.createElement('div');
n@311 324 dndHInclude.style.width = "30px";
n@311 325 dndHInclude.className = "dndheaderelement";
n@311 326 var text = document.createElement('span');
n@311 327 text.textContent = "Inc.";
n@311 328 dndHInclude.appendChild(text);
n@311 329 dndHeader.appendChild(dndHInclude);
n@311 330 var dndHTitle = document.createElement('div');
n@311 331 dndHTitle.style.width = "180px";
n@311 332 dndHTitle.className = "dndheaderelement";
n@311 333 text = document.createElement('span');
n@311 334 text.textContent = "File Name";
n@311 335 dndHTitle.appendChild(text);
n@311 336 dndHeader.appendChild(dndHTitle);
n@311 337 var dndHID = document.createElement('div');
n@311 338 dndHID.style.width = "100px";
n@311 339 dndHID.className = "dndheaderelement";
n@311 340 text = document.createElement('span');
n@311 341 text.textContent = "ID";
n@311 342 dndHID.appendChild(text);
n@311 343 dndHeader.appendChild(dndHID);
n@311 344 var dndHPlay = document.createElement('div');
n@311 345 dndHPlay.style.width = "100px";
n@311 346 dndHPlay.className = "dndheaderelement";
n@311 347 text = document.createElement('span');
n@311 348 text.textContent = "Sample";
n@311 349 dndHPlay.appendChild(text);
n@311 350 dndHeader.appendChild(dndHPlay);
n@311 351 dnd.appendChild(dndHeader);
n@311 352 this.popupBody.appendChild(dnd);
n@311 353 var button = document.createElement('button');
n@311 354 button.className = "popupButton";
n@311 355 button.textContent = "Submit";
n@311 356 button.onclick = function(event)
n@311 357 {
n@311 358
n@311 359 };
n@311 360 this.popupFooter.appendChild(button);
n@162 361 }
n@311 362 this.state++;
n@311 363 };
n@311 364 };
n@311 365
n@311 366 function Specification() {
n@311 367 // Handles the decoding of the project specification XML into a simple JavaScript Object.
n@311 368
n@311 369 this.interfaceType = null;
n@311 370 this.commonInterface = new function()
n@311 371 {
n@311 372 this.options = [];
n@311 373 this.optionNode = function(input)
n@311 374 {
n@311 375 var name = input.getAttribute('name');
n@311 376 this.type = name;
n@311 377 if(this.type == "option")
n@311 378 {
n@311 379 this.name = input.id;
n@311 380 } else if (this.type == "check")
n@311 381 {
n@311 382 this.check = input.id;
n@311 383 }
n@311 384 };
n@311 385 };
n@311 386 this.projectReturn = null;
n@311 387 this.randomiseOrder = null;
n@311 388 this.collectMetrics = null;
n@311 389 this.testPages = null;
n@311 390 this.preTest = null;
n@311 391 this.postTest = null;
n@311 392 this.audioHolders = [];
n@311 393
n@311 394 this.decode = function() {
n@311 395 // projectXML - DOM Parsed document
n@311 396 this.projectXML = projectXML.childNodes[0];
n@311 397 var setupNode = projectXML.getElementsByTagName('setup')[0];
n@311 398 this.interfaceType = setupNode.getAttribute('interface');
n@311 399 this.projectReturn = setupNode.getAttribute('projectReturn');
n@311 400 this.testPages = setupNode.getAttribute('testPages');
n@311 401 if (setupNode.getAttribute('randomiseOrder') == "true") {
n@311 402 this.randomiseOrder = true;
n@311 403 } else {this.randomiseOrder = false;}
n@311 404 if (setupNode.getAttribute('collectMetrics') == "true") {
n@311 405 this.collectMetrics = true;
n@311 406 } else {this.collectMetrics = false;}
n@311 407 if (isNaN(Number(this.testPages)) || this.testPages == undefined)
n@311 408 {
n@311 409 this.testPages = null;
n@311 410 } else {
n@311 411 this.testPages = Number(this.testPages);
n@311 412 if (this.testPages == 0) {this.testPages = null;}
n@162 413 }
n@311 414 var metricCollection = setupNode.getElementsByTagName('Metric');
n@162 415
n@311 416 this.preTest = new this.prepostNode('pretest',setupNode.getElementsByTagName('PreTest'));
n@311 417 this.postTest = new this.prepostNode('posttest',setupNode.getElementsByTagName('PostTest'));
n@163 418
n@311 419 if (metricCollection.length > 0) {
n@311 420 metricCollection = metricCollection[0].getElementsByTagName('metricEnable');
n@311 421 for (var i=0; i<metricCollection.length; i++) {
n@311 422 this.metrics.push(new this.metricNode(metricCollection[i].textContent));
n@311 423 }
n@172 424 }
n@172 425
n@311 426 var commonInterfaceNode = setupNode.getElementsByTagName('interface');
n@311 427 if (commonInterfaceNode.length > 0) {
n@311 428 commonInterfaceNode = commonInterfaceNode[0];
n@311 429 } else {
n@311 430 commonInterfaceNode = undefined;
n@163 431 }
n@163 432
n@311 433 this.commonInterface = new function() {
n@311 434 this.OptionNode = function(child) {
n@311 435 this.type = child.nodeName;
n@311 436 if (this.type == 'option')
n@311 437 {
n@311 438 this.name = child.getAttribute('name');
n@311 439 }
n@311 440 else if (this.type == 'check') {
n@311 441 this.check = child.getAttribute('name');
n@311 442 if (this.check == 'scalerange') {
n@311 443 this.min = child.getAttribute('min');
n@311 444 this.max = child.getAttribute('max');
n@311 445 if (this.min == null) {this.min = 1;}
n@311 446 else if (Number(this.min) > 1 && this.min != null) {
n@311 447 this.min = Number(this.min)/100;
n@311 448 } else {
n@311 449 this.min = Number(this.min);
n@311 450 }
n@311 451 if (this.max == null) {this.max = 0;}
n@311 452 else if (Number(this.max) > 1 && this.max != null) {
n@311 453 this.max = Number(this.max)/100;
n@311 454 } else {
n@311 455 this.max = Number(this.max);
n@311 456 }
n@311 457 }
n@311 458 } else if (this.type == 'anchor' || this.type == 'reference') {
n@311 459 this.value = Number(child.textContent);
n@311 460 this.enforce = child.getAttribute('enforce');
n@311 461 if (this.enforce == 'true') {this.enforce = true;}
n@311 462 else {this.enforce = false;}
n@311 463 }
n@311 464 };
n@311 465 this.options = [];
n@311 466 if (commonInterfaceNode != undefined) {
n@311 467 var child = commonInterfaceNode.firstElementChild;
n@311 468 while (child != undefined) {
n@311 469 this.options.push(new this.OptionNode(child));
n@311 470 child = child.nextElementSibling;
n@311 471 }
n@311 472 }
n@311 473 };
n@311 474
n@311 475 var audioHolders = projectXML.getElementsByTagName('audioHolder');
n@311 476 for (var i=0; i<audioHolders.length; i++) {
n@311 477 this.audioHolders.push(new this.audioHolderNode(this,audioHolders[i]));
n@166 478 }
n@167 479
n@311 480 // New check if we need to randomise the test order
n@311 481 if (this.randomiseOrder)
n@311 482 {
n@311 483 this.audioHolders = randomiseOrder(this.audioHolders);
n@311 484 for (var i=0; i<this.audioHolders.length; i++)
n@311 485 {
n@311 486 this.audioHolders[i].presentedId = i;
n@311 487 }
n@167 488 }
n@311 489
n@311 490 if (this.testPages != null || this.testPages != undefined)
n@311 491 {
n@311 492 if (this.testPages > audioHolders.length)
n@311 493 {
n@311 494 console.log('Warning: You have specified '+audioHolders.length+' tests but requested '+this.testPages+' be completed!');
n@311 495 this.testPages = audioHolders.length;
n@311 496 }
n@311 497 var aH = this.audioHolders;
n@311 498 this.audioHolders = [];
n@311 499 for (var i=0; i<this.testPages; i++)
n@311 500 {
n@311 501 this.audioHolders.push(aH[i]);
n@162 502 }
n@162 503 }
n@311 504 };
n@163 505
n@311 506 this.prepostNode = function(type,Collection) {
n@311 507 this.type = type;
n@311 508 this.options = [];
n@311 509
n@311 510 this.OptionNode = function(child) {
n@311 511
n@311 512 this.childOption = function(element) {
n@311 513 this.type = 'option';
n@311 514 this.id = element.id;
n@311 515 this.name = element.getAttribute('name');
n@311 516 this.text = element.textContent;
n@311 517 };
n@311 518
n@311 519 this.type = child.nodeName;
n@311 520 if (child.nodeName == "question") {
n@311 521 this.id = child.id;
n@311 522 this.mandatory;
n@311 523 if (child.getAttribute('mandatory') == "true") {this.mandatory = true;}
n@311 524 else {this.mandatory = false;}
n@311 525 this.question = child.textContent;
n@311 526 if (child.getAttribute('boxsize') == null) {
n@311 527 this.boxsize = 'normal';
n@311 528 } else {
n@311 529 this.boxsize = child.getAttribute('boxsize');
n@311 530 }
n@311 531 } else if (child.nodeName == "statement") {
n@311 532 this.statement = child.textContent;
n@311 533 } else if (child.nodeName == "checkbox" || child.nodeName == "radio") {
n@311 534 var element = child.firstElementChild;
n@311 535 this.id = child.id;
n@311 536 if (element == null) {
n@311 537 console.log('Malformed' +child.nodeName+ 'entry');
n@311 538 this.statement = 'Malformed' +child.nodeName+ 'entry';
n@311 539 this.type = 'statement';
n@311 540 } else {
n@311 541 this.options = [];
n@311 542 while (element != null) {
n@311 543 if (element.nodeName == 'statement' && this.statement == undefined){
n@311 544 this.statement = element.textContent;
n@311 545 } else if (element.nodeName == 'option') {
n@311 546 this.options.push(new this.childOption(element));
n@163 547 }
n@311 548 element = element.nextElementSibling;
n@163 549 }
n@311 550 }
n@311 551 } else if (child.nodeName == "number") {
n@311 552 this.statement = child.textContent;
n@311 553 this.id = child.id;
n@311 554 this.min = child.getAttribute('min');
n@311 555 this.max = child.getAttribute('max');
n@311 556 this.step = child.getAttribute('step');
n@311 557 }
n@311 558 };
n@311 559
n@311 560 // On construction:
n@311 561 if (Collection.length != 0) {
n@311 562 Collection = Collection[0];
n@311 563 if (Collection.childElementCount != 0) {
n@311 564 var child = Collection.firstElementChild;
n@311 565 this.options.push(new this.OptionNode(child));
n@311 566 while (child.nextElementSibling != null) {
n@311 567 child = child.nextElementSibling;
n@311 568 this.options.push(new this.OptionNode(child));
n@163 569 }
n@163 570 }
n@163 571 }
n@172 572 };
n@172 573
n@311 574 this.metricNode = function(name) {
n@311 575 this.enabled = name;
n@311 576 };
n@172 577
n@311 578 this.audioHolderNode = function(parent,xml) {
n@311 579 this.type = 'audioHolder';
n@311 580 this.presentedId = parent.audioHolders.length;
n@311 581 this.interfaceNode = function(DOM) {
n@311 582 var title = DOM.getElementsByTagName('title');
n@311 583 if (title.length == 0) {this.title = null;}
n@311 584 else {this.title = title[0].textContent;}
n@311 585 this.options = parent.commonInterface.options;
n@311 586 var scale = DOM.getElementsByTagName('scale');
n@311 587 this.scale = [];
n@311 588 for (var i=0; i<scale.length; i++) {
n@311 589 var arr = [null, null];
n@311 590 arr[0] = scale[i].getAttribute('position');
n@311 591 arr[1] = scale[i].textContent;
n@311 592 this.scale.push(arr);
n@311 593 }
n@311 594 };
n@311 595
n@311 596 this.audioElementNode = function(parent,xml) {
n@311 597 this.url = xml.getAttribute('url');
n@311 598 this.id = xml.id;
n@311 599 this.parent = parent;
n@311 600 this.type = xml.getAttribute('type');
n@311 601 if (this.type == null) {this.type = "normal";}
n@311 602 if (this.type == 'anchor') {this.anchor = true;}
n@311 603 else {this.anchor = false;}
n@311 604 if (this.type == 'reference') {this.reference = true;}
n@311 605 else {this.reference = false;}
n@311 606
n@311 607 this.marker = xml.getAttribute('marker');
n@311 608 if (this.marker == null) {this.marker = undefined;}
n@311 609
n@311 610 if (this.anchor == true) {
n@311 611 if (this.marker != undefined) {this.enforce = true;}
n@311 612 else {this.enforce = enforceAnchor;}
n@311 613 this.marker = anchor;
n@311 614 }
n@311 615 else if (this.reference == true) {
n@311 616 if (this.marker != undefined) {this.enforce = true;}
n@311 617 else {this.enforce = enforceReference;}
n@311 618 this.marker = reference;
n@311 619 }
n@311 620
n@311 621 if (this.marker != undefined) {
n@311 622 this.marker = Number(this.marker);
n@311 623 if (this.marker > 1) {this.marker /= 100;}
n@311 624 }
n@311 625 };
n@311 626
n@311 627 this.commentQuestionNode = function(xml) {
n@311 628 this.childOption = function(element) {
n@311 629 this.type = 'option';
n@311 630 this.name = element.getAttribute('name');
n@311 631 this.text = element.textContent;
n@311 632 };
n@311 633 this.id = xml.id;
n@311 634 if (xml.getAttribute('mandatory') == 'true') {this.mandatory = true;}
n@311 635 else {this.mandatory = false;}
n@311 636 this.type = xml.getAttribute('type');
n@311 637 if (this.type == undefined) {this.type = 'text';}
n@311 638 switch (this.type) {
n@311 639 case 'text':
n@311 640 this.question = xml.textContent;
n@311 641 break;
n@311 642 case 'radio':
n@311 643 var child = xml.firstElementChild;
n@311 644 this.options = [];
n@311 645 while (child != undefined) {
n@311 646 if (child.nodeName == 'statement' && this.statement == undefined) {
n@311 647 this.statement = child.textContent;
n@311 648 } else if (child.nodeName == 'option') {
n@311 649 this.options.push(new this.childOption(child));
n@311 650 }
n@311 651 child = child.nextElementSibling;
n@311 652 }
n@311 653 break;
n@311 654 case 'checkbox':
n@311 655 var child = xml.firstElementChild;
n@311 656 this.options = [];
n@311 657 while (child != undefined) {
n@311 658 if (child.nodeName == 'statement' && this.statement == undefined) {
n@311 659 this.statement = child.textContent;
n@311 660 } else if (child.nodeName == 'option') {
n@311 661 this.options.push(new this.childOption(child));
n@311 662 }
n@311 663 child = child.nextElementSibling;
n@311 664 }
n@311 665 break;
n@311 666 }
n@311 667 };
n@311 668
n@311 669 this.id = xml.id;
n@311 670 this.hostURL = xml.getAttribute('hostURL');
n@311 671 this.sampleRate = xml.getAttribute('sampleRate');
n@311 672 if (xml.getAttribute('randomiseOrder') == "true") {this.randomiseOrder = true;}
n@311 673 else {this.randomiseOrder = false;}
n@311 674 this.repeatCount = xml.getAttribute('repeatCount');
n@311 675 if (xml.getAttribute('loop') == 'true') {this.loop = true;}
n@311 676 else {this.loop == false;}
n@311 677 if (xml.getAttribute('elementComments') == "true") {this.elementComments = true;}
n@311 678 else {this.elementComments = false;}
n@311 679
n@311 680 var anchor = xml.getElementsByTagName('anchor');
n@311 681 var enforceAnchor = false;
n@311 682 if (anchor.length == 0) {
n@311 683 // Find anchor in commonInterface;
n@311 684 for (var i=0; i<parent.commonInterface.options.length; i++) {
n@311 685 if(parent.commonInterface.options[i].type == 'anchor') {
n@311 686 anchor = parent.commonInterface.options[i].value;
n@311 687 enforceAnchor = parent.commonInterface.options[i].enforce;
n@311 688 break;
n@311 689 }
n@311 690 }
n@311 691 if (typeof(anchor) == "object") {
n@311 692 anchor = null;
n@311 693 }
n@311 694 } else {
n@311 695 anchor = anchor[0].textContent;
n@169 696 }
n@311 697
n@311 698 var reference = xml.getElementsByTagName('anchor');
n@311 699 var enforceReference = false;
n@311 700 if (reference.length == 0) {
n@311 701 // Find anchor in commonInterface;
n@311 702 for (var i=0; i<parent.commonInterface.options.length; i++) {
n@311 703 if(parent.commonInterface.options[i].type == 'reference') {
n@311 704 reference = parent.commonInterface.options[i].value;
n@311 705 enforceReference = parent.commonInterface.options[i].enforce;
n@311 706 break;
n@311 707 }
n@311 708 }
n@311 709 if (typeof(reference) == "object") {
n@311 710 reference = null;
n@311 711 }
n@311 712 } else {
n@311 713 reference = reference[0].textContent;
n@169 714 }
n@169 715
n@311 716 if (typeof(anchor) == 'number') {
n@311 717 if (anchor > 1 && anchor < 100) {anchor /= 100.0;}
n@311 718 }
n@311 719
n@311 720 if (typeof(reference) == 'number') {
n@311 721 if (reference > 1 && reference < 100) {reference /= 100.0;}
n@311 722 }
n@311 723
n@311 724 this.preTest = new parent.prepostNode('pretest',xml.getElementsByTagName('PreTest'));
n@311 725 this.postTest = new parent.prepostNode('posttest',xml.getElementsByTagName('PostTest'));
n@311 726
n@311 727 this.interfaces = [];
n@311 728 var interfaceDOM = xml.getElementsByTagName('interface');
n@311 729 for (var i=0; i<interfaceDOM.length; i++) {
n@311 730 this.interfaces.push(new this.interfaceNode(interfaceDOM[i]));
n@311 731 }
n@311 732
n@311 733 this.commentBoxPrefix = xml.getElementsByTagName('commentBoxPrefix');
n@311 734 if (this.commentBoxPrefix.length != 0) {
n@311 735 this.commentBoxPrefix = this.commentBoxPrefix[0].textContent;
n@311 736 } else {
n@311 737 this.commentBoxPrefix = "Comment on track";
n@311 738 }
n@311 739
n@311 740 this.audioElements =[];
n@311 741 var audioElementsDOM = xml.getElementsByTagName('audioElements');
n@311 742 this.outsideReference = null;
n@311 743 for (var i=0; i<audioElementsDOM.length; i++) {
n@311 744 if (audioElementsDOM[i].getAttribute('type') == 'outsidereference') {
n@311 745 if (this.outsideReference == null) {
n@311 746 this.outsideReference = new this.audioElementNode(this,audioElementsDOM[i]);
n@311 747 } else {
n@311 748 console.log('Error only one audioelement can be of type outsidereference per audioholder');
n@311 749 this.audioElements.push(new this.audioElementNode(this,audioElementsDOM[i]));
n@311 750 console.log('Element id '+audioElementsDOM[i].id+' made into normal node');
n@169 751 }
n@311 752 } else {
n@311 753 this.audioElements.push(new this.audioElementNode(this,audioElementsDOM[i]));
n@169 754 }
n@169 755 }
n@311 756
n@311 757 if (this.randomiseOrder) {
n@311 758 this.audioElements = randomiseOrder(this.audioElements);
n@172 759 }
n@172 760
n@311 761 // Check only one anchor and one reference per audioNode
n@311 762 var anchor = [];
n@311 763 var reference = [];
n@311 764 this.anchorId = null;
n@311 765 this.referenceId = null;
n@311 766 for (var i=0; i<this.audioElements.length; i++)
n@311 767 {
n@311 768 if (this.audioElements[i].anchor == true) {anchor.push(i);}
n@311 769 if (this.audioElements[i].reference == true) {reference.push(i);}
n@169 770 }
n@169 771
n@311 772 if (anchor.length > 1) {
n@311 773 console.log('Error - cannot have more than one anchor!');
n@311 774 console.log('Each anchor node will be a normal mode to continue the test');
n@311 775 for (var i=0; i<anchor.length; i++)
n@311 776 {
n@311 777 this.audioElements[anchor[i]].anchor = false;
n@311 778 this.audioElements[anchor[i]].value = undefined;
n@311 779 }
n@311 780 } else {this.anchorId = anchor[0];}
n@311 781 if (reference.length > 1) {
n@311 782 console.log('Error - cannot have more than one anchor!');
n@311 783 console.log('Each anchor node will be a normal mode to continue the test');
n@311 784 for (var i=0; i<reference.length; i++)
n@311 785 {
n@311 786 this.audioElements[reference[i]].reference = false;
n@311 787 this.audioElements[reference[i]].value = undefined;
n@311 788 }
n@311 789 } else {this.referenceId = reference[0];}
n@311 790
n@311 791 this.commentQuestions = [];
n@311 792 var commentQuestionsDOM = xml.getElementsByTagName('CommentQuestion');
n@311 793 for (var i=0; i<commentQuestionsDOM.length; i++) {
n@311 794 this.commentQuestions.push(new this.commentQuestionNode(commentQuestionsDOM[i]));
n@169 795 }
n@311 796 };
n@168 797 }
n@157 798 </script>
n@157 799 <style>
n@311 800 div.popup {
n@311 801 width: 500px;
n@311 802 position: absolute;
n@311 803 height: 400px;
n@311 804 background-color: #fff;
n@311 805 border-radius: 10px;
n@311 806 box-shadow: 0px 0px 50px #000;
n@311 807 z-index: 2;
n@157 808 }
n@311 809
n@311 810 button.popupButton {
n@311 811 /* Button for popup window
n@311 812 */
n@311 813 min-width: 50px;
n@311 814 height: 25px;
n@311 815 position: relative;
n@311 816 border-radius: 5px;
n@311 817 border: #444;
n@311 818 border-width: 1px;
n@311 819 border-style: solid;
n@311 820 background-color: #fff;
n@311 821 }
n@311 822
n@311 823 div.dragndrop {
n@311 824 margin-top: 10px;
n@311 825 border:#000000;
n@311 826 border-style: dashed;
n@157 827 border-width: 2px;
n@157 828 }
n@311 829 div.dndheaderelement {
n@311 830 float: left;
n@311 831 height: 100%;
n@311 832 border-right: #DDDDDD;
n@311 833 border-right-width: 1px;
n@311 834 border-right-style: solid;
n@157 835 }
n@311 836 div.dndheaderelement span{
n@311 837 padding-left: 5px;
n@168 838 }
n@157 839 </style>
n@156 840 </head>
n@156 841
n@156 842 <body>
n@311 843 <div id="content"></div>
n@156 844 </body>
n@156 845 </html>