annotate interfaces/ordinal.js @ 2846:64a83c964fae

#141 Add submit button interactions
author Nicholas Jillings <nicholas.jillings@mail.bcu.ac.uk>
date Tue, 25 Apr 2017 15:47:18 +0100
parents be138735977b
children ed2c8a04b7c4
rev   line source
nicholas@2844 1 /**
nicholas@2844 2 * WAET Blank Template
nicholas@2844 3 * Use this to start building your custom interface
nicholas@2844 4 */
nicholas@2844 5 /*globals interfaceContext, window, document, specification, audioEngineContext, console, testState, $, storage */
nicholas@2844 6 // Once this is loaded and parsed, begin execution
nicholas@2844 7 loadInterface();
nicholas@2844 8
nicholas@2844 9 function loadInterface() {
nicholas@2844 10 // Use this to do any one-time page / element construction. For instance, placing any stationary text objects,
nicholas@2844 11 // holding div's, or setting up any nodes which are present for the entire test sequence
nicholas@2844 12
nicholas@2844 13 // The injection point into the HTML page
nicholas@2844 14 interfaceContext.insertPoint = document.getElementById("topLevelBody");
nicholas@2844 15 var testContent = document.createElement('div');
nicholas@2844 16 testContent.id = 'testContent';
nicholas@2844 17
nicholas@2844 18 // Create the top div for the Title element
nicholas@2844 19 var titleAttr = specification.title;
nicholas@2844 20 var title = document.createElement('div');
nicholas@2844 21 title.className = "title";
nicholas@2844 22 title.align = "center";
nicholas@2844 23 var titleSpan = document.createElement('span');
nicholas@2844 24 titleSpan.id = "test-title";
nicholas@2844 25
nicholas@2844 26 // Set title to that defined in XML, else set to default
nicholas@2844 27 if (titleAttr !== undefined) {
nicholas@2844 28 titleSpan.textContent = titleAttr;
nicholas@2844 29 } else {
nicholas@2844 30 titleSpan.textContent = 'Listening test';
nicholas@2844 31 }
nicholas@2844 32 // Insert the titleSpan element into the title div element.
nicholas@2844 33 title.appendChild(titleSpan);
nicholas@2844 34
nicholas@2844 35 var pagetitle = document.createElement('div');
nicholas@2844 36 pagetitle.className = "pageTitle";
nicholas@2844 37 pagetitle.align = "center";
nicholas@2844 38
nicholas@2844 39 titleSpan = document.createElement('span');
nicholas@2844 40 titleSpan.id = "pageTitle";
nicholas@2844 41 pagetitle.appendChild(titleSpan);
nicholas@2844 42
nicholas@2844 43 // Create Interface buttons!
nicholas@2844 44 var interfaceButtons = document.createElement('div');
nicholas@2844 45 interfaceButtons.id = 'interface-buttons';
nicholas@2844 46 interfaceButtons.style.height = '25px';
nicholas@2844 47
nicholas@2844 48 // Create playback start/stop points
nicholas@2844 49 var playback = document.createElement("button");
nicholas@2844 50 playback.innerHTML = 'Stop';
nicholas@2844 51 playback.id = 'playback-button';
nicholas@2844 52 playback.style.float = 'left';
nicholas@2844 53 // onclick function. Check if it is playing or not, call the correct function in the
nicholas@2844 54 // audioEngine, change the button text to reflect the next state.
nicholas@2844 55 playback.onclick = function () {
nicholas@2844 56 if (audioEngineContext.status == 1) {
nicholas@2844 57 audioEngineContext.stop();
nicholas@2844 58 this.innerHTML = 'Stop';
nicholas@2844 59 var time = audioEngineContext.timer.getTestTime();
nicholas@2844 60 console.log('Stopped at ' + time); // DEBUG/SAFETY
nicholas@2844 61 }
nicholas@2844 62 };
nicholas@2844 63 // Create Submit (save) button
nicholas@2844 64 var submit = document.createElement("button");
nicholas@2844 65 submit.innerHTML = 'Next';
nicholas@2844 66 submit.onclick = buttonSubmitClick;
nicholas@2844 67 submit.id = 'submit-button';
nicholas@2844 68 submit.style.float = 'left';
nicholas@2844 69 // Append the interface buttons into the interfaceButtons object.
nicholas@2844 70 interfaceButtons.appendChild(playback);
nicholas@2844 71 interfaceButtons.appendChild(submit);
nicholas@2844 72
nicholas@2844 73 // Create outside reference holder
nicholas@2844 74 var outsideRef = document.createElement("div");
nicholas@2844 75 outsideRef.id = "outside-reference-holder";
nicholas@2844 76
nicholas@2844 77 // Create a slider box
nicholas@2844 78 var slider = document.createElement("div");
nicholas@2844 79 slider.id = "slider";
nicholas@2845 80 slider.style.height = "300px";
nicholas@2844 81
nicholas@2844 82 // Global parent for the comment boxes on the page
nicholas@2844 83 var feedbackHolder = document.createElement('div');
nicholas@2844 84 feedbackHolder.id = 'feedbackHolder';
nicholas@2844 85
nicholas@2844 86 testContent.style.zIndex = 1;
nicholas@2844 87 interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema
nicholas@2844 88
nicholas@2844 89 // Inject into HTML
nicholas@2844 90 testContent.appendChild(title); // Insert the title
nicholas@2844 91 testContent.appendChild(pagetitle);
nicholas@2844 92 testContent.appendChild(interfaceButtons);
nicholas@2844 93 testContent.appendChild(outsideRef);
nicholas@2844 94 testContent.appendChild(slider);
nicholas@2844 95 testContent.appendChild(feedbackHolder);
nicholas@2844 96 interfaceContext.insertPoint.appendChild(testContent);
nicholas@2844 97
nicholas@2844 98 // Load the full interface
nicholas@2844 99 testState.initialise();
nicholas@2844 100 testState.advanceState();
nicholas@2844 101 }
nicholas@2844 102
nicholas@2844 103 function loadTest(page) {
nicholas@2844 104 // Called each time a new test page is to be build. The page specification node is the only item passed in
nicholas@2844 105 var id = page.id;
nicholas@2844 106
nicholas@2844 107 var feedbackHolder = document.getElementById('feedbackHolder');
nicholas@2844 108 feedbackHolder.innerHTML = "";
nicholas@2844 109
nicholas@2844 110 var interfaceObj = interfaceContext.getCombinedInterfaces(page);
nicholas@2844 111 if (interfaceObj.length > 1) {
nicholas@2844 112 console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node");
nicholas@2844 113 }
nicholas@2844 114 interfaceObj = interfaceObj[0];
nicholas@2844 115
nicholas@2844 116 // Set the page title
nicholas@2844 117 if (typeof page.title == "string" && page.title.length > 0) {
nicholas@2844 118 document.getElementById("test-title").textContent = page.title;
nicholas@2844 119 }
nicholas@2844 120
nicholas@2844 121 if (interfaceObj.title !== null) {
nicholas@2844 122 document.getElementById("pageTitle").textContent = interfaceObj.title;
nicholas@2844 123 }
nicholas@2844 124
nicholas@2844 125 if (interfaceObj.image !== undefined) {
nicholas@2844 126 feedbackHolder.insertBefore(interfaceContext.imageHolder.root, document.getElementById("slider"));
nicholas@2844 127 interfaceContext.imageHolder.setImage(interfaceObj.image);
nicholas@2844 128 }
nicholas@2844 129 // Delete outside reference
nicholas@2844 130 document.getElementById("outside-reference-holder").innerHTML = "";
nicholas@2844 131
nicholas@2844 132 var sliderBox = document.getElementById('slider');
nicholas@2844 133 sliderBox.innerHTML = "";
nicholas@2844 134
nicholas@2844 135 var commentBoxPrefix = "Comment on track";
nicholas@2844 136 if (interfaceObj.commentBoxPrefix !== undefined) {
nicholas@2844 137 commentBoxPrefix = interfaceObj.commentBoxPrefix;
nicholas@2844 138 }
nicholas@2844 139
nicholas@2844 140 $(page.commentQuestions).each(function (index, element) {
nicholas@2844 141 var node = interfaceContext.createCommentQuestion(element);
nicholas@2844 142 feedbackHolder.appendChild(node.holder);
nicholas@2844 143 });
nicholas@2844 144
nicholas@2844 145 var index = 0;
nicholas@2844 146 var labelType = page.label;
nicholas@2844 147 if (labelType == "default") {
nicholas@2844 148 labelType = "number";
nicholas@2844 149 }
nicholas@2844 150 page.audioElements.forEach(function (element, pageIndex) {
nicholas@2844 151 var audioObject = audioEngineContext.newTrack(element);
nicholas@2844 152 if (element.type == 'outside-reference') {
nicholas@2844 153 // Construct outside reference;
nicholas@2844 154 var orNode = new interfaceContext.outsideReferenceDOM(audioObject, index, document.getElementById("outside-reference-holder"));
nicholas@2844 155 audioObject.bindInterface(orNode);
nicholas@2844 156 } else {
nicholas@2844 157 // Create a slider per track
nicholas@2844 158 var label = interfaceContext.getLabel(labelType, index, page.labelStart);
nicholas@2844 159 var sliderObj = new interfaceObject(audioObject, label);
nicholas@2844 160
nicholas@2844 161 sliderBox.appendChild(sliderObj.root);
nicholas@2844 162 audioObject.bindInterface(sliderObj);
nicholas@2844 163 interfaceContext.commentBoxes.createCommentBox(audioObject);
nicholas@2844 164 index += 1;
nicholas@2844 165 }
nicholas@2844 166 });
nicholas@2845 167 interfaceObj.options.forEach(function (option) {
nicholas@2845 168 if (option.type == "show") {
nicholas@2845 169 switch (option.name) {
nicholas@2845 170 case "playhead":
nicholas@2845 171 var playbackHolder = document.getElementById('playback-holder');
nicholas@2845 172 if (playbackHolder === null) {
nicholas@2845 173 playbackHolder = document.createElement('div');
nicholas@2845 174 playbackHolder.style.width = "100%";
nicholas@2845 175 playbackHolder.align = 'center';
nicholas@2845 176 playbackHolder.appendChild(interfaceContext.playhead.object);
nicholas@2845 177 feedbackHolder.appendChild(playbackHolder);
nicholas@2845 178 }
nicholas@2845 179 break;
nicholas@2845 180 case "page-count":
nicholas@2845 181 var pagecountHolder = document.getElementById('page-count');
nicholas@2845 182 if (pagecountHolder === null) {
nicholas@2845 183 pagecountHolder = document.createElement('div');
nicholas@2845 184 pagecountHolder.id = 'page-count';
nicholas@2845 185 }
nicholas@2845 186 pagecountHolder.innerHTML = '<span>Page ' + (testState.stateIndex + 1) + ' of ' + testState.stateMap.length + '</span>';
nicholas@2845 187 var inject = document.getElementById('interface-buttons');
nicholas@2845 188 inject.appendChild(pagecountHolder);
nicholas@2845 189 break;
nicholas@2845 190 case "volume":
nicholas@2845 191 if (document.getElementById('master-volume-holder') === null) {
nicholas@2845 192 feedbackHolder.appendChild(interfaceContext.volume.object);
nicholas@2845 193 }
nicholas@2845 194 break;
nicholas@2845 195 case "comments":
nicholas@2845 196 interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder, true);
nicholas@2845 197 break;
nicholas@2845 198 }
nicholas@2845 199 }
nicholas@2845 200 });
nicholas@2844 201 resizeWindow();
nicholas@2844 202 }
nicholas@2844 203
nicholas@2844 204 function interfaceObject(audioObject, label) {
nicholas@2844 205 var container = document.getElementById("slider");
nicholas@2844 206 var playing = false;
nicholas@2844 207 var root = document.createElement("div");
nicholas@2844 208 root.className = "ordinal-element";
nicholas@2844 209 root.draggable = "true";
nicholas@2844 210 var labelElement = document.createElement("span");
nicholas@2844 211 labelElement.className = "ordinal-element-label";
nicholas@2844 212 labelElement.textContent = label;
nicholas@2844 213 root.appendChild(labelElement);
nicholas@2844 214 root.classList.add("disabled");
nicholas@2844 215 // An example node, you can make this however you want for each audioElement.
nicholas@2844 216 // However, every audioObject (audioEngineContext.audioObject) MUST have an interface object with the following
nicholas@2844 217 // You attach them by calling audioObject.bindInterface( )
nicholas@2844 218 root.addEventListener("click", this, true);
nicholas@2844 219 root.addEventListener('dragstart', this, true);
nicholas@2844 220 root.addEventListener('dragenter', this, true);
nicholas@2844 221 root.addEventListener('dragover', this, true);
nicholas@2844 222 root.addEventListener('dragleave', this, true);
nicholas@2844 223 root.addEventListener('drop', this, true);
nicholas@2844 224 root.addEventListener('dragend', this, true);
nicholas@2844 225 this.handleEvent = function (event) {
nicholas@2844 226 if (event.type == "click") {
nicholas@2844 227 if (playing === false) {
nicholas@2844 228 audioEngineContext.play(audioObject.id);
nicholas@2844 229 } else {
nicholas@2844 230 audioEngineContext.stop();
nicholas@2844 231 }
nicholas@2844 232 playing = !playing;
nicholas@2844 233 return;
nicholas@2844 234 } else if (event.type == "dragstart") {
nicholas@2844 235 return dragStart.call(this, event);
nicholas@2844 236 } else if (event.type == "dragenter") {
nicholas@2844 237 return dragEnter.call(this, event);
nicholas@2844 238 } else if (event.type == "dragleave") {
nicholas@2844 239 return dragLeave.call(this, event);
nicholas@2844 240 } else if (event.type == "dragover") {
nicholas@2844 241 return dragOver.call(this, event);
nicholas@2844 242 } else if (event.type == "drop") {
nicholas@2844 243 return drop.call(this, event);
nicholas@2844 244 } else if (event.type == "dragend") {
nicholas@2844 245 return dragEnd.call(this, event);
nicholas@2844 246 }
nicholas@2844 247 throw (event);
nicholas@2844 248 };
nicholas@2844 249
nicholas@2844 250 function dragStart(e) {
nicholas@2844 251 e.currentTarget.classList.add("dragging");
nicholas@2844 252
nicholas@2844 253 e.dataTransfer.effectAllowed = 'move';
nicholas@2844 254 e.dataTransfer.setData('text/plain', audioObject.id);
nicholas@2844 255 }
nicholas@2844 256
nicholas@2844 257 function dragEnter(e) {
nicholas@2844 258 // this / e.target is the current hover target.
nicholas@2844 259 root.classList.add('over');
nicholas@2844 260 }
nicholas@2844 261
nicholas@2844 262 function dragLeave(e) {
nicholas@2844 263 root.classList.remove('over'); // this / e.target is previous target element.
nicholas@2844 264 }
nicholas@2844 265
nicholas@2844 266 function dragOver(e) {
nicholas@2844 267 if (e.preventDefault) {
nicholas@2844 268 e.preventDefault(); // Necessary. Allows us to drop.
nicholas@2844 269 }
nicholas@2844 270
nicholas@2844 271 e.dataTransfer.dropEffect = 'move'; // See the section on the DataTransfer object.
nicholas@2844 272
nicholas@2844 273 var srcid = Number(e.dataTransfer.getData("text/plain"));
nicholas@2844 274 var elements = container.childNodes;
nicholas@2844 275 var srcObject = audioEngineContext.audioObjects.find(function (ao) {
nicholas@2844 276 return ao.id === srcid;
nicholas@2844 277 });
nicholas@2844 278 var src = srcObject.interfaceDOM.root;
nicholas@2844 279 if (src !== root) {
nicholas@2844 280 var srcpos = srcObject.interfaceDOM.getElementPosition();
nicholas@2844 281 var mypos = this.getElementPosition();
nicholas@2844 282 var neighbour;
nicholas@2844 283 if (srcpos <= mypos) {
nicholas@2844 284 neighbour = root.nextElementSibling;
nicholas@2844 285 } else {
nicholas@2844 286 neighbour = root;
nicholas@2844 287 }
nicholas@2844 288 if (neighbour)
nicholas@2844 289 container.insertBefore(src, neighbour);
nicholas@2844 290 else {
nicholas@2844 291 container.removeChild(src);
nicholas@2844 292 container.appendChild(src);
nicholas@2844 293 }
nicholas@2844 294
nicholas@2844 295 }
nicholas@2844 296
nicholas@2844 297 return false;
nicholas@2844 298 }
nicholas@2844 299
nicholas@2844 300 function drop(e) {
nicholas@2844 301 // this / e.target is current target element.
nicholas@2844 302
nicholas@2844 303 if (e.stopPropagation) {
nicholas@2844 304 e.stopPropagation(); // stops the browser from redirecting.
nicholas@2844 305 }
nicholas@2844 306 if (e.preventDefault) {
nicholas@2844 307 e.preventDefault(); // Necessary. Allows us to drop.
nicholas@2844 308 }
nicholas@2844 309
nicholas@2844 310 audioEngineContext.audioObjects.forEach(function (ao) {
nicholas@2844 311 ao.interfaceDOM.processMovement();
nicholas@2844 312 });
nicholas@2844 313
nicholas@2844 314 return false;
nicholas@2844 315 }
nicholas@2844 316
nicholas@2844 317 function dragEnd(e) {
nicholas@2844 318 // this/e.target is the source node.
nicholas@2844 319 $(".ordinal-element").removeClass("dragging");
nicholas@2844 320 $(".ordinal-element").removeClass("over");
nicholas@2844 321 }
nicholas@2844 322
nicholas@2844 323 this.getElementPosition = function () {
nicholas@2844 324 var elements = container.childNodes,
nicholas@2844 325 position = 0,
nicholas@2844 326 elem = elements[0];
nicholas@2844 327 while (root !== elem) {
nicholas@2844 328 position++;
nicholas@2844 329 elem = elem.nextElementSibling;
nicholas@2844 330 }
nicholas@2844 331 return position;
nicholas@2845 332 };
nicholas@2844 333
nicholas@2844 334 this.processMovement = function () {
nicholas@2844 335 var time = audioEngineContext.timer.getTestTime();
nicholas@2844 336 var pos = this.getElementPosition();
nicholas@2844 337 var rank = pos / (audioEngineContext.audioObjects.length - 1);
nicholas@2844 338 audioObject.metric.moved(time, rank);
nicholas@2844 339 console.log('slider ' + audioObject.id + ' moved to ' + rank + ' (' + time + ')');
nicholas@2845 340 };
nicholas@2844 341
nicholas@2844 342 this.enable = function () {
nicholas@2844 343 // This is used to tell the interface object that playback of this node is ready
nicholas@2844 344 root.classList.remove("disabled");
nicholas@2844 345 labelElement.textContent = label;
nicholas@2844 346 };
nicholas@2844 347 this.updateLoading = function (progress) {
nicholas@2844 348 // progress is a value from 0 to 100 indicating the current download state of media files
nicholas@2844 349 labelElement.textContent = String(progress);
nicholas@2844 350 };
nicholas@2844 351 this.startPlayback = function () {
nicholas@2844 352 // Called when playback has begun
nicholas@2844 353 root.classList.add("playing");
nicholas@2845 354 if (audioObject.commentDOM) {
nicholas@2845 355 audioObject.commentDOM.trackComment.classList.add("comment-box-playing");
nicholas@2845 356 }
nicholas@2844 357 };
nicholas@2844 358 this.stopPlayback = function () {
nicholas@2844 359 // Called when playback has stopped. This gets called even if playback never started!
nicholas@2844 360 root.classList.remove("playing");
nicholas@2845 361 playing = false;
nicholas@2845 362 if (audioObject.commentDOM) {
nicholas@2845 363 audioObject.commentDOM.trackComment.classList.remove("comment-box-playing");
nicholas@2845 364 }
nicholas@2844 365 };
nicholas@2844 366 this.getValue = function () {
nicholas@2844 367 // Return the current value of the object. If there is no value, return 0
nicholas@2844 368 var pos = this.getElementPosition();
nicholas@2844 369 var rank = pos / (audioEngineContext.audioObjects.length - 1);
nicholas@2844 370 };
nicholas@2844 371 this.getPresentedId = function () {
nicholas@2844 372 // Return the presented ID of the object. For instance, the APE has sliders starting from 0. Whilst AB has alphabetical scale
nicholas@2844 373 return label;
nicholas@2844 374 };
nicholas@2844 375 this.canMove = function () {
nicholas@2844 376 // Return either true or false if the interface object can be moved. AB / Reference cannot, whilst sliders can and therefore have a continuous scale.
nicholas@2844 377 // These are checked primarily if the interface check option 'fragmentMoved' is enabled.
nicholas@2844 378 return true;
nicholas@2844 379 };
nicholas@2844 380 this.exportXMLDOM = function (audioObject) {
nicholas@2844 381 // Called by the audioObject holding this element to export the interface <value> node.
nicholas@2844 382 // If there is no value node (such as outside reference), return null
nicholas@2844 383 // If there are multiple value nodes (such as multiple scale / 2D scales), return an array of nodes with each value node having an 'interfaceName' attribute
nicholas@2844 384 // Use storage.document.createElement('value'); to generate the XML node.
nicholas@2844 385 var node = storage.document.createElement('value');
nicholas@2844 386 node.textContent = this.slider.value;
nicholas@2844 387 return node;
nicholas@2844 388
nicholas@2844 389 };
nicholas@2844 390 this.error = function () {
nicholas@2844 391 // If there is an error with the audioObject, this will be called to indicate a failure
nicholas@2844 392 root.classList.remove("disabled");
nicholas@2844 393 labelElement.textContent = "Error";
nicholas@2844 394 };
nicholas@2844 395 Object.defineProperties(this, {
nicholas@2844 396 "root": {
nicholas@2844 397 "get": function () {
nicholas@2844 398 return root;
nicholas@2844 399 },
nicholas@2844 400 "set": function () {}
nicholas@2844 401 }
nicholas@2844 402 });
nicholas@2844 403 }
nicholas@2844 404
nicholas@2844 405 function resizeWindow(event) {
nicholas@2844 406 // Called on every window resize event, use this to scale your page properly
nicholas@2844 407 var w = $("#slider").width();
nicholas@2844 408 var N = audioEngineContext.audioObjects.length;
nicholas@2844 409 w /= N;
nicholas@2844 410 w -= 14;
nicholas@2845 411 w = Math.floor(w);
nicholas@2844 412 $(".ordinal-element").width(w);
nicholas@2844 413 }
nicholas@2844 414
nicholas@2846 415 function buttonSubmitClick() // TODO: Only when all songs have been played!
nicholas@2846 416 {
nicholas@2846 417 var checks = testState.currentStateMap.interfaces[0].options,
nicholas@2846 418 canContinue = true;
nicholas@2844 419
nicholas@2846 420 // Check that the anchor and reference objects are correctly placed
nicholas@2846 421 if (interfaceContext.checkHiddenAnchor() === false) {
nicholas@2846 422 return;
nicholas@2846 423 }
nicholas@2846 424 if (interfaceContext.checkHiddenReference() === false) {
nicholas@2846 425 return;
nicholas@2846 426 }
nicholas@2846 427
nicholas@2846 428 for (var i = 0; i < checks.length; i++) {
nicholas@2846 429 var checkState = true;
nicholas@2846 430 if (checks[i].type == 'check') {
nicholas@2846 431 switch (checks[i].name) {
nicholas@2846 432 case 'fragmentPlayed':
nicholas@2846 433 // Check if all fragments have been played
nicholas@2846 434 checkState = interfaceContext.checkAllPlayed(checks[i].errorMessage);
nicholas@2846 435 break;
nicholas@2846 436 case 'fragmentFullPlayback':
nicholas@2846 437 // Check all fragments have been played to their full length
nicholas@2846 438 checkState = interfaceContext.checkAllPlayed(checks[i].errorMessage);
nicholas@2846 439 console.log('NOTE: fragmentFullPlayback not currently implemented, performing check fragmentPlayed instead');
nicholas@2846 440 break;
nicholas@2846 441 case 'fragmentMoved':
nicholas@2846 442 // Check all fragment sliders have been moved.
nicholas@2846 443 checkState = interfaceContext.checkAllMoved(checks[i].errorMessage);
nicholas@2846 444 break;
nicholas@2846 445 case 'fragmentComments':
nicholas@2846 446 // Check all fragment sliders have been moved.
nicholas@2846 447 checkState = interfaceContext.checkAllCommented(checks[i].errorMessage);
nicholas@2846 448 break;
nicholas@2846 449 case 'scalerange':
nicholas@2846 450 // Check the scale has been used effectively
nicholas@2846 451 checkState = interfaceContext.checkScaleRange(checks[i].errorMessage);
nicholas@2846 452
nicholas@2846 453 break;
nicholas@2846 454 default:
nicholas@2846 455 console.log("WARNING - Check option " + checks[i].check + " is not supported on this interface");
nicholas@2846 456 break;
nicholas@2846 457 }
nicholas@2846 458 }
nicholas@2846 459 if (checkState === false) {
nicholas@2846 460 canContinue = false;
nicholas@2846 461 break;
nicholas@2846 462 }
nicholas@2846 463 }
nicholas@2846 464
nicholas@2846 465 if (canContinue) {
nicholas@2846 466 if (audioEngineContext.status == 1) {
nicholas@2846 467 var playback = document.getElementById('playback-button');
nicholas@2846 468 playback.click();
nicholas@2846 469 // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options
nicholas@2846 470 } else {
nicholas@2846 471 if (audioEngineContext.timer.testStarted === false) {
nicholas@2846 472 interfaceContext.lightbox.post("Warning", 'You have not started the test! Please press start to begin the test!');
nicholas@2846 473 return;
nicholas@2846 474 }
nicholas@2846 475 }
nicholas@2846 476 testState.advanceState();
nicholas@2846 477 }
nicholas@2844 478 }
nicholas@2844 479
nicholas@2844 480 function pageXMLSave(store, pageSpecification) {
nicholas@2844 481 // MANDATORY
nicholas@2844 482 // Saves a specific test page
nicholas@2844 483 // You can use this space to add any extra nodes to your XML <audioHolder> saves
nicholas@2844 484 // Get the current <page> information in store (remember to appendChild your data to it)
nicholas@2844 485 // pageSpecification is the current page node configuration
nicholas@2844 486 // To create new XML nodes, use storage.document.createElement();
nicholas@2844 487 }