annotate interfaces/ordinal.js @ 3141:335bc77627e0 tip

fixing discrete interface to allow labels to display
author Dave Moffat <me@davemoffat.com>
date Mon, 26 Jul 2021 12:15:24 +0100
parents a8455b0766cd
children
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 */
n@2980 5 /*globals interfaceContext, window, document, specification, audioEngineContext, console, testState, $, storage, sessionStorage */
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@2953 254 e.dataTransfer.setData('text/plain', String(audioObject.id));
nicholas@2953 255 sessionStorage.setItem("drag-object", String(audioObject.id));
nicholas@2844 256 }
nicholas@2844 257
nicholas@2844 258 function dragEnter(e) {
nicholas@2844 259 // this / e.target is the current hover target.
nicholas@2844 260 root.classList.add('over');
nicholas@2844 261 }
nicholas@2844 262
nicholas@2844 263 function dragLeave(e) {
nicholas@2844 264 root.classList.remove('over'); // this / e.target is previous target element.
nicholas@2844 265 }
nicholas@2844 266
nicholas@2844 267 function dragOver(e) {
nicholas@2844 268 if (e.preventDefault) {
nicholas@2844 269 e.preventDefault(); // Necessary. Allows us to drop.
nicholas@2844 270 }
nicholas@2844 271
nicholas@2844 272 e.dataTransfer.dropEffect = 'move'; // See the section on the DataTransfer object.
nicholas@2953 273 var srcid = e.dataTransfer.getData('text/plain');
n@2980 274 if (srcid === "") {
nicholas@2953 275 srcid = sessionStorage.getItem("drag-object");
nicholas@2953 276 }
nicholas@2953 277 console.log(srcid);
n@2980 278 srcid = Number(srcid);
nicholas@2844 279 var elements = container.childNodes;
nicholas@2844 280 var srcObject = audioEngineContext.audioObjects.find(function (ao) {
nicholas@2844 281 return ao.id === srcid;
nicholas@2844 282 });
nicholas@2844 283 var src = srcObject.interfaceDOM.root;
nicholas@2844 284 if (src !== root) {
nicholas@2844 285 var srcpos = srcObject.interfaceDOM.getElementPosition();
nicholas@2844 286 var mypos = this.getElementPosition();
nicholas@2844 287 var neighbour;
nicholas@2844 288 if (srcpos <= mypos) {
nicholas@2844 289 neighbour = root.nextElementSibling;
nicholas@2844 290 } else {
nicholas@2844 291 neighbour = root;
nicholas@2844 292 }
nicholas@2844 293 if (neighbour)
nicholas@2844 294 container.insertBefore(src, neighbour);
nicholas@2844 295 else {
nicholas@2844 296 container.removeChild(src);
nicholas@2844 297 container.appendChild(src);
nicholas@2844 298 }
nicholas@2844 299
nicholas@2844 300 }
nicholas@2844 301
nicholas@2844 302 return false;
nicholas@2844 303 }
nicholas@2844 304
nicholas@2844 305 function drop(e) {
nicholas@2844 306 // this / e.target is current target element.
nicholas@2844 307
nicholas@2844 308 if (e.stopPropagation) {
nicholas@2844 309 e.stopPropagation(); // stops the browser from redirecting.
nicholas@2844 310 }
nicholas@2844 311 if (e.preventDefault) {
nicholas@2844 312 e.preventDefault(); // Necessary. Allows us to drop.
nicholas@2844 313 }
nicholas@2844 314
nicholas@2844 315 audioEngineContext.audioObjects.forEach(function (ao) {
nicholas@2844 316 ao.interfaceDOM.processMovement();
nicholas@2844 317 });
nicholas@2844 318
nicholas@2952 319 sessionStorage.removeItem("drag-object");
nicholas@2952 320
nicholas@2844 321 return false;
nicholas@2844 322 }
nicholas@2844 323
nicholas@2844 324 function dragEnd(e) {
nicholas@2844 325 // this/e.target is the source node.
nicholas@2844 326 $(".ordinal-element").removeClass("dragging");
nicholas@2844 327 $(".ordinal-element").removeClass("over");
nicholas@2844 328 }
nicholas@2844 329
nicholas@2844 330 this.getElementPosition = function () {
nicholas@2844 331 var elements = container.childNodes,
nicholas@2844 332 position = 0,
nicholas@2844 333 elem = elements[0];
nicholas@2844 334 while (root !== elem) {
nicholas@2844 335 position++;
nicholas@2844 336 elem = elem.nextElementSibling;
nicholas@2844 337 }
nicholas@2844 338 return position;
nicholas@2845 339 };
nicholas@2844 340
nicholas@2844 341 this.processMovement = function () {
nicholas@2844 342 var time = audioEngineContext.timer.getTestTime();
nicholas@2844 343 var pos = this.getElementPosition();
nicholas@2844 344 var rank = pos / (audioEngineContext.audioObjects.length - 1);
nicholas@2844 345 audioObject.metric.moved(time, rank);
nicholas@2844 346 console.log('slider ' + audioObject.id + ' moved to ' + rank + ' (' + time + ')');
nicholas@2845 347 };
nicholas@2844 348
nicholas@2844 349 this.enable = function () {
nicholas@2844 350 // This is used to tell the interface object that playback of this node is ready
nicholas@2844 351 root.classList.remove("disabled");
nicholas@2844 352 labelElement.textContent = label;
nicholas@2844 353 };
nicholas@2844 354 this.updateLoading = function (progress) {
nicholas@2844 355 // progress is a value from 0 to 100 indicating the current download state of media files
nicholas@2844 356 labelElement.textContent = String(progress);
nicholas@2844 357 };
nicholas@2844 358 this.startPlayback = function () {
nicholas@2844 359 // Called when playback has begun
nicholas@2844 360 root.classList.add("playing");
nicholas@2845 361 if (audioObject.commentDOM) {
nicholas@2845 362 audioObject.commentDOM.trackComment.classList.add("comment-box-playing");
nicholas@2845 363 }
nicholas@2844 364 };
nicholas@2844 365 this.stopPlayback = function () {
nicholas@2844 366 // Called when playback has stopped. This gets called even if playback never started!
nicholas@2844 367 root.classList.remove("playing");
nicholas@2845 368 playing = false;
nicholas@2845 369 if (audioObject.commentDOM) {
nicholas@2845 370 audioObject.commentDOM.trackComment.classList.remove("comment-box-playing");
nicholas@2845 371 }
nicholas@2844 372 };
nicholas@2844 373 this.getValue = function () {
nicholas@2844 374 // Return the current value of the object. If there is no value, return 0
nicholas@2844 375 var pos = this.getElementPosition();
nicholas@2844 376 var rank = pos / (audioEngineContext.audioObjects.length - 1);
nicholas@2992 377 return rank;
nicholas@2844 378 };
nicholas@2844 379 this.getPresentedId = function () {
nicholas@2844 380 // Return the presented ID of the object. For instance, the APE has sliders starting from 0. Whilst AB has alphabetical scale
nicholas@2844 381 return label;
nicholas@2844 382 };
nicholas@2844 383 this.canMove = function () {
nicholas@2844 384 // 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 385 // These are checked primarily if the interface check option 'fragmentMoved' is enabled.
nicholas@2844 386 return true;
nicholas@2844 387 };
nicholas@2844 388 this.exportXMLDOM = function (audioObject) {
nicholas@2844 389 // Called by the audioObject holding this element to export the interface <value> node.
nicholas@2844 390 // If there is no value node (such as outside reference), return null
nicholas@2844 391 // 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 392 // Use storage.document.createElement('value'); to generate the XML node.
nicholas@2844 393 var node = storage.document.createElement('value');
nicholas@2847 394 node.textContent = this.getValue();
nicholas@2844 395 return node;
nicholas@2844 396
nicholas@2844 397 };
nicholas@2844 398 this.error = function () {
nicholas@2844 399 // If there is an error with the audioObject, this will be called to indicate a failure
nicholas@2844 400 root.classList.remove("disabled");
nicholas@2844 401 labelElement.textContent = "Error";
nicholas@2844 402 };
nicholas@2844 403 Object.defineProperties(this, {
nicholas@2844 404 "root": {
nicholas@2844 405 "get": function () {
nicholas@2844 406 return root;
nicholas@2844 407 },
nicholas@2844 408 "set": function () {}
nicholas@2844 409 }
nicholas@2844 410 });
nicholas@2844 411 }
nicholas@2844 412
nicholas@2844 413 function resizeWindow(event) {
nicholas@2844 414 // Called on every window resize event, use this to scale your page properly
nicholas@2844 415 var w = $("#slider").width();
nicholas@2844 416 var N = audioEngineContext.audioObjects.length;
nicholas@2844 417 w /= N;
nicholas@2844 418 w -= 14;
nicholas@2845 419 w = Math.floor(w);
nicholas@2844 420 $(".ordinal-element").width(w);
nicholas@2844 421 }
nicholas@2844 422
nicholas@2846 423 function buttonSubmitClick() // TODO: Only when all songs have been played!
nicholas@2846 424 {
nicholas@2846 425 var checks = testState.currentStateMap.interfaces[0].options,
nicholas@2846 426 canContinue = true;
nicholas@2844 427
nicholas@2846 428 // Check that the anchor and reference objects are correctly placed
nicholas@2846 429 if (interfaceContext.checkHiddenAnchor() === false) {
nicholas@2846 430 return;
nicholas@2846 431 }
nicholas@2846 432 if (interfaceContext.checkHiddenReference() === false) {
nicholas@2846 433 return;
nicholas@2846 434 }
nicholas@2846 435
nicholas@2846 436 for (var i = 0; i < checks.length; i++) {
nicholas@2846 437 var checkState = true;
nicholas@2846 438 if (checks[i].type == 'check') {
nicholas@2846 439 switch (checks[i].name) {
nicholas@2846 440 case 'fragmentPlayed':
nicholas@2846 441 // Check if all fragments have been played
nicholas@2846 442 checkState = interfaceContext.checkAllPlayed(checks[i].errorMessage);
nicholas@2846 443 break;
nicholas@2846 444 case 'fragmentFullPlayback':
nicholas@2846 445 // Check all fragments have been played to their full length
nicholas@2846 446 checkState = interfaceContext.checkAllPlayed(checks[i].errorMessage);
nicholas@2846 447 console.log('NOTE: fragmentFullPlayback not currently implemented, performing check fragmentPlayed instead');
nicholas@2846 448 break;
nicholas@2846 449 case 'fragmentMoved':
nicholas@2846 450 // Check all fragment sliders have been moved.
nicholas@2846 451 checkState = interfaceContext.checkAllMoved(checks[i].errorMessage);
nicholas@2846 452 break;
nicholas@2846 453 case 'fragmentComments':
nicholas@2846 454 // Check all fragment sliders have been moved.
nicholas@2846 455 checkState = interfaceContext.checkAllCommented(checks[i].errorMessage);
nicholas@2846 456 break;
nicholas@2846 457 case 'scalerange':
nicholas@2846 458 // Check the scale has been used effectively
nicholas@2846 459 checkState = interfaceContext.checkScaleRange(checks[i].errorMessage);
nicholas@2846 460
nicholas@2846 461 break;
nicholas@2846 462 default:
nicholas@2846 463 console.log("WARNING - Check option " + checks[i].check + " is not supported on this interface");
nicholas@2846 464 break;
nicholas@2846 465 }
nicholas@2846 466 }
nicholas@2846 467 if (checkState === false) {
nicholas@2846 468 canContinue = false;
nicholas@2846 469 break;
nicholas@2846 470 }
nicholas@2846 471 }
nicholas@2846 472
nicholas@2846 473 if (canContinue) {
nicholas@2846 474 if (audioEngineContext.status == 1) {
nicholas@2846 475 var playback = document.getElementById('playback-button');
nicholas@2846 476 playback.click();
nicholas@2846 477 // 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 478 } else {
nicholas@2846 479 if (audioEngineContext.timer.testStarted === false) {
nicholas@2846 480 interfaceContext.lightbox.post("Warning", 'You have not started the test! Please press start to begin the test!');
nicholas@2846 481 return;
nicholas@2846 482 }
nicholas@2846 483 }
nicholas@2846 484 testState.advanceState();
nicholas@2846 485 }
nicholas@2844 486 }
nicholas@2844 487
nicholas@2844 488 function pageXMLSave(store, pageSpecification) {
nicholas@2844 489 // MANDATORY
nicholas@2844 490 // Saves a specific test page
nicholas@2844 491 // You can use this space to add any extra nodes to your XML <audioHolder> saves
nicholas@2844 492 // Get the current <page> information in store (remember to appendChild your data to it)
nicholas@2844 493 // pageSpecification is the current page node configuration
nicholas@2844 494 // To create new XML nodes, use storage.document.createElement();
nicholas@2844 495 }