comparison core.js @ 371:ad267c5e32ae

Merge of dev into default/master
author Nicholas Jillings <n.g.r.jillings@se14.qmul.ac.uk>
date Fri, 04 Dec 2015 11:00:55 +0000
parents ed22a47dcacd
children 6139c53deba1
comparison
equal deleted inserted replaced
370:58fdadeb1414 371:ad267c5e32ae
71 this.popup.style.top = (window.innerHeight/2)-125 + 'px'; 71 this.popup.style.top = (window.innerHeight/2)-125 + 'px';
72 72
73 this.popupContent = document.createElement('div'); 73 this.popupContent = document.createElement('div');
74 this.popupContent.id = 'popupContent'; 74 this.popupContent.id = 'popupContent';
75 this.popupContent.style.marginTop = '20px'; 75 this.popupContent.style.marginTop = '20px';
76 this.popupContent.align = 'center'; 76 this.popupContent.style.marginBottom = '5px';
77 this.popup.appendChild(this.popupContent); 77 this.popup.appendChild(this.popupContent);
78 78
79 var titleHolder = document.createElement('div'); 79 var titleHolder = document.createElement('div');
80 titleHolder.id = 'popupTitleHolder'; 80 titleHolder.id = 'popupTitleHolder';
81 titleHolder.align = 'center';
81 titleHolder.style.width = 'inherit'; 82 titleHolder.style.width = 'inherit';
82 titleHolder.style.height = '25px'; 83 titleHolder.style.minHeight = '25px';
84 titleHolder.style.maxHeight = '250px';
85 titleHolder.style.overflow = 'auto';
83 titleHolder.style.marginBottom = '5px'; 86 titleHolder.style.marginBottom = '5px';
84 87
85 this.popupTitle = document.createElement('span'); 88 this.popupTitle = document.createElement('span');
86 this.popupTitle.id = 'popupTitle'; 89 this.popupTitle.id = 'popupTitle';
87 titleHolder.appendChild(this.popupTitle); 90 titleHolder.appendChild(this.popupTitle);
88 this.popupContent.appendChild(titleHolder); 91 this.popupContent.appendChild(titleHolder);
89 92
90 this.popupResponse = document.createElement('div'); 93 this.popupResponse = document.createElement('div');
91 this.popupResponse.id = 'popupResponse'; 94 this.popupResponse.id = 'popupResponse';
95 this.popupResponse.align = 'center';
92 this.popupResponse.style.width = 'inherit'; 96 this.popupResponse.style.width = 'inherit';
93 this.popupResponse.style.minHeight = '170px'; 97 this.popupResponse.style.minHeight = '50px';
94 this.popupResponse.style.maxHeight = '320px'; 98 this.popupResponse.style.maxHeight = '320px';
95 this.popupResponse.style.overflow = 'auto'; 99 this.popupResponse.style.overflow = 'auto';
96 this.popupContent.appendChild(this.popupResponse); 100 this.popupContent.appendChild(this.popupResponse);
97 101
98 var buttonHolder = document.createElement('div');
99 buttonHolder.id='buttonHolder';
100 buttonHolder.width = 'inherit';
101 buttonHolder.style.height= '30px';
102 buttonHolder.align = 'left';
103 this.popupContent.appendChild(buttonHolder);
104
105 this.buttonProceed = document.createElement('button'); 102 this.buttonProceed = document.createElement('button');
106 this.buttonProceed.className = 'popupButton'; 103 this.buttonProceed.className = 'popupButton';
104 this.buttonProceed.position = 'relative';
107 this.buttonProceed.style.left = '390px'; 105 this.buttonProceed.style.left = '390px';
108 this.buttonProceed.style.top = '2px';
109 this.buttonProceed.innerHTML = 'Next'; 106 this.buttonProceed.innerHTML = 'Next';
110 this.buttonProceed.onclick = function(){popup.proceedClicked();}; 107 this.buttonProceed.onclick = function(){popup.proceedClicked();};
111 108
112 this.buttonPrevious = document.createElement('button'); 109 this.buttonPrevious = document.createElement('button');
113 this.buttonPrevious.className = 'popupButton'; 110 this.buttonPrevious.className = 'popupButton';
111 this.buttonPrevious.position = 'relative';
114 this.buttonPrevious.style.left = '10px'; 112 this.buttonPrevious.style.left = '10px';
115 this.buttonPrevious.style.top = '2px';
116 this.buttonPrevious.innerHTML = 'Back'; 113 this.buttonPrevious.innerHTML = 'Back';
117 this.buttonPrevious.onclick = function(){popup.previousClick();}; 114 this.buttonPrevious.onclick = function(){popup.previousClick();};
118 115
119 buttonHolder.appendChild(this.buttonPrevious); 116 this.popupContent.appendChild(this.buttonPrevious);
120 buttonHolder.appendChild(this.buttonProceed); 117 this.popupContent.appendChild(this.buttonProceed);
121 118
122 this.popup.style.zIndex = -1; 119 this.popup.style.zIndex = -1;
123 this.popup.style.visibility = 'hidden'; 120 this.popup.style.visibility = 'hidden';
124 blank.style.zIndex = -2; 121 blank.style.zIndex = -2;
125 blank.style.visibility = 'hidden'; 122 blank.style.visibility = 'hidden';
137 blank.style.zIndex = 2; 134 blank.style.zIndex = 2;
138 blank.style.visibility = 'visible'; 135 blank.style.visibility = 'visible';
139 $(window).keypress(function(e){ 136 $(window).keypress(function(e){
140 if (e.keyCode == 13 && popup.popup.style.visibility == 'visible') 137 if (e.keyCode == 13 && popup.popup.style.visibility == 'visible')
141 { 138 {
142 // Enter key pressed
143 var textarea = $(popup.popupContent).find('textarea');
144 if (textarea.length != 0)
145 {
146 if (textarea[0] == document.activeElement)
147 {return;}
148 }
149 popup.buttonProceed.onclick(); 139 popup.buttonProceed.onclick();
150 } 140 }
151 }); 141 });
152 }; 142 };
153 143
156 this.popup.style.visibility = 'hidden'; 146 this.popup.style.visibility = 'hidden';
157 var blank = document.getElementsByClassName('testHalt')[0]; 147 var blank = document.getElementsByClassName('testHalt')[0];
158 blank.style.zIndex = -2; 148 blank.style.zIndex = -2;
159 blank.style.visibility = 'hidden'; 149 blank.style.visibility = 'hidden';
160 this.buttonPrevious.style.visibility = 'inherit'; 150 this.buttonPrevious.style.visibility = 'inherit';
151 $(window).keypress(function(e){});
161 }; 152 };
162 153
163 this.postNode = function() { 154 this.postNode = function() {
164 // This will take the node from the popupOptions and display it 155 // This will take the node from the popupOptions and display it
165 var node = this.popupOptions[this.currentIndex]; 156 var node = this.popupOptions[this.currentIndex];
188 case 'huge': 179 case 'huge':
189 textArea.cols = "50"; 180 textArea.cols = "50";
190 textArea.rows = "10"; 181 textArea.rows = "10";
191 break; 182 break;
192 } 183 }
193 document.onkeydown=function(){
194 if(window.event.keyCode=='13'){ // when you hit enter
195 window.event.preventDefault(); // don't make newline
196 popup.proceedClicked(); // go to the next window (or start the test or submit)
197 }
198 }
199 this.popupResponse.appendChild(textArea); 184 this.popupResponse.appendChild(textArea);
200 textArea.focus(); 185 textArea.focus();
201 } else if (node.type == 'checkbox') { 186 } else if (node.type == 'checkbox') {
202 this.popupTitle.textContent = node.statement; 187 this.popupTitle.textContent = node.statement;
203 var optHold = this.popupResponse; 188 var optHold = this.popupResponse;
240 if (node.min != null) {input.min = node.min;} 225 if (node.min != null) {input.min = node.min;}
241 if (node.max != null) {input.max = node.max;} 226 if (node.max != null) {input.max = node.max;}
242 if (node.step != null) {input.step = node.step;} 227 if (node.step != null) {input.step = node.step;}
243 this.popupResponse.appendChild(input); 228 this.popupResponse.appendChild(input);
244 } 229 }
230 var content_height = Number(this.popup.offsetHeight.toFixed());
231 content_height -= Number(this.popupContent.offsetHeight.toFixed());
232 content_height -=Number(this.buttonProceed.offsetHeight.toFixed());
233 content_height = content_height + "px";
234 this.buttonProceed.style.top = content_height;
235 this.buttonPrevious.style.top = content_height;
245 if(this.currentIndex+1 == this.popupOptions.length) { 236 if(this.currentIndex+1 == this.popupOptions.length) {
246 if (this.responses.nodeName == "PRETEST") { 237 if (this.responses.nodeName == "PRETEST") {
247 this.buttonProceed.textContent = 'Start'; 238 this.buttonProceed.textContent = 'Start';
248 } else { 239 } else {
249 this.buttonProceed.textContent = 'Submit'; 240 this.buttonProceed.textContent = 'Submit';
725 var xmlDoc = document.createElement("BrowserEvaluationResult"); 716 var xmlDoc = document.createElement("BrowserEvaluationResult");
726 var projectDocument = specification.projectXML; 717 var projectDocument = specification.projectXML;
727 projectDocument.setAttribute('file-name',url); 718 projectDocument.setAttribute('file-name',url);
728 xmlDoc.appendChild(projectDocument); 719 xmlDoc.appendChild(projectDocument);
729 xmlDoc.appendChild(returnDateNode()); 720 xmlDoc.appendChild(returnDateNode());
721 xmlDoc.appendChild(interfaceContext.returnNavigator());
730 for (var i=0; i<testState.stateResults.length; i++) 722 for (var i=0; i<testState.stateResults.length; i++)
731 { 723 {
732 xmlDoc.appendChild(testState.stateResults[i]); 724 xmlDoc.appendChild(testState.stateResults[i]);
733 } 725 }
734 726
950 this.bufferNode.connect(this.outputGain); 942 this.bufferNode.connect(this.outputGain);
951 this.bufferNode.buffer = this.buffer; 943 this.bufferNode.buffer = this.buffer;
952 this.bufferNode.loop = audioEngineContext.loopPlayback; 944 this.bufferNode.loop = audioEngineContext.loopPlayback;
953 this.bufferNode.onended = function(event) { 945 this.bufferNode.onended = function(event) {
954 // Safari does not like using 'this' to reference the calling object! 946 // Safari does not like using 'this' to reference the calling object!
955 event.currentTarget.owner.metric.stopListening(audioEngineContext.timer.getTestTime(),event.currentTarget.owner.getCurrentPosition()); 947 //event.currentTarget.owner.metric.stopListening(audioEngineContext.timer.getTestTime(),event.currentTarget.owner.getCurrentPosition());
948 event.currentTarget.owner.stop();
956 }; 949 };
957 if (this.bufferNode.loop == false) { 950 if (this.bufferNode.loop == false) {
958 this.metric.startListening(audioEngineContext.timer.getTestTime()); 951 this.metric.startListening(audioEngineContext.timer.getTestTime());
959 } 952 }
960 this.bufferNode.start(startTime); 953 this.bufferNode.start(startTime);
973 this.getCurrentPosition = function() { 966 this.getCurrentPosition = function() {
974 var time = audioEngineContext.timer.getTestTime(); 967 var time = audioEngineContext.timer.getTestTime();
975 if (this.bufferNode != undefined) { 968 if (this.bufferNode != undefined) {
976 if (this.bufferNode.loop == true) { 969 if (this.bufferNode.loop == true) {
977 if (audioEngineContext.status == 1) { 970 if (audioEngineContext.status == 1) {
978 return time%this.buffer.duration; 971 return (time-this.metric.listenStart)%this.buffer.duration;
979 } else { 972 } else {
980 return 0; 973 return 0;
981 } 974 }
982 } else { 975 } else {
983 if (this.metric.listenHold) { 976 if (this.metric.listenHold) {
1316 } 1309 }
1317 1310
1318 function Specification() { 1311 function Specification() {
1319 // Handles the decoding of the project specification XML into a simple JavaScript Object. 1312 // Handles the decoding of the project specification XML into a simple JavaScript Object.
1320 1313
1321 this.interfaceType; 1314 this.interfaceType = null;
1322 this.commonInterface; 1315 this.commonInterface = null;
1323 this.projectReturn; 1316 this.projectReturn = null;
1324 this.randomiseOrder; 1317 this.randomiseOrder = null;
1325 this.collectMetrics; 1318 this.collectMetrics = null;
1326 this.testPages; 1319 this.testPages = null;
1327 this.preTest; 1320 this.preTest = null;
1328 this.postTest; 1321 this.postTest = null;
1329 this.metrics =[]; 1322 this.metrics =[];
1330 1323
1331 this.audioHolders = []; 1324 this.audioHolders = [];
1332 1325
1333 this.decode = function() { 1326 this.decode = function() {
1393 } else { 1386 } else {
1394 this.max = Number(this.max); 1387 this.max = Number(this.max);
1395 } 1388 }
1396 } 1389 }
1397 } else if (this.type == 'anchor' || this.type == 'reference') { 1390 } else if (this.type == 'anchor' || this.type == 'reference') {
1398 this.value = Number(child.textContent); 1391 Console.log("WARNING: Anchor and Reference tags in the <interface> node are depricated");
1399 this.enforce = child.getAttribute('enforce');
1400 if (this.enforce == 'true') {this.enforce = true;}
1401 else {this.enforce = false;}
1402 } 1392 }
1403 }; 1393 };
1404 this.options = []; 1394 this.options = [];
1405 if (commonInterfaceNode != undefined) { 1395 if (commonInterfaceNode != undefined) {
1406 var child = commonInterfaceNode.firstElementChild; 1396 var child = commonInterfaceNode.firstElementChild;
1541 if (this.type == 'anchor') {this.anchor = true;} 1531 if (this.type == 'anchor') {this.anchor = true;}
1542 else {this.anchor = false;} 1532 else {this.anchor = false;}
1543 if (this.type == 'reference') {this.reference = true;} 1533 if (this.type == 'reference') {this.reference = true;}
1544 else {this.reference = false;} 1534 else {this.reference = false;}
1545 1535
1546 this.marker = xml.getAttribute('marker'); 1536 if (this.anchor == true || this.reference == true)
1547 if (this.marker == null) {this.marker = undefined;} 1537 {
1548 1538 this.marker = xml.getAttribute('marker');
1549 if (this.anchor == true) { 1539 if (this.marker != undefined)
1550 if (this.marker != undefined) {this.enforce = true;} 1540 {
1551 else {this.enforce = enforceAnchor;} 1541 this.marker = Number(this.marker);
1552 this.marker = anchor; 1542 if (isNaN(this.marker) == false)
1553 } 1543 {
1554 else if (this.reference == true) { 1544 if (this.marker > 1)
1555 if (this.marker != undefined) {this.enforce = true;} 1545 { this.marker /= 100.0;}
1556 else {this.enforce = enforceReference;} 1546 if (this.marker >= 0 && this.marker <= 1)
1557 this.marker = reference; 1547 {
1558 } 1548 this.enforce = true;
1559 1549 return;
1560 if (this.marker != undefined) { 1550 } else {
1561 this.marker = Number(this.marker); 1551 console.log("ERROR - Marker of audioElement "+this.id+" is not between 0 and 1 (float) or 0 and 100 (integer)!");
1562 if (this.marker > 1) {this.marker /= 100;} 1552 console.log("ERROR - Marker not enforced!");
1563 } 1553 }
1554 } else {
1555 console.log("ERROR - Marker of audioElement "+this.id+" is not a number!");
1556 console.log("ERROR - Marker not enforced!");
1557 }
1558 }
1559 }
1560 this.marker = false;
1561 this.enforce = false;
1564 }; 1562 };
1565 1563
1566 this.commentQuestionNode = function(xml) { 1564 this.commentQuestionNode = function(xml) {
1567 this.childOption = function(element) { 1565 this.childOption = function(element) {
1568 this.type = 'option'; 1566 this.type = 'option';
1614 if (xml.getAttribute('loop') == 'true') {this.loop = true;} 1612 if (xml.getAttribute('loop') == 'true') {this.loop = true;}
1615 else {this.loop == false;} 1613 else {this.loop == false;}
1616 if (xml.getAttribute('elementComments') == "true") {this.elementComments = true;} 1614 if (xml.getAttribute('elementComments') == "true") {this.elementComments = true;}
1617 else {this.elementComments = false;} 1615 else {this.elementComments = false;}
1618 1616
1619 var anchor = xml.getElementsByTagName('anchor');
1620 var enforceAnchor = false;
1621 if (anchor.length == 0) {
1622 // Find anchor in commonInterface;
1623 for (var i=0; i<parent.commonInterface.options.length; i++) {
1624 if(parent.commonInterface.options[i].type == 'anchor') {
1625 anchor = parent.commonInterface.options[i].value;
1626 enforceAnchor = parent.commonInterface.options[i].enforce;
1627 break;
1628 }
1629 }
1630 if (typeof(anchor) == "object") {
1631 anchor = null;
1632 }
1633 } else {
1634 anchor = anchor[0].textContent;
1635 }
1636
1637 var reference = xml.getElementsByTagName('anchor');
1638 var enforceReference = false;
1639 if (reference.length == 0) {
1640 // Find anchor in commonInterface;
1641 for (var i=0; i<parent.commonInterface.options.length; i++) {
1642 if(parent.commonInterface.options[i].type == 'reference') {
1643 reference = parent.commonInterface.options[i].value;
1644 enforceReference = parent.commonInterface.options[i].enforce;
1645 break;
1646 }
1647 }
1648 if (typeof(reference) == "object") {
1649 reference = null;
1650 }
1651 } else {
1652 reference = reference[0].textContent;
1653 }
1654
1655 if (typeof(anchor) == 'number') {
1656 if (anchor > 1 && anchor < 100) {anchor /= 100.0;}
1657 }
1658
1659 if (typeof(reference) == 'number') {
1660 if (reference > 1 && reference < 100) {reference /= 100.0;}
1661 }
1662
1663 this.preTest = new parent.prepostNode('pretest',xml.getElementsByTagName('PreTest')); 1617 this.preTest = new parent.prepostNode('pretest',xml.getElementsByTagName('PreTest'));
1664 this.postTest = new parent.prepostNode('posttest',xml.getElementsByTagName('PostTest')); 1618 this.postTest = new parent.prepostNode('posttest',xml.getElementsByTagName('PostTest'));
1665 1619
1666 this.interfaces = []; 1620 this.interfaces = [];
1667 var interfaceDOM = xml.getElementsByTagName('interface'); 1621 var interfaceDOM = xml.getElementsByTagName('interface');
1695 1649
1696 if (this.randomiseOrder) { 1650 if (this.randomiseOrder) {
1697 this.audioElements = randomiseOrder(this.audioElements); 1651 this.audioElements = randomiseOrder(this.audioElements);
1698 } 1652 }
1699 1653
1700 // Check only one anchor and one reference per audioNode
1701 var anchor = [];
1702 var reference = [];
1703 this.anchorId = null;
1704 this.referenceId = null;
1705 for (var i=0; i<this.audioElements.length; i++)
1706 {
1707 if (this.audioElements[i].anchor == true) {anchor.push(i);}
1708 if (this.audioElements[i].reference == true) {reference.push(i);}
1709 }
1710
1711 if (anchor.length > 1) {
1712 console.log('Error - cannot have more than one anchor!');
1713 console.log('Each anchor node will be a normal mode to continue the test');
1714 for (var i=0; i<anchor.length; i++)
1715 {
1716 this.audioElements[anchor[i]].anchor = false;
1717 this.audioElements[anchor[i]].value = undefined;
1718 }
1719 } else {this.anchorId = anchor[0];}
1720 if (reference.length > 1) {
1721 console.log('Error - cannot have more than one anchor!');
1722 console.log('Each anchor node will be a normal mode to continue the test');
1723 for (var i=0; i<reference.length; i++)
1724 {
1725 this.audioElements[reference[i]].reference = false;
1726 this.audioElements[reference[i]].value = undefined;
1727 }
1728 } else {this.referenceId = reference[0];}
1729
1730 this.commentQuestions = []; 1654 this.commentQuestions = [];
1731 var commentQuestionsDOM = xml.getElementsByTagName('CommentQuestion'); 1655 var commentQuestionsDOM = xml.getElementsByTagName('CommentQuestion');
1732 for (var i=0; i<commentQuestionsDOM.length; i++) { 1656 for (var i=0; i<commentQuestionsDOM.length; i++) {
1733 this.commentQuestions.push(new this.commentQuestionNode(commentQuestionsDOM[i])); 1657 this.commentQuestions.push(new this.commentQuestionNode(commentQuestionsDOM[i]));
1734 } 1658 }
1759 catch(err) 1683 catch(err)
1760 { 1684 {
1761 console.log("Warning - Interface does not have Resize option"); 1685 console.log("Warning - Interface does not have Resize option");
1762 console.log(err); 1686 console.log(err);
1763 } 1687 }
1688 };
1689
1690 this.returnNavigator = function()
1691 {
1692 var node = document.createElement("navigator");
1693 var platform = document.createElement("platform");
1694 platform.textContent = navigator.platform;
1695 var vendor = document.createElement("vendor");
1696 vendor.textContent = navigator.vendor;
1697 var userAgent = document.createElement("uagent");
1698 userAgent.textContent = navigator.userAgent;
1699 node.appendChild(platform);
1700 node.appendChild(vendor);
1701 node.appendChild(userAgent);
1702 return node;
1764 }; 1703 };
1765 1704
1766 this.commentBoxes = []; 1705 this.commentBoxes = [];
1767 this.elementCommentBox = function(audioObject) { 1706 this.elementCommentBox = function(audioObject) {
1768 var element = audioObject.specification; 1707 var element = audioObject.specification;
2245 return false; 2184 return false;
2246 } 2185 }
2247 } 2186 }
2248 return true; 2187 return true;
2249 }; 2188 };
2189
2190 this.checkFragmentsFullyPlayed = function ()
2191 {
2192 // Checks the entire file has been played back
2193 // NOTE ! This will return true IF playback is Looped!!!
2194 if (audioEngineContext.loopPlayback)
2195 {
2196 console.log("WARNING - Looped source: Cannot check fragments are fully played");
2197 return true;
2198 }
2199 var check_pass = true;
2200 var error_obj = [];
2201 for (var i = 0; i<audioEngineContext.audioObjects.length; i++)
2202 {
2203 var object = audioEngineContext.audioObjects[i];
2204 var time = object.buffer.duration;
2205 var metric = object.metric;
2206 var passed = false;
2207 for (var j=0; j<metric.listenTracker.length; j++)
2208 {
2209 var bt = metric.listenTracker[j].getElementsByTagName('buffertime');
2210 var start_time = Number(bt[0].getAttribute('start'));
2211 var stop_time = Number(bt[0].getAttribute('stop'));
2212 var delta = stop_time - start_time;
2213 if (delta >= time)
2214 {
2215 passed = true;
2216 break;
2217 }
2218 }
2219 if (passed == false)
2220 {
2221 check_pass = false;
2222 console.log("Continue listening to track-"+i);
2223 error_obj.push(i);
2224 }
2225 }
2226 if (check_pass == false)
2227 {
2228 var str_start = "You have not listened to fragments ";
2229 for (var i=0; i<error_obj.length; i++)
2230 {
2231 str_start += error_obj[i];
2232 if (i != error_obj.length-1)
2233 {
2234 str_start += ', ';
2235 }
2236 }
2237 str_start += ". Please keep listening";
2238 console.log("[ALERT]: "+str_start);
2239 alert(str_start);
2240 }
2241 };
2250 } 2242 }