annotate interfaces/mushra.js @ 1116:c44fbf72f7f2

All interfaces support comment boxes. Comment box identification matches presented tag (for instance, AB will be Comment on fragment A, rather than 1). Tighter buffer loading protocol, audioObjects register with the buffer rather than checking for buffer existence (which can be buggy depending on the buffer state). Buffers now have a state to ensure exact location in loading chain (downloading, decoding, LUFS, ready).
author Nicholas Jillings <n.g.r.jillings@se14.qmul.ac.uk>
date Fri, 29 Jan 2016 11:11:57 +0000
parents
children c0022a09c4f6
rev   line source
n@1116 1 /**
n@1116 2 * mushra.js
n@1116 3 * Create the MUSHRA interface
n@1116 4 */
n@1116 5
n@1116 6 // Once this is loaded and parsed, begin execution
n@1116 7 loadInterface();
n@1116 8
n@1116 9 function loadInterface() {
n@1116 10 // Get the dimensions of the screen available to the page
n@1116 11 var width = window.innerWidth;
n@1116 12 var height = window.innerHeight;
n@1116 13
n@1116 14 // The injection point into the HTML page
n@1116 15 interfaceContext.insertPoint = document.getElementById("topLevelBody");
n@1116 16 var testContent = document.createElement('div');
n@1116 17 testContent.id = 'testContent';
n@1116 18
n@1116 19 // Create the top div for the Title element
n@1116 20 var titleAttr = specification.title;
n@1116 21 var title = document.createElement('div');
n@1116 22 title.className = "title";
n@1116 23 title.align = "center";
n@1116 24 var titleSpan = document.createElement('span');
n@1116 25
n@1116 26 // Set title to that defined in XML, else set to default
n@1116 27 if (titleAttr != undefined) {
n@1116 28 titleSpan.textContent = titleAttr;
n@1116 29 } else {
n@1116 30 titleSpan.textContent = 'Listening test';
n@1116 31 }
n@1116 32 // Insert the titleSpan element into the title div element.
n@1116 33 title.appendChild(titleSpan);
n@1116 34
n@1116 35 var pagetitle = document.createElement('div');
n@1116 36 pagetitle.className = "pageTitle";
n@1116 37 pagetitle.align = "center";
n@1116 38 var titleSpan = document.createElement('span');
n@1116 39 titleSpan.id = "pageTitle";
n@1116 40 pagetitle.appendChild(titleSpan);
n@1116 41
n@1116 42 // Create Interface buttons!
n@1116 43 var interfaceButtons = document.createElement('div');
n@1116 44 interfaceButtons.id = 'interface-buttons';
n@1116 45 interfaceButtons.style.height = '25px';
n@1116 46
n@1116 47 // Create playback start/stop points
n@1116 48 var playback = document.createElement("button");
n@1116 49 playback.innerHTML = 'Stop';
n@1116 50 playback.id = 'playback-button';
n@1116 51 playback.style.float = 'left';
n@1116 52 // onclick function. Check if it is playing or not, call the correct function in the
n@1116 53 // audioEngine, change the button text to reflect the next state.
n@1116 54 playback.onclick = function() {
n@1116 55 if (audioEngineContext.status == 1) {
n@1116 56 audioEngineContext.stop();
n@1116 57 this.innerHTML = 'Stop';
n@1116 58 var time = audioEngineContext.timer.getTestTime();
n@1116 59 console.log('Stopped at ' + time); // DEBUG/SAFETY
n@1116 60 }
n@1116 61 };
n@1116 62 // Create Submit (save) button
n@1116 63 var submit = document.createElement("button");
n@1116 64 submit.innerHTML = 'Submit';
n@1116 65 submit.onclick = buttonSubmitClick;
n@1116 66 submit.id = 'submit-button';
n@1116 67 submit.style.float = 'left';
n@1116 68 // Append the interface buttons into the interfaceButtons object.
n@1116 69 interfaceButtons.appendChild(playback);
n@1116 70 interfaceButtons.appendChild(submit);
n@1116 71
n@1116 72 // Create a slider box
n@1116 73 var sliderBox = document.createElement('div');
n@1116 74 sliderBox.style.width = "100%";
n@1116 75 sliderBox.style.height = window.innerHeight - 200+12 + 'px';
n@1116 76 sliderBox.style.marginBottom = '10px';
n@1116 77 sliderBox.id = 'slider';
n@1116 78 var scaleHolder = document.createElement('div');
n@1116 79 scaleHolder.id = "scale-holder";
n@1116 80 sliderBox.appendChild(scaleHolder);
n@1116 81 var scaleText = document.createElement('div');
n@1116 82 scaleText.id = "scale-text-holder";
n@1116 83 scaleHolder.appendChild(scaleText);
n@1116 84 var scaleCanvas = document.createElement('canvas');
n@1116 85 scaleCanvas.id = "scale-canvas";
n@1116 86 scaleHolder.appendChild(scaleCanvas);
n@1116 87 var sliderObjectHolder = document.createElement('div');
n@1116 88 sliderObjectHolder.id = 'slider-holder';
n@1116 89 sliderObjectHolder.align = "center";
n@1116 90 sliderBox.appendChild(sliderObjectHolder);
n@1116 91
n@1116 92 // Global parent for the comment boxes on the page
n@1116 93 var feedbackHolder = document.createElement('div');
n@1116 94 feedbackHolder.id = 'feedbackHolder';
n@1116 95
n@1116 96 testContent.style.zIndex = 1;
n@1116 97 interfaceContext.insertPoint.innerHTML = null; // Clear the current schema
n@1116 98
n@1116 99 // Inject into HTML
n@1116 100 testContent.appendChild(title); // Insert the title
n@1116 101 testContent.appendChild(pagetitle);
n@1116 102 testContent.appendChild(interfaceButtons);
n@1116 103 testContent.appendChild(sliderBox);
n@1116 104 testContent.appendChild(feedbackHolder);
n@1116 105 interfaceContext.insertPoint.appendChild(testContent);
n@1116 106
n@1116 107 // Load the full interface
n@1116 108 testState.initialise();
n@1116 109 testState.advanceState();
n@1116 110 }
n@1116 111
n@1116 112 function loadTest(audioHolderObject)
n@1116 113 {
n@1116 114 var id = audioHolderObject.id;
n@1116 115
n@1116 116 var feedbackHolder = document.getElementById('feedbackHolder');
n@1116 117 feedbackHolder.innerHTML = null;
n@1116 118 var interfaceObj = audioHolderObject.interfaces;
n@1116 119 if (interfaceObj.length > 1)
n@1116 120 {
n@1116 121 console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node");
n@1116 122 }
n@1116 123 interfaceObj = interfaceObj[0];
n@1116 124 if(interfaceObj.title != null)
n@1116 125 {
n@1116 126 document.getElementById("pageTitle").textContent = interfaceObj.title;
n@1116 127 }
n@1116 128 var interfaceOptions = specification.interfaces.options.concat(interfaceObj.options);
n@1116 129 for (var option of interfaceOptions)
n@1116 130 {
n@1116 131 if (option.type == "show")
n@1116 132 {
n@1116 133 switch(option.name) {
n@1116 134 case "playhead":
n@1116 135 var playbackHolder = document.getElementById('playback-holder');
n@1116 136 if (playbackHolder == null)
n@1116 137 {
n@1116 138 playbackHolder = document.createElement('div');
n@1116 139 playbackHolder.style.width = "100%";
n@1116 140 playbackHolder.align = 'center';
n@1116 141 playbackHolder.appendChild(interfaceContext.playhead.object);
n@1116 142 feedbackHolder.appendChild(playbackHolder);
n@1116 143 }
n@1116 144 break;
n@1116 145 case "page-count":
n@1116 146 var pagecountHolder = document.getElementById('page-count');
n@1116 147 if (pagecountHolder == null)
n@1116 148 {
n@1116 149 pagecountHolder = document.createElement('div');
n@1116 150 pagecountHolder.id = 'page-count';
n@1116 151 }
n@1116 152 pagecountHolder.innerHTML = '<span>Page '+(audioHolderObject.presentedId+1)+' of '+specification.pages.length+'</span>';
n@1116 153 var inject = document.getElementById('interface-buttons');
n@1116 154 inject.appendChild(pagecountHolder);
n@1116 155 break;
n@1116 156 case "volume":
n@1116 157 if (document.getElementById('master-volume-holder') == null)
n@1116 158 {
n@1116 159 feedbackHolder.appendChild(interfaceContext.volume.object);
n@1116 160 }
n@1116 161 break;
n@1116 162 }
n@1116 163 }
n@1116 164 }
n@1116 165
n@1116 166 // Delete outside reference
n@1116 167 var outsideReferenceHolder = document.getElementById('outside-reference');
n@1116 168 if (outsideReferenceHolder != null) {
n@1116 169 document.getElementById('interface-buttons').removeChild(outsideReferenceHolder);
n@1116 170 }
n@1116 171
n@1116 172 var sliderBox = document.getElementById('slider-holder');
n@1116 173 sliderBox.innerHTML = null;
n@1116 174
n@1116 175 var commentBoxPrefix = "Comment on track";
n@1116 176 if (interfaceObj.commentBoxPrefix != undefined) {
n@1116 177 commentBoxPrefix = interfaceObj.commentBoxPrefix;
n@1116 178 }
n@1116 179 var loopPlayback = audioHolderObject.loop;
n@1116 180
n@1116 181 currentTestHolder = document.createElement('audioHolder');
n@1116 182 currentTestHolder.id = audioHolderObject.id;
n@1116 183 currentTestHolder.repeatCount = audioHolderObject.repeatCount;
n@1116 184
n@1116 185 $(audioHolderObject.commentQuestions).each(function(index,element) {
n@1116 186 var node = interfaceContext.createCommentQuestion(element);
n@1116 187 feedbackHolder.appendChild(node.holder);
n@1116 188 });
n@1116 189
n@1116 190 // Find all the audioElements from the audioHolder
n@1116 191 var label = 0;
n@1116 192 $(audioHolderObject.audioElements).each(function(index,element){
n@1116 193 // Find URL of track
n@1116 194 // In this jQuery loop, variable 'this' holds the current audioElement.
n@1116 195
n@1116 196 var audioObject = audioEngineContext.newTrack(element);
n@1116 197 if (element.type == 'outside-reference')
n@1116 198 {
n@1116 199 // Construct outside reference;
n@1116 200 var orNode = new outsideReferenceDOM(audioObject,index,document.getElementById('interface-buttons'));
n@1116 201 audioObject.bindInterface(orNode);
n@1116 202 } else {
n@1116 203 // Create a slider per track
n@1116 204 var sliderObj = new sliderObject(audioObject,label);
n@1116 205
n@1116 206 if (typeof audioHolderObject.initialPosition === "number")
n@1116 207 {
n@1116 208 // Set the values
n@1116 209 sliderObj.slider.value = audioHolderObject.initalPosition;
n@1116 210 } else {
n@1116 211 // Distribute it randomnly
n@1116 212 sliderObj.slider.value = Math.random();
n@1116 213 }
n@1116 214 sliderBox.appendChild(sliderObj.holder);
n@1116 215 audioObject.bindInterface(sliderObj);
n@1116 216 interfaceContext.createCommentBox(audioObject);
n@1116 217 label += 1;
n@1116 218 }
n@1116 219
n@1116 220 });
n@1116 221
n@1116 222 // Auto-align
n@1116 223 resizeWindow(null);
n@1116 224 }
n@1116 225
n@1116 226 function sliderObject(audioObject,label)
n@1116 227 {
n@1116 228 // Constructs the slider object. We use the HTML5 slider object
n@1116 229 this.parent = audioObject;
n@1116 230 this.holder = document.createElement('div');
n@1116 231 this.title = document.createElement('span');
n@1116 232 this.slider = document.createElement('input');
n@1116 233 this.play = document.createElement('button');
n@1116 234
n@1116 235 this.holder.className = 'track-slider';
n@1116 236 this.holder.style.height = window.innerHeight-200 + 'px';
n@1116 237 this.holder.appendChild(this.title);
n@1116 238 this.holder.appendChild(this.slider);
n@1116 239 this.holder.appendChild(this.play);
n@1116 240 this.holder.align = "center";
n@1116 241 if (label == 0)
n@1116 242 {
n@1116 243 this.holder.style.marginLeft = '0px';
n@1116 244 }
n@1116 245 this.holder.setAttribute('trackIndex',audioObject.id);
n@1116 246
n@1116 247 this.title.textContent = label;
n@1116 248 this.title.style.width = "100%";
n@1116 249 this.title.style.float = "left";
n@1116 250
n@1116 251 this.slider.type = "range";
n@1116 252 this.slider.className = "track-slider-range track-slider-not-moved";
n@1116 253 this.slider.min = "0";
n@1116 254 this.slider.max = "1";
n@1116 255 this.slider.step = "0.01";
n@1116 256 this.slider.setAttribute('orient','vertical');
n@1116 257 this.slider.style.height = window.innerHeight-250 + 'px';
n@1116 258 this.slider.onchange = function()
n@1116 259 {
n@1116 260 var time = audioEngineContext.timer.getTestTime();
n@1116 261 var id = Number(this.parentNode.getAttribute('trackIndex'));
n@1116 262 audioEngineContext.audioObjects[id].metric.moved(time,this.value);
n@1116 263 console.log('slider '+id+' moved to '+this.value+' ('+time+')');
n@1116 264 $(this).removeClass('track-slider-not-moved');
n@1116 265 };
n@1116 266
n@1116 267 this.play.textContent = "Loading...";
n@1116 268 this.play.value = audioObject.id;
n@1116 269 this.play.style.float = "left";
n@1116 270 this.play.style.width = "100%";
n@1116 271 this.play.disabled = true;
n@1116 272 this.play.onclick = function(event)
n@1116 273 {
n@1116 274 var id = Number(event.currentTarget.value);
n@1116 275 //audioEngineContext.metric.sliderPlayed(id);
n@1116 276 audioEngineContext.play(id);
n@1116 277 $(".track-slider").removeClass('track-slider-playing');
n@1116 278 $(event.currentTarget.parentElement).addClass('track-slider-playing');
n@1116 279 var outsideReference = document.getElementById('outside-reference');
n@1116 280 if (outsideReference != null) {
n@1116 281 $(outsideReference).removeClass('track-slider-playing');
n@1116 282 }
n@1116 283 };
n@1116 284
n@1116 285 this.enable = function() {
n@1116 286 this.play.disabled = false;
n@1116 287 this.play.textContent = "Play";
n@1116 288 $(this.slider).removeClass('track-slider-disabled');
n@1116 289 };
n@1116 290
n@1116 291 this.exportXMLDOM = function(audioObject) {
n@1116 292 // Called by the audioObject holding this element. Must be present
n@1116 293 var node = storage.document.createElement('value');
n@1116 294 node.textContent = this.slider.value;
n@1116 295 return node;
n@1116 296 };
n@1116 297 this.startPlayback = function()
n@1116 298 {
n@1116 299 // Called when playback has begun
n@1116 300 $(".track-slider").removeClass('track-slider-playing');
n@1116 301 $(this.holder).addClass('track-slider-playing');
n@1116 302 var outsideReference = document.getElementById('outside-reference');
n@1116 303 if (outsideReference != null) {
n@1116 304 $(outsideReference).removeClass('track-slider-playing');
n@1116 305 }
n@1116 306 };
n@1116 307 this.stopPlayback = function()
n@1116 308 {
n@1116 309 // Called when playback has stopped. This gets called even if playback never started!
n@1116 310 $(this.holder).removeClass('track-slider-playing');
n@1116 311 };
n@1116 312 this.getValue = function() {
n@1116 313 return this.slider.value;
n@1116 314 };
n@1116 315
n@1116 316 this.resize = function(event)
n@1116 317 {
n@1116 318 this.holder.style.height = window.innerHeight-200 + 'px';
n@1116 319 this.slider.style.height = window.innerHeight-250 + 'px';
n@1116 320 };
n@1116 321 this.updateLoading = function(progress)
n@1116 322 {
n@1116 323 progress = String(progress);
n@1116 324 progress = progress.substr(0,5);
n@1116 325 this.play.textContent = "Loading: "+progress+"%";
n@1116 326 };
n@1116 327
n@1116 328 if (this.parent.state == 1)
n@1116 329 {
n@1116 330 this.enable();
n@1116 331 }
n@1116 332 this.getPresentedId = function()
n@1116 333 {
n@1116 334 return this.title.textContent;
n@1116 335 };
n@1116 336 this.canMove = function()
n@1116 337 {
n@1116 338 return true;
n@1116 339 };
n@1116 340 }
n@1116 341
n@1116 342 function outsideReferenceDOM(audioObject,index,inject)
n@1116 343 {
n@1116 344 this.parent = audioObject;
n@1116 345 this.outsideReferenceHolder = document.createElement('button');
n@1116 346 this.outsideReferenceHolder.id = 'outside-reference';
n@1116 347 this.outsideReferenceHolder.className = 'outside-reference';
n@1116 348 this.outsideReferenceHolder.setAttribute('track-id',index);
n@1116 349 this.outsideReferenceHolder.textContent = "Play Reference";
n@1116 350 this.outsideReferenceHolder.disabled = true;
n@1116 351
n@1116 352 this.outsideReferenceHolder.onclick = function(event)
n@1116 353 {
n@1116 354 audioEngineContext.play(event.currentTarget.getAttribute('track-id'));
n@1116 355 };
n@1116 356 inject.appendChild(this.outsideReferenceHolder);
n@1116 357 this.enable = function()
n@1116 358 {
n@1116 359 if (this.parent.state == 1)
n@1116 360 {
n@1116 361 this.outsideReferenceHolder.disabled = false;
n@1116 362 }
n@1116 363 };
n@1116 364 this.updateLoading = function(progress)
n@1116 365 {
n@1116 366 if (progress != 100)
n@1116 367 {
n@1116 368 progress = String(progress);
n@1116 369 progress = progress.split('.')[0];
n@1116 370 this.outsideReferenceHolder[0].children[0].textContent = progress+'%';
n@1116 371 } else {
n@1116 372 this.outsideReferenceHolder[0].children[0].textContent = "Play Reference";
n@1116 373 }
n@1116 374 };
n@1116 375 this.startPlayback = function()
n@1116 376 {
n@1116 377 // Called when playback has begun
n@1116 378 $('.track-slider').removeClass('track-slider-playing');
n@1116 379 $('.comment-div').removeClass('comment-box-playing');
n@1116 380 $(this.outsideReferenceHolder).addClass('track-slider-playing');
n@1116 381 };
n@1116 382 this.stopPlayback = function()
n@1116 383 {
n@1116 384 // Called when playback has stopped. This gets called even if playback never started!
n@1116 385 $(this.outsideReferenceHolder).removeClass('track-slider-playing');
n@1116 386 };
n@1116 387 this.exportXMLDOM = function(audioObject)
n@1116 388 {
n@1116 389 return null;
n@1116 390 };
n@1116 391 this.getValue = function()
n@1116 392 {
n@1116 393 return 0;
n@1116 394 };
n@1116 395 this.getPresentedId = function()
n@1116 396 {
n@1116 397 return 'reference';
n@1116 398 };
n@1116 399 this.canMove = function()
n@1116 400 {
n@1116 401 return false;
n@1116 402 };
n@1116 403 }
n@1116 404
n@1116 405 function resizeWindow(event)
n@1116 406 {
n@1116 407 // Function called when the window has been resized.
n@1116 408 // MANDATORY FUNCTION
n@1116 409
n@1116 410 var outsideRef = document.getElementById('outside-reference');
n@1116 411 if(outsideRef != null)
n@1116 412 {
n@1116 413 outsideRef.style.left = (window.innerWidth-120)/2 + 'px';
n@1116 414 }
n@1116 415
n@1116 416 // Auto-align
n@1116 417 var numObj = document.getElementsByClassName('track-slider').length;
n@1116 418 var totalWidth = (numObj-1)*150+100;
n@1116 419 var diff = (window.innerWidth - totalWidth)/2;
n@1116 420 document.getElementById('slider').style.height = window.innerHeight - 180 + 'px';
n@1116 421 if (diff <= 0){diff = 0;}
n@1116 422 document.getElementById('slider-holder').style.marginLeft = diff + 'px';
n@1116 423 for (var i in audioEngineContext.audioObjects)
n@1116 424 {
n@1116 425 if (audioEngineContext.audioObjects[i].specification.type != 'outside-reference'){
n@1116 426 audioEngineContext.audioObjects[i].interfaceDOM.resize(event);
n@1116 427 }
n@1116 428 }
n@1116 429 document.getElementById('scale-holder').style.marginLeft = (diff-100) + 'px';
n@1116 430 document.getElementById('scale-text-holder').style.height = window.innerHeight-194 + 'px';
n@1116 431 var canvas = document.getElementById('scale-canvas');
n@1116 432 canvas.width = totalWidth;
n@1116 433 canvas.height = window.innerHeight-194;
n@1116 434 drawScale();
n@1116 435 }
n@1116 436
n@1116 437 function drawScale()
n@1116 438 {
n@1116 439 var interfaceObj = testState.currentStateMap.interfaces[0];
n@1116 440 var scales = testState.currentStateMap.interfaces[0].scales;
n@1116 441 scales = scales.sort(function(a,b) {
n@1116 442 return a.position - b.position;
n@1116 443 });
n@1116 444 var canvas = document.getElementById('scale-canvas');
n@1116 445 var ctx = canvas.getContext("2d");
n@1116 446 var height = canvas.height;
n@1116 447 var width = canvas.width;
n@1116 448 var draw_heights = [24, height-34];
n@1116 449 var textHolder = document.getElementById('scale-text-holder');
n@1116 450 textHolder.innerHTML = null;
n@1116 451 var lastHeight = 0;
n@1116 452 for (var scale of scales)
n@1116 453 {
n@1116 454 var posPercent = scale.position / 100.0;
n@1116 455 var posPix = (1-posPercent)*(draw_heights[1]-draw_heights[0])+draw_heights[0];
n@1116 456 ctx.fillStyle = "#000000";
n@1116 457 ctx.setLineDash([1,2]);
n@1116 458 ctx.moveTo(0,posPix);
n@1116 459 ctx.lineTo(width,posPix);
n@1116 460 ctx.stroke();
n@1116 461 var text = document.createElement('div');
n@1116 462 text.align = "right";
n@1116 463 var textC = document.createElement('span');
n@1116 464 textC.textContent = scale.text;
n@1116 465 text.appendChild(textC);
n@1116 466 text.className = "scale-text";
n@1116 467 textHolder.appendChild(text);
n@1116 468 text.style.top = (posPix-9) + 'px';
n@1116 469 text.style.left = 100 - ($(text).width()+3) + 'px';
n@1116 470 lastHeight = posPix;
n@1116 471 }
n@1116 472 }
n@1116 473
n@1116 474 function buttonSubmitClick() // TODO: Only when all songs have been played!
n@1116 475 {
n@1116 476 var checks = [];
n@1116 477 checks = checks.concat(testState.currentStateMap.interfaces[0].options);
n@1116 478 checks = checks.concat(specification.interfaces.options);
n@1116 479 var canContinue = true;
n@1116 480
n@1116 481 // Check that the anchor and reference objects are correctly placed
n@1116 482 if (interfaceContext.checkHiddenAnchor() == false) {return;}
n@1116 483 if (interfaceContext.checkHiddenReference() == false) {return;}
n@1116 484
n@1116 485 for (var i=0; i<checks.length; i++) {
n@1116 486 if (checks[i].type == 'check')
n@1116 487 {
n@1116 488 switch(checks[i].name) {
n@1116 489 case 'fragmentPlayed':
n@1116 490 // Check if all fragments have been played
n@1116 491 var checkState = interfaceContext.checkAllPlayed();
n@1116 492 if (checkState == false) {canContinue = false;}
n@1116 493 break;
n@1116 494 case 'fragmentFullPlayback':
n@1116 495 // Check all fragments have been played to their full length
n@1116 496 var checkState = interfaceContext.checkAllPlayed();
n@1116 497 if (checkState == false) {canContinue = false;}
n@1116 498 console.log('NOTE: fragmentFullPlayback not currently implemented, performing check fragmentPlayed instead');
n@1116 499 break;
n@1116 500 case 'fragmentMoved':
n@1116 501 // Check all fragment sliders have been moved.
n@1116 502 var checkState = interfaceContext.checkAllMoved();
n@1116 503 if (checkState == false) {canContinue = false;}
n@1116 504 break;
n@1116 505 case 'fragmentComments':
n@1116 506 // Check all fragment sliders have been moved.
n@1116 507 var checkState = interfaceContext.checkAllCommented();
n@1116 508 if (checkState == false) {canContinue = false;}
n@1116 509 break;
n@1116 510 //case 'scalerange':
n@1116 511 // Check the scale is used to its full width outlined by the node
n@1116 512 //var checkState = interfaceContext.checkScaleRange();
n@1116 513 //if (checkState == false) {canContinue = false;}
n@1116 514 // break;
n@1116 515 default:
n@1116 516 console.log("WARNING - Check option "+checks[i].check+" is not supported on this interface");
n@1116 517 break;
n@1116 518 }
n@1116 519
n@1116 520 }
n@1116 521 if (!canContinue) {break;}
n@1116 522 }
n@1116 523
n@1116 524 if (canContinue) {
n@1116 525 if (audioEngineContext.status == 1) {
n@1116 526 var playback = document.getElementById('playback-button');
n@1116 527 playback.click();
n@1116 528 // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options
n@1116 529 } else
n@1116 530 {
n@1116 531 if (audioEngineContext.timer.testStarted == false)
n@1116 532 {
n@1116 533 alert('You have not started the test! Please press start to begin the test!');
n@1116 534 return;
n@1116 535 }
n@1116 536 }
n@1116 537 testState.advanceState();
n@1116 538 }
n@1116 539 }
n@1116 540
n@1116 541 function pageXMLSave(store, pageSpecification)
n@1116 542 {
n@1116 543 // MANDATORY
n@1116 544 // Saves a specific test page
n@1116 545 // You can use this space to add any extra nodes to your XML <audioHolder> saves
n@1116 546 // Get the current <page> information in store (remember to appendChild your data to it)
n@1116 547 // pageSpecification is the current page node configuration
n@1116 548 // To create new XML nodes, use storage.document.createElement();
n@1116 549 }