annotate test_create/test_create.html @ 1016:3b24b06f93a1

Create_test: Submit button exposes completed XML file.
author Nicholas Jillings <n.g.r.jillings@se14.qmul.ac.uk>
date Wed, 03 Jun 2015 12:15:14 +0100
parents 9ad0ee1430de
children e103d40537b5
rev   line source
n@1010 1 <!DOCTYPE html>
n@1010 2 <html lang="en">
n@1010 3 <head>
n@1010 4 <meta charset="utf-8">
n@1010 5
n@1010 6 <!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
n@1010 7 Remove this if you use the .htaccess -->
n@1010 8 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
n@1010 9
n@1010 10 <title>WAET Create Test</title>
n@1010 11 <meta name="description" content="">
n@1010 12 <meta name="author" content="">
n@1010 13
n@1010 14 <meta name="viewport" content="width=device-width; initial-scale=1.0">
n@921 15
n@921 16 <script type="text/javascript">
n@921 17 // To aid 'one-page set-up' all scripts and CSS must be included directly in this file!
n@921 18 var topLevel;
n@921 19 window.onload = function() {
n@921 20 // Initialise page
n@921 21 topLevel = document.getElementById('topLevelBody');
n@921 22 var setup = document.createElement('div');
n@921 23 setup.id = 'setupTagDiv';
n@921 24
n@921 25 };
n@921 26
n@924 27 function attributePair(string, type, mandatory){
n@921 28 var id = document.createElement("span");
n@921 29 id.textContent = string;
n@921 30 var input = document.createElement("input");
n@921 31 input.type = type;
n@924 32 if (type == 'text') {
n@924 33 if (mandatory == true) {
n@924 34 input.setAttribute('mandatory','true');
n@924 35 }
n@924 36 else {
n@924 37 input.setAttribute('mandatory','false');
n@924 38 }
n@924 39 }
n@921 40 return [id, input];
n@921 41 }
n@921 42
n@922 43 function removeNode(event) {
n@922 44 event.srcElement.parentElement.parentElement.removeChild(event.srcElement.parentElement);
n@922 45 }
n@922 46
n@924 47 function buttonClickedValidate() {
n@924 48 var ready = validate();
n@924 49 if (ready == false) {
n@924 50 var errMsg = document.getElementById('errorMessage');
n@925 51 errMsg.textContent = "There were some errors with your XML. Any input boxes highlighted in red are invalid because they are empty or because its ID matches another elements ID. Please fill these in correctly. Any boxes which are yellow are not-invalid but will use the default value.";
n@924 52 errMsg.style.visibility = 'visible';
n@924 53 document.getElementById('createXML').disabled = true;
n@924 54
n@924 55 } else {
n@924 56 var errMsg = document.getElementById('errorMessage');
n@924 57 errMsg.textContent = "";
n@924 58 errMsg.style.visiblity = 'hidden';
n@924 59 document.getElementById('createXML').disabled = false;
n@924 60 }
n@924 61 }
n@924 62
n@925 63 function buttonClickedSubmit() {
n@925 64 var ready = validate();
n@925 65 if (ready == true) {
n@1016 66 var xmlDoc = buildXML();
n@1016 67 var inject = document.getElementById('errorMessage');
n@1016 68 createProjectSave(xmlDoc, inject);
n@1016 69 }
n@1016 70 }
n@1016 71
n@1016 72 function createProjectSave(xmlDoc, injectPoint) {
n@1016 73 var parent = document.createElement("div");
n@1016 74 parent.appendChild(xmlDoc);
n@1016 75 var file = [parent.innerHTML];
n@1016 76 var bb = new Blob(file,{type : 'application/xml'});
n@1016 77 var dnlk = window.URL.createObjectURL(bb);
n@1016 78 var a = document.createElement("a");
n@1016 79 a.hidden = '';
n@1016 80 a.href = dnlk;
n@1016 81 a.download = "save.xml";
n@1016 82 a.textContent = "Save File";
n@1016 83 injectPoint.appendChild(a);
n@1016 84 }
n@1016 85
n@1016 86 function buildXML() {
n@1016 87 var xmlDoc = document.createElement('BrowserEvalProjectDocument');
n@1016 88 var setup = document.createElement('setup');
n@1016 89 setup.setAttribute('interface',document.getElementById('interface').value);
n@1016 90 if (document.getElementById('projectReturn').value == "") {
n@1016 91 setup.setAttribute('projectReturn',"null");
n@1016 92 } else {
n@1016 93 setup.setAttribute('projectReturn',document.getElementById('projectReturn').value);
n@1016 94 }
n@1016 95 setup.setAttribute('randomiseOrder',document.getElementById('randomisePageOrder').checked);
n@1016 96 setup.setAttribute('collectMetrics',document.getElementById('collectMetrics').checked);
n@1016 97
n@1016 98 var globalPreTest = document.createElement('preTest');
n@1016 99 var options = document.getElementById('globalPreTest').getElementsByClassName('head');
n@1016 100 constructPrePost(globalPreTest, options);
n@1016 101
n@1016 102 var globalPostTest = document.createElement('postTest');
n@1016 103 options = document.getElementById('globalPostTest').getElementsByClassName('head');
n@1016 104 constructPrePost(globalPostTest, options);
n@1016 105
n@1016 106 var globalMetrics = document.createElement('metric');
n@1016 107 options = document.getElementById('globalMetric').getElementsByClassName('attrib')[0].getElementsByTagName('input');
n@1016 108 for (var i=0; i<options.length; i++) {
n@1016 109 if (options[i].checked) {
n@1016 110 var metric = document.createElement('metricEnable');
n@1016 111 metric.textContent = options[i].id;
n@1016 112 globalMetrics.appendChild(metric);
n@925 113 }
n@1016 114 }
n@1016 115 setup.appendChild(globalPreTest);
n@1016 116 setup.appendChild(globalPostTest);
n@1016 117 setup.appendChild(globalMetrics);
n@1016 118 xmlDoc.appendChild(setup);
n@1016 119
n@1016 120 var audioHolders = document.getElementsByName('audio-holder');
n@1016 121 for (var i=0; i<audioHolders.length; i++) {
n@1016 122 var audioHolder = document.createElement('audioHolder');
n@1016 123 var audioHolderDOM = audioHolders[i];
n@1016 124 var attribs = audioHolderDOM.getElementsByClassName('attrib')[0].getElementsByTagName('input');
n@1016 125 audioHolder.id = attribs[0].value;
n@1016 126 if (attribs[1].value != "") {audioHolder.setAttribute('sampleRate',attribs[1].value);}
n@1016 127 if (attribs[2].value != "") {audioHolder.setAttribute('hostURL',attribs[2].value);}
n@1016 128 audioHolder.setAttribute('randomiseOrder',attribs[3].checked);
n@1016 129 audioHolder.setAttribute('repeatCount',attribs[4].checked);
n@1016 130 audioHolder.setAttribute('loop',attribs[5].checked);
n@1016 131 audioHolder.setAttribute('elementComments',attribs[6].checked);
n@925 132
n@1016 133 // Audio-Holder PreTests
n@1016 134 var audioHolderPreTest = document.createElement('preTest');
n@1016 135 var audioHolderPostTest = document.createElement('postTest');
n@1016 136 options = audioHolderDOM.childNodes[2].getElementsByClassName('head');
n@1016 137 constructPrePost(audioHolderPreTest, options);
n@1016 138 options = audioHolderDOM.childNodes[3].getElementsByClassName('head');
n@1016 139 constructPrePost(audioHolderPostTest, options);
n@925 140
n@1016 141 audioHolder.appendChild(audioHolderPreTest);
n@1016 142 audioHolder.appendChild(audioHolderPostTest);
n@925 143
n@1016 144 // audio-Elements
n@1016 145 var audioElementsDOM = [];
n@1016 146 var commentQuestionDOM = [];
n@1016 147 for (var j=0; j<audioHolderDOM.childElementCount; j++) {
n@1016 148 var child = audioHolderDOM.childNodes[j];
n@1016 149 var name = child.getAttribute('name');
n@1016 150 if (name == 'audio-element') {audioElementsDOM.push(child);}
n@1016 151 else if (name == 'comment-question') {commentQuestionDOM.push(child);}
n@925 152 }
n@925 153
n@1016 154 for (var j=0; j<audioElementsDOM.length; j++) {
n@1016 155 var audioElement = document.createElement('audioElement');
n@1016 156 attribs = audioElementsDOM[j].getElementsByClassName('attrib')[0].getElementsByTagName('input');
n@1016 157 audioElement.id = attribs[0].value;
n@1016 158 audioElement.setAttribute('url',attribs[1].value);
n@1016 159 audioHolder.appendChild(audioElement);
n@1015 160 }
n@1016 161
n@1016 162 for (var j=0; j<commentQuestionDOM.length; j++) {
n@1016 163 var commentQuestion = document.createElement('commentQuestion');
n@1016 164 attribs = commentQuestionDOM[j].getElementsByClassName('attrib')[0].getElementsByTagName('input');
n@1016 165 commentQuestion.id = attribs[0].value;
n@1016 166 commentQuestion.textContent = attribs[1].value;
n@1016 167 audioHolder.appendChild(commentQuestion);
n@1016 168 }
n@1016 169 xmlDoc.appendChild(audioHolder);
n@925 170 }
n@1016 171 return xmlDoc;
n@925 172 }
n@925 173
n@925 174 function constructPrePost(parent, options) {
n@925 175 for (var i=0; i<options.length; i++) {
n@925 176 var elem = options[i];
n@925 177 var attributes = elem.getElementsByClassName('attrib')[0].getElementsByTagName('input');
n@925 178 if (elem.getAttribute('name') == 'question-node') {
n@925 179 var node = document.createElement('question');
n@925 180 node.setAttribute('id',attributes[0].value);
n@925 181 node.textContent = attributes[1].value;
n@925 182 } else if (elem.getAttribute('name') == 'statement-node') {
n@925 183 var node = document.createElement('statment');
n@925 184 node.textContent = attributes[0].value;
n@925 185 }
n@925 186 parent.appendChild(node);
n@925 187 }
n@925 188 }
n@925 189
n@924 190 function validate() {
n@924 191 var canExport = true;
n@924 192 // Checks if the XML can be created from the given entries
n@924 193 var inputs = document.getElementsByTagName('input');
n@924 194 for (var i=0; i<inputs.length; i++) {
n@924 195 if (inputs[i].type == 'text') {
n@924 196 if (inputs[i].value == "") {
n@924 197 var mandatory = inputs[i].getAttribute('mandatory');
n@924 198 if (mandatory == "true") {
n@924 199 errorInput(inputs[i]);
n@924 200 canExport = false;
n@924 201 } else {
n@924 202 warningInput(inputs[i]);
n@924 203 }
n@924 204 } else {
n@924 205 goodInput(inputs[i]);
n@924 206 }
n@924 207 }
n@924 208 }
n@925 209
n@925 210 var audioHolders = document.getElementsByName('audio-holder');
n@925 211 for (var i=0; i<audioHolders.length; i++) {
n@925 212 var divs = audioHolders[i].getElementsByClassName('head');
n@925 213 var IDs = [];
n@925 214 for (var j=0; j<divs.length; j++) {
n@925 215 if (divs[j].getAttribute('name') == 'audio-element') {
n@925 216 var obj = divs[j].getElementsByClassName('attrib')[0].children[1];
n@925 217 var aeID = obj.value;
n@925 218 if (aeID != "") {
n@925 219 var unique = true;
n@925 220 for (var k=0; k<IDs.length; k++) {
n@925 221 if (aeID == IDs[k]) {
n@925 222 unique = false;
n@925 223 break;
n@925 224 }
n@925 225 }
n@925 226 if (unique == true) {
n@925 227 IDs.push(aeID);
n@925 228 } else {
n@925 229 errorInput(obj);
n@925 230 canExport = false;
n@925 231 }
n@925 232 }
n@925 233 }
n@925 234 }
n@925 235 }
n@924 236 return canExport;
n@924 237 };
n@924 238
n@924 239 function errorInput(node) {
n@924 240 node.style.backgroundColor = "#FF0000";
n@924 241 }
n@924 242
n@924 243 function warningInput(node) {
n@924 244 node.style.backgroundColor = "#FFFF00";
n@924 245 }
n@924 246
n@924 247 function goodInput(node) {
n@924 248 node.style.backgroundColor = "#FFFFFF";
n@924 249 }
n@924 250
n@921 251 function questionNode() {
n@921 252 var node = document.createElement("div");
n@921 253 node.setAttribute('class','head');
n@921 254 node.setAttribute('name','question-node');
n@921 255 var nodeTitle = document.createElement("span");
n@921 256 nodeTitle.textContent = "Question";
n@921 257 var attributes = document.createElement("div");
n@921 258 attributes.setAttribute('class','attrib');
n@924 259 var id = attributePair("ID:","text", true);
n@924 260 var question = attributePair("Question:","text", false);
n@921 261 node.appendChild(nodeTitle);
n@921 262 id.forEach(function(item){attributes.appendChild(item);},false);
n@921 263 question.forEach(function(item){attributes.appendChild(item);},false);
n@921 264 node.appendChild(attributes);
n@922 265
n@922 266 var removeButton = document.createElement("button");
n@922 267 removeButton.textContent = "Remove";
n@922 268 removeButton.onclick = removeNode;
n@922 269 node.appendChild(removeButton);
n@921 270 return node;
n@921 271 }
n@921 272
n@921 273 function statementNode() {
n@921 274 var node = document.createElement("div");
n@921 275 node.setAttribute('class','head');
n@924 276 node.setAttribute('name','statement-node');
n@921 277 var nodeTitle = document.createElement("span");
n@921 278 nodeTitle.textContent = "Statement";
n@921 279 var attributes = document.createElement("div");
n@921 280 attributes.setAttribute('class','attrib');
n@924 281 var statement = attributePair("Statement:","text",false);
n@921 282 node.appendChild(nodeTitle);
n@921 283 statement.forEach(function(item){attributes.appendChild(item);},false);
n@921 284 node.appendChild(attributes);
n@922 285
n@922 286 var removeButton = document.createElement("button");
n@922 287 removeButton.textContent = "Remove";
n@922 288 removeButton.onclick = removeNode;
n@922 289 node.appendChild(removeButton);
n@921 290 return node;
n@921 291 }
n@921 292
n@921 293 function audioHolderNode() {
n@921 294 var audioHolderCounts = document.getElementsByName("audio-holder").length;
n@921 295 var node = document.createElement("div");
n@921 296 node.setAttribute("class","head");
n@921 297 node.setAttribute("name","audio-holder");
n@922 298 node.setAttribute("id","audio-holder-"+audioHolderCounts);
n@921 299 var nodeTitle = document.createElement("span");
n@922 300 nodeTitle.textContent = "Audio Holder "+(audioHolderCounts+1);
n@921 301
n@921 302 var attributes = document.createElement("div");
n@921 303 attributes.setAttribute('class','attrib');
n@924 304 var id = attributePair("ID:","text",true);
n@922 305 id[1].value=audioHolderCounts;
n@924 306 var hostURL = attributePair("Host URL:", "text",false);
n@924 307 var sampleRate = attributePair("Sample Rate:","text",false);
n@922 308 var randomiseOrder = attributePair("Randomise Element Order:","checkbox");
n@922 309 var repeatCount = attributePair("Repeat Page Count:","number");
n@922 310 repeatCount[1].value = 0;
n@922 311 var loop = attributePair("Loop Element Playback","checkbox");
n@922 312 var elementComments = attributePair("Enable Comment Boxes","checkbox");
n@922 313 id.forEach(function(item){attributes.appendChild(item);},false);
n@922 314 hostURL.forEach(function(item){attributes.appendChild(item);},false);
n@922 315 sampleRate.forEach(function(item){attributes.appendChild(item);},false);
n@922 316 hostURL.forEach(function(item){attributes.appendChild(item);},false);
n@922 317 randomiseOrder.forEach(function(item){attributes.appendChild(item);},false);
n@922 318 repeatCount.forEach(function(item){attributes.appendChild(item);},false);
n@922 319 loop.forEach(function(item){attributes.appendChild(item);},false);
n@922 320 elementComments.forEach(function(item){attributes.appendChild(item);},false);
n@922 321
n@922 322 node.appendChild(nodeTitle);
n@922 323 node.appendChild(attributes);
n@922 324
n@922 325 var pretest = document.createElement("div");
n@922 326 pretest.setAttribute('class','head');
n@922 327 pretest.setAttribute('name','pre-test');
n@922 328 var pretestTitle = document.createElement("h4");
n@922 329 pretestTitle.textContent = "Pre Test";
n@922 330 var buttonAddQ = document.createElement("button");
n@922 331 buttonAddQ.textContent = "Add Pre Test Question";
n@922 332 buttonAddQ.onclick = function(){event.srcElement.parentElement.appendChild(questionNode());};
n@922 333 var buttonAddS = document.createElement("button");
n@922 334 buttonAddS.textContent = "Add Pre Test Statement";
n@922 335 buttonAddS.onclick = function(){event.srcElement.parentElement.appendChild(statementNode());};
n@922 336 pretest.appendChild(pretestTitle);
n@922 337 pretest.appendChild(buttonAddQ);
n@922 338 pretest.appendChild(buttonAddS);
n@922 339
n@922 340 var posttest = document.createElement("div");
n@922 341 posttest.setAttribute('class','head');
n@922 342 posttest.setAttribute('name','post-test');
n@922 343 var posttestTitle = document.createElement("h4");
n@922 344 posttestTitle.textContent = "Post Test";
n@922 345 var buttonAddQ = document.createElement("button");
n@922 346 buttonAddQ.textContent = "Add Post Test Question";
n@922 347 buttonAddQ.onclick = function(){event.srcElement.parentElement.appendChild(questionNode());};
n@922 348 var buttonAddS = document.createElement("button");
n@922 349 buttonAddS.textContent = "Add Post Test Statement";
n@922 350 buttonAddS.onclick = function(){event.srcElement.parentElement.appendChild(statementNode());};
n@922 351 posttest.appendChild(posttestTitle);
n@922 352 posttest.appendChild(buttonAddQ);
n@922 353 posttest.appendChild(buttonAddS);
n@922 354
n@922 355 node.appendChild(pretest);
n@922 356 node.appendChild(posttest);
n@922 357
n@922 358 var newAudioElementButton = document.createElement("button");
n@922 359 newAudioElementButton.textContent = "Add audio element";
n@922 360 newAudioElementButton.onclick = function(){
n@922 361 event.srcElement.parentElement.appendChild(audioElementNode());
n@922 362 };
n@922 363 node.appendChild(newAudioElementButton);
n@922 364
n@922 365 var newCommentButton = document.createElement("button");
n@922 366 newCommentButton.textContent = "Add Comment Box";
n@922 367 newCommentButton.onclick = function() {
n@922 368 event.srcElement.parentElement.appendChild(commentBox());
n@922 369 };
n@922 370 node.appendChild(newCommentButton);
n@922 371
n@922 372 var removeButton = document.createElement("button");
n@922 373 removeButton.textContent = "Remove Audio Holder";
n@922 374 removeButton.onclick = removeNode;
n@922 375 node.appendChild(removeButton);
n@922 376 return node;
n@922 377 }
n@922 378
n@922 379 function audioElementNode() {
n@922 380 var parentStructure = event.srcElement.parentElement.childNodes;
n@922 381 var audioElemCounts = 0;
n@922 382 for (var i=0; i<parentStructure.length; i++) {
n@922 383 if (parentStructure[i].getAttribute('name') == "audio-element")
n@922 384 {audioElemCounts++;}
n@922 385 }
n@922 386 var node = document.createElement('div');
n@922 387 node.setAttribute('class','head');
n@922 388 node.setAttribute('name','audio-element');
n@922 389 var nodeTitle = document.createElement('span');
n@922 390 nodeTitle.textContent = 'Audio Element '+(audioElemCounts+1);
n@922 391
n@922 392 var attributes = document.createElement("div");
n@922 393 attributes.setAttribute('class','attrib');
n@924 394 var id = attributePair("ID:","text",true);
n@922 395 id[1].value = audioElemCounts;
n@924 396 var url = attributePair("URL:","text",true);
n@922 397 id.forEach(function(item){attributes.appendChild(item);},false);
n@922 398 url.forEach(function(item){attributes.appendChild(item);},false);
n@922 399
n@922 400 node.appendChild(nodeTitle);
n@922 401 node.appendChild(attributes);
n@922 402
n@922 403 var removeButton = document.createElement("button");
n@922 404 removeButton.textContent = "Remove Audio Element";
n@922 405 removeButton.onclick = removeNode;
n@922 406 node.appendChild(removeButton);
n@922 407 return node;
n@922 408 }
n@922 409
n@922 410 function commentBox() {
n@922 411 var node = document.createElement('div');
n@922 412 node.setAttribute('class','head');
n@922 413 node.setAttribute('name','comment-question');
n@922 414 var nodeTitle = document.createElement('h4');
n@922 415 nodeTitle.textContent = "Comment Box";
n@922 416
n@922 417 var attributes = document.createElement('div');
n@922 418 attributes.setAttribute('class','attrib');
n@924 419 var id = attributePair("ID:",'text',true);
n@924 420 var question = attributePair("Question:",'text',true);
n@922 421 id.forEach(function(item){attributes.appendChild(item);},false);
n@922 422 question.forEach(function(item){attributes.appendChild(item);},false);
n@922 423
n@922 424 var removeButton = document.createElement("button");
n@922 425 removeButton.textContent = "Remove Comment Box";
n@922 426 removeButton.onclick = removeNode;
n@922 427
n@922 428 node.appendChild(nodeTitle);
n@922 429 node.appendChild(attributes);
n@922 430 node.appendChild(removeButton);
n@922 431 return node;
n@921 432 }
n@921 433 </script>
n@921 434 <style>
n@921 435 div {
n@921 436 padding: 2px;
n@921 437 margin-top: 2px;
n@921 438 margin-bottom: 2px;
n@921 439 }
n@921 440 div.head{
n@921 441 margin-left: 10px;
n@921 442 border: black;
n@921 443 border-width: 2px;
n@921 444 border-style: solid;
n@921 445 }
n@921 446 div.attrib{
n@921 447 margin-left:25px;
n@921 448 border: black;
n@921 449 border-width: 2px;
n@921 450 border-style: dashed;
n@921 451 margin-bottom: 10px;
n@921 452 }
n@921 453 </style>
n@921 454
n@1010 455 </head>
n@1010 456
n@1010 457 <body>
n@921 458 <h1>Create Test Setup XML</h1>
n@924 459 <button id="validateXML" onclick="buttonClickedValidate();">Validate</button>
n@1016 460 <button id="createXML" onclick="buttonClickedSubmit();" disabled>Submit</button>
n@924 461 <span id="errorMessage" visibility="hidden"></span>
n@921 462 <div id="topLevelBody" align="left">
n@1010 463 <!-- Interface goes here -->
n@921 464 <div name='test-setup'>
n@921 465 <div id="setup" class="head">
n@921 466 <h2>Setup Tag</h2>
n@921 467 <div id="setup-attribs" class="attrib">
n@921 468 <span>Interface</span>
n@921 469 <select id="interface">
n@921 470 <option value='APE'>APE</option>
n@921 471 </select>
n@921 472 <span>Project Return</span>
n@924 473 <input type="text" id="projectReturn" mandatory="false">
n@921 474 <span>Randomise Test Page Order</span>
n@921 475 <input id="randomisePageOrder" type="checkbox" value="false">
n@921 476 <span>Collect Session Metrics</span>
n@921 477 <input id="collectMetrics" type="checkbox">
n@921 478 </div>
n@921 479 <div id="globalPreTest" class="head">
n@921 480 <h3>Pre Test</h3>
n@921 481 <button id="addPreTestQ" onclick="event.srcElement.parentElement.appendChild(questionNode());">Add Pre Test Question</button>
n@921 482 <button id="addPreTestS" onclick="event.srcElement.parentElement.appendChild(statementNode());">Add Pre Test Statement</button>
n@921 483 </div>
n@921 484 <div id="globalPostTest" class="head">
n@921 485 <h3>Post Test</h3>
n@921 486 <button id="addPreTestQ" onclick="event.srcElement.parentElement.appendChild(questionNode());">Add Post Test Question</button>
n@921 487 <button id="addPreTestS" onclick="event.srcElement.parentElement.appendChild(statementNode());">Add Post Test Statement</button>
n@921 488 </div>
n@921 489 <div id="globalMetric" class="head">
n@921 490 <h3>Global Metrics</h3>
n@921 491 <div id="globalMetric-attrib" class="attrib">
n@921 492 <span>Test Timer</span>
n@921 493 <input type="checkbox" id="testTimer" />
n@921 494 <span>Element Playback Timer</span>
n@921 495 <input type="checkbox" id="elementTimer" />
n@921 496 <span>Element Initial Position</span>
n@921 497 <input type="checkbox" id="elementInitialPosition" />
n@921 498 <span>Element Tracker</span>
n@921 499 <input type="checkbox" id="elementTracker" />
n@921 500 <span>Element Flag Listened To</span>
n@925 501 <input type="checkbox" id="elementFlagListenedTo" />
n@921 502 <span>Element Flag Moved</span>
n@921 503 <input type="checkbox" id="elementFlagMoved" />
n@921 504 </div>
n@921 505 </div>
n@922 506 <button id="addAudioHolder" onclick="event.srcElement.parentElement.appendChild(audioHolderNode());">Add AudioHolder / Test Page</button>
n@921 507 </div>
n@921 508 </div>
n@1010 509 </div>
n@1010 510 </body>
n@1010 511 </html>