Mercurial > hg > webaudioevaluationtool
comparison test_create/test_create.html @ 444:9c9fd68693b1
Merge. Pull of revision info from dev_main.
author | Nicholas Jillings <n.g.r.jillings@se14.qmul.ac.uk> |
---|---|
date | Wed, 23 Dec 2015 14:36:00 +0000 |
parents | db353cc479b8 |
children | 9a8ede168aba |
comparison
equal
deleted
inserted
replaced
442:1081368deed7 | 444:9c9fd68693b1 |
---|---|
102 text.textContent = "Thank you for downloading the Web Audio Evaluation Toolbox. This page will help guide you through creating the documents required to run a test. If you have an existing XML file you wish to edit, please drag and drop it into the box below"; | 102 text.textContent = "Thank you for downloading the Web Audio Evaluation Toolbox. This page will help guide you through creating the documents required to run a test. If you have an existing XML file you wish to edit, please drag and drop it into the box below"; |
103 var dnd = document.createElement('div'); | 103 var dnd = document.createElement('div'); |
104 dnd.style.width = "100%"; | 104 dnd.style.width = "100%"; |
105 dnd.style.height = "50px"; | 105 dnd.style.height = "50px"; |
106 dnd.className = "dragndrop"; | 106 dnd.className = "dragndrop"; |
107 dnd.ondragover = function(e) { | |
108 e.stopPropagation(); | |
109 e.preventDefault(); | |
110 }; | |
111 dnd.ondragenter = function(e) { | |
112 e.stopPropagation(); | |
113 e.preventDefault(); | |
114 this.style.backgroundColor = '#AAFFAA'; | |
115 }; | |
116 dnd.ondragleave = function(e) { | |
117 e.stopPropagation(); | |
118 e.preventDefault(); | |
119 this.style.backgroundColor = "#FFFFFF"; | |
120 }; | |
121 dnd.ondrop = function(e) { | |
122 e.stopPropagation(); | |
123 e.preventDefault(); | |
124 | |
125 var file = e.dataTransfer.files[0]; | |
126 | |
127 // Uses HTML5 FileAPI - https://w3c.github.io/FileAPI/#filereader-interface | |
128 var reader = new FileReader(); | |
129 reader.onload = function() { | |
130 var parse = new DOMParser(); | |
131 var xml = parse.parseFromString(reader.result,'text/xml'); | |
132 specificationNode.decode(xml); | |
133 popupInstance.hidePopup(); | |
134 SpecificationToHTML(); | |
135 }; | |
136 reader.readAsText(file); | |
137 | |
138 }; | |
107 this.popupBody.appendChild(text); | 139 this.popupBody.appendChild(text); |
108 this.popupBody.appendChild(dnd); | 140 this.popupBody.appendChild(dnd); |
109 this.showPopup(); | 141 this.showPopup(); |
110 | 142 |
111 var button = document.createElement('button'); | 143 var button = document.createElement('button'); |
1509 this.popupFooter.appendChild(button); | 1541 this.popupFooter.appendChild(button); |
1510 break; | 1542 break; |
1511 case 8: | 1543 case 8: |
1512 this.hidePopup(); | 1544 this.hidePopup(); |
1513 this.state = 0; | 1545 this.state = 0; |
1514 SpecficationToHTML(); | 1546 SpecificationToHTML (); |
1515 } | 1547 } |
1516 this.state++; | 1548 this.state++; |
1517 }; | 1549 }; |
1518 }; | 1550 }; |
1519 | 1551 |
1583 { | 1615 { |
1584 this.check = input.id; | 1616 this.check = input.id; |
1585 } | 1617 } |
1586 }; | 1618 }; |
1587 }; | 1619 }; |
1620 | |
1621 this.randomiseOrder = function(input) | |
1622 { | |
1623 // This takes an array of information and randomises the order | |
1624 var N = input.length; | |
1625 | |
1626 var inputSequence = []; // For safety purposes: keep track of randomisation | |
1627 for (var counter = 0; counter < N; ++counter) | |
1628 inputSequence.push(counter) // Fill array | |
1629 var inputSequenceClone = inputSequence.slice(0); | |
1630 | |
1631 var holdArr = []; | |
1632 var outputSequence = []; | |
1633 for (var n=0; n<N; n++) | |
1634 { | |
1635 // First pick a random number | |
1636 var r = Math.random(); | |
1637 // Multiply and floor by the number of elements left | |
1638 r = Math.floor(r*input.length); | |
1639 // Pick out that element and delete from the array | |
1640 holdArr.push(input.splice(r,1)[0]); | |
1641 // Do the same with sequence | |
1642 outputSequence.push(inputSequence.splice(r,1)[0]); | |
1643 } | |
1644 console.log(inputSequenceClone.toString()); // print original array to console | |
1645 console.log(outputSequence.toString()); // print randomised array to console | |
1646 return holdArr; | |
1647 }; | |
1588 this.projectReturn = null; | 1648 this.projectReturn = null; |
1589 this.randomiseOrder = null; | 1649 this.randomiseOrder = null; |
1590 this.collectMetrics = null; | 1650 this.collectMetrics = null; |
1591 this.testPages = null; | 1651 this.testPages = null; |
1592 this.audioHolders = []; | 1652 this.audioHolders = []; |
1593 this.metrics = []; | 1653 this.metrics = []; |
1594 | 1654 |
1595 this.decode = function() { | 1655 this.decode = function(projectXML) { |
1596 // projectXML - DOM Parsed document | 1656 // projectXML - DOM Parsed document |
1597 this.projectXML = projectXML.childNodes[0]; | 1657 this.projectXML = projectXML.childNodes[0]; |
1598 var setupNode = projectXML.getElementsByTagName('setup')[0]; | 1658 var setupNode = projectXML.getElementsByTagName('setup')[0]; |
1599 this.interfaceType = setupNode.getAttribute('interface'); | 1659 this.interfaceType = setupNode.getAttribute('interface'); |
1600 this.projectReturn = setupNode.getAttribute('projectReturn'); | 1660 this.projectReturn = setupNode.getAttribute('projectReturn'); |
1612 this.testPages = Number(this.testPages); | 1672 this.testPages = Number(this.testPages); |
1613 if (this.testPages == 0) {this.testPages = null;} | 1673 if (this.testPages == 0) {this.testPages = null;} |
1614 } | 1674 } |
1615 var metricCollection = setupNode.getElementsByTagName('Metric'); | 1675 var metricCollection = setupNode.getElementsByTagName('Metric'); |
1616 | 1676 |
1617 this.preTest = new this.prepostNode('pretest',setupNode.getElementsByTagName('PreTest')); | 1677 var setupPreTestNode = setupNode.getElementsByTagName('PreTest'); |
1618 this.postTest = new this.prepostNode('posttest',setupNode.getElementsByTagName('PostTest')); | 1678 if (setupPreTestNode.length != 0) |
1679 { | |
1680 setupPreTestNode = setupPreTestNode[0]; | |
1681 this.preTest.construct(setupPreTestNode); | |
1682 } | |
1683 | |
1684 var setupPostTestNode = setupNode.getElementsByTagName('PostTest'); | |
1685 if (setupPostTestNode.length != 0) | |
1686 { | |
1687 setupPostTestNode = setupPostTestNode[0]; | |
1688 this.postTest.construct(setupPostTestNode); | |
1689 } | |
1619 | 1690 |
1620 if (metricCollection.length > 0) { | 1691 if (metricCollection.length > 0) { |
1621 metricCollection = metricCollection[0].getElementsByTagName('metricEnable'); | 1692 metricCollection = metricCollection[0].getElementsByTagName('metricEnable'); |
1622 for (var i=0; i<metricCollection.length; i++) { | 1693 for (var i=0; i<metricCollection.length; i++) { |
1623 this.metrics.push(new this.metricNode(metricCollection[i].textContent)); | 1694 this.metrics.push(new this.metricNode(metricCollection[i].textContent)); |
1673 } | 1744 } |
1674 }; | 1745 }; |
1675 | 1746 |
1676 var audioHolders = projectXML.getElementsByTagName('audioHolder'); | 1747 var audioHolders = projectXML.getElementsByTagName('audioHolder'); |
1677 for (var i=0; i<audioHolders.length; i++) { | 1748 for (var i=0; i<audioHolders.length; i++) { |
1678 this.audioHolders.push(new this.audioHolderNode(this,audioHolders[i])); | 1749 var node = new this.audioHolderNode(this); |
1750 node.decode(this,audioHolders[i]); | |
1751 this.audioHolders.push(node); | |
1679 } | 1752 } |
1680 | 1753 |
1681 // New check if we need to randomise the test order | 1754 // New check if we need to randomise the test order |
1682 if (this.randomiseOrder) | 1755 if (this.randomiseOrder && typeof randomiseOrder === "function") |
1683 { | 1756 { |
1684 this.audioHolders = randomiseOrder(this.audioHolders); | 1757 this.audioHolders = randomiseOrder(this.audioHolders); |
1685 for (var i=0; i<this.audioHolders.length; i++) | 1758 for (var i=0; i<this.audioHolders.length; i++) |
1686 { | 1759 { |
1687 this.audioHolders[i].presentedId = i; | 1760 this.audioHolders[i].presentedId = i; |
1716 setupNode.setAttribute('testPages',this.testPages); | 1789 setupNode.setAttribute('testPages',this.testPages); |
1717 | 1790 |
1718 var setupPreTest = root.createElement("PreTest"); | 1791 var setupPreTest = root.createElement("PreTest"); |
1719 for (var i=0; i<this.preTest.options.length; i++) | 1792 for (var i=0; i<this.preTest.options.length; i++) |
1720 { | 1793 { |
1721 setupPreTest.appendChild(this.preTest.options.exportXML(root)); | 1794 setupPreTest.appendChild(this.preTest.options[i].exportXML(root)); |
1722 } | 1795 } |
1723 | 1796 |
1724 var setupPostTest = root.createElement("PostTest"); | 1797 var setupPostTest = root.createElement("PostTest"); |
1725 for (var i=0; i<this.preTest.options.length; i++) | 1798 for (var i=0; i<this.postTest.options.length; i++) |
1726 { | 1799 { |
1727 setupPostTest.appendChild(this.postTest.options.exportXML(root)); | 1800 setupPostTest.appendChild(this.postTest.options[i].exportXML(root)); |
1728 } | 1801 } |
1729 | 1802 |
1730 setupNode.appendChild(setupPreTest); | 1803 setupNode.appendChild(setupPreTest); |
1731 setupNode.appendChild(setupPostTest); | 1804 setupNode.appendChild(setupPostTest); |
1732 | 1805 |
1733 // <Metric> tag | 1806 // <Metric> tag |
1734 var Metric = root.createElement("Metric"); | 1807 var Metric = root.createElement("Metric"); |
1735 for (var i=0; i<this.metrics.length; i++) | 1808 for (var i=0; i<this.metrics.length; i++) |
1736 { | 1809 { |
1737 var metricEnable = document.createElement("metricEnable"); | 1810 var metricEnable = root.createElement("metricEnable"); |
1738 metricEnable.textContent = this.metrics[i].enabled; | 1811 metricEnable.textContent = this.metrics[i].enabled; |
1739 Metric.appendChild(metricEnable); | 1812 Metric.appendChild(metricEnable); |
1740 } | 1813 } |
1741 setupNode.appendChild(Metric); | 1814 setupNode.appendChild(Metric); |
1742 | 1815 |
1743 // <interface> tag | 1816 // <interface> tag |
1744 var CommonInterface = root.createElement("interface"); | 1817 var CommonInterface = root.createElement("interface"); |
1745 for (var i=0; i<this.commonInterface.options.length; i++) | 1818 for (var i=0; i<this.commonInterface.options.length; i++) |
1746 { | 1819 { |
1747 var CIObj = this.commonInterface.options[i]; | 1820 var CIObj = this.commonInterface.options[i]; |
1748 var CINode = document.createElement(CIObj.type); | 1821 var CINode = root.createElement(CIObj.type); |
1749 if (CIObj.type == "check") {CINode.setAttribute("name",CIObj.check);} | 1822 if (CIObj.type == "check") {CINode.setAttribute("name",CIObj.check);} |
1750 else {CINode.setAttribute("name",CIObj.name);} | 1823 else {CINode.setAttribute("name",CIObj.name);} |
1751 CommonInterface.appendChild(CINode); | 1824 CommonInterface.appendChild(CINode); |
1752 } | 1825 } |
1753 setupNode.appendChild(CommonInterface); | 1826 setupNode.appendChild(CommonInterface); |
1754 | 1827 |
1755 root.getElementsByTagName("BrowserEvalProjectDocument")[0].appendChild(setupNode); | 1828 root.getElementsByTagName("BrowserEvalProjectDocument")[0].appendChild(setupNode); |
1756 // Time for the <audioHolder> tags | 1829 // Time for the <audioHolder> tags |
1757 for (var ahIndex = 0; ahIndex < this.audioHolders.length; ahIndex++) | 1830 for (var ahIndex = 0; ahIndex < this.audioHolders.length; ahIndex++) |
1758 { | 1831 { |
1759 var AHObj = this.audioHolders[ahIndex]; | 1832 var node = this.audioHolders[ahIndex].encode(root); |
1760 var AHNode = root.createElement("audioHolder"); | 1833 root.getElementsByTagName("BrowserEvalProjectDocument")[0].appendChild(node); |
1761 AHNode.id = AHObj.id; | |
1762 AHNode.setAttribute("hostURL",AHObj.hostURL); | |
1763 AHNode.setAttribute("sampleRate",AHObj.samplerate); | |
1764 AHNode.setAttribute("randomiseOrder",AHObj.randomiseOrder); | |
1765 AHNode.setAttribute("repeatCount",AHObj.repeatCount); | |
1766 AHNode.setAttribute("loop",AHObj.loop); | |
1767 AHNode.setAttribute("elementComments",AHObj.elementComments); | |
1768 | |
1769 // Create <interface> tag | |
1770 for (var i=0; i<AHObj.interfaces.length; i++) | |
1771 { | |
1772 var AHObjInterface = AHObj.interfaces[i]; | |
1773 var AHinterface = root.createElement("interface"); | |
1774 if (AHObjInterface.title != undefined) | |
1775 { | |
1776 var title = root.createElement("title"); | |
1777 title.textContent = AHObjInterface.title; | |
1778 AHinterface.appendChild(title); | |
1779 } | |
1780 for (var j=0; j<AHObjInterface.options.length; j++) | |
1781 { | |
1782 var CIObj = AHObjInterface.options[j]; | |
1783 var CINode = root.createElement(CIObj.type); | |
1784 if (CIObj.type == "check") {CINode.setAttribute("name",CIObj.check);} | |
1785 else {CINode.setAttribute("name",CIObj.name);} | |
1786 AHinterface.appendChild(CINode); | |
1787 } | |
1788 if (AHObjInterface.scale != undefined) | |
1789 { | |
1790 for (var j=0; j<AHObjInterface.scale.length; j++) | |
1791 { | |
1792 var CIObj = AHObjInterface.scale[j]; | |
1793 var CINode = root.createElement("scale"); | |
1794 CINode.setAttribute("position",CIObj[0]); | |
1795 CINode.textContent = CIObj[1]; | |
1796 AHinterface.appendChild(CINode); | |
1797 } | |
1798 } | |
1799 AHNode.appendChild(AHinterface); | |
1800 } | |
1801 | |
1802 // Create <audioElements> | |
1803 for (var aeIndex = 0; aeIndex < AHObj.audioElements.length; aeIndex++) | |
1804 { | |
1805 var AEObj = AHObj.audioElements[aeIndex]; | |
1806 var AENode = root.createElement("audioElements"); | |
1807 AENode.id = AEObj.id; | |
1808 AENode.setAttribute("url",AEObj.url); | |
1809 AENode.setAttribute("type",AEObj.type); | |
1810 if (AEObj.marker != undefined && AEObj.enforce) | |
1811 { | |
1812 AENode.setAttribute("marker",AEObj.marker*100); | |
1813 } | |
1814 AHNode.appendChild(AENode); | |
1815 } | |
1816 | |
1817 // Create <CommentQuestion> | |
1818 for (var i=0; i<AHObj.commentQuestions.length; i++) | |
1819 { | |
1820 AHNode.appendChild(AHObj.commentQuestions[i].exportXML(root)); | |
1821 } | |
1822 | |
1823 // Create <PreTest> | |
1824 var AHPreTest = document.createElement("PreTest"); | |
1825 for (var i=0; i<AHObj.preTest.options.length; i++) | |
1826 { | |
1827 AHPreTest.appendChild(AHObj.preTest.options.exportXML(root)); | |
1828 } | |
1829 | |
1830 var AHPostTest = document.createElement("PostTest"); | |
1831 for (var i=0; i<AHObj.preTest.options.length; i++) | |
1832 { | |
1833 AHPostTest.appendChild(AHObj.postTest.options.exportXML(root)); | |
1834 } | |
1835 AHNode.appendChild(AHPreTest); | |
1836 AHNode.appendChild(AHPostTest); | |
1837 root.getElementsByTagName("BrowserEvalProjectDocument")[0].appendChild(AHNode); | |
1838 } | 1834 } |
1839 return root; | 1835 return root; |
1840 }; | 1836 }; |
1841 | 1837 |
1842 this.prepostNode = function(type) { | 1838 this.prepostNode = function(type) { |
1845 | 1841 |
1846 this.OptionNode = function() { | 1842 this.OptionNode = function() { |
1847 | 1843 |
1848 this.childOption = function() { | 1844 this.childOption = function() { |
1849 this.type = 'option'; | 1845 this.type = 'option'; |
1850 this.id = element.id; | 1846 this.id = null; |
1851 this.name = element.getAttribute('name'); | 1847 this.name = undefined; |
1852 this.text = element.textContent; | 1848 this.text = null; |
1853 }; | 1849 }; |
1854 | 1850 |
1855 this.type = undefined; | 1851 this.type = undefined; |
1856 this.id = undefined; | 1852 this.id = undefined; |
1857 this.mandatory = undefined; | 1853 this.mandatory = undefined; |
1861 this.options = []; | 1857 this.options = []; |
1862 this.min = undefined; | 1858 this.min = undefined; |
1863 this.max = undefined; | 1859 this.max = undefined; |
1864 this.step = undefined; | 1860 this.step = undefined; |
1865 | 1861 |
1862 this.decode = function(child) | |
1863 { | |
1864 this.type = child.nodeName; | |
1865 if (child.nodeName == "question") { | |
1866 this.id = child.id; | |
1867 this.mandatory; | |
1868 if (child.getAttribute('mandatory') == "true") {this.mandatory = true;} | |
1869 else {this.mandatory = false;} | |
1870 this.question = child.textContent; | |
1871 if (child.getAttribute('boxsize') == null) { | |
1872 this.boxsize = 'normal'; | |
1873 } else { | |
1874 this.boxsize = child.getAttribute('boxsize'); | |
1875 } | |
1876 } else if (child.nodeName == "statement") { | |
1877 this.statement = child.textContent; | |
1878 } else if (child.nodeName == "checkbox" || child.nodeName == "radio") { | |
1879 var element = child.firstElementChild; | |
1880 this.id = child.id; | |
1881 if (element == null) { | |
1882 console.log('Malformed' +child.nodeName+ 'entry'); | |
1883 this.statement = 'Malformed' +child.nodeName+ 'entry'; | |
1884 this.type = 'statement'; | |
1885 } else { | |
1886 this.options = []; | |
1887 while (element != null) { | |
1888 if (element.nodeName == 'statement' && this.statement == undefined){ | |
1889 this.statement = element.textContent; | |
1890 } else if (element.nodeName == 'option') { | |
1891 var node = new this.childOption(); | |
1892 node.id = element.id; | |
1893 node.name = element.getAttribute('name'); | |
1894 node.text = element.textContent; | |
1895 this.options.push(node); | |
1896 } | |
1897 element = element.nextElementSibling; | |
1898 } | |
1899 } | |
1900 } else if (child.nodeName == "number") { | |
1901 this.statement = child.textContent; | |
1902 this.id = child.id; | |
1903 this.min = child.getAttribute('min'); | |
1904 this.max = child.getAttribute('max'); | |
1905 this.step = child.getAttribute('step'); | |
1906 } | |
1907 }; | |
1908 | |
1866 this.exportXML = function(root) | 1909 this.exportXML = function(root) |
1867 { | 1910 { |
1868 var node = root.createElement(this.type); | 1911 var node = root.createElement(this.type); |
1869 switch(this.type) | 1912 switch(this.type) |
1870 { | 1913 { |
1878 node.textContent = this.question; | 1921 node.textContent = this.question; |
1879 break; | 1922 break; |
1880 case "number": | 1923 case "number": |
1881 node.id = this.id; | 1924 node.id = this.id; |
1882 node.setAttribute("mandatory",this.mandatory); | 1925 node.setAttribute("mandatory",this.mandatory); |
1883 node.setAttribute("min"), this.min; | 1926 node.setAttribute("min", this.min); |
1884 node.setAttribute("max"), this.max; | 1927 node.setAttribute("max", this.max); |
1885 node.setAttribute("step"), this.step; | 1928 node.setAttribute("step", this.step); |
1929 node.textContent = this.statement; | |
1886 break; | 1930 break; |
1887 case "checkbox": | 1931 case "checkbox": |
1888 node.id = this.id; | 1932 node.id = this.id; |
1889 var statement = document.createElement("statement"); | 1933 var statement = root.createElement("statement"); |
1890 statement.textContent = this.statement; | 1934 statement.textContent = this.statement; |
1891 node.appendChild(statement); | 1935 node.appendChild(statement); |
1892 for (var i=0; i<this.options.length; i++) | 1936 for (var i=0; i<this.options.length; i++) |
1893 { | 1937 { |
1894 var option = this.option[i]; | 1938 var option = this.options[i]; |
1895 var optionNode = document.createElement("option"); | 1939 var optionNode = root.createElement("option"); |
1896 optionNode.id = option.id; | 1940 optionNode.id = option.id; |
1897 optionNode.textContent = option.text; | 1941 optionNode.textContent = option.text; |
1898 node.appendChild(option); | 1942 node.appendChild(optionNode); |
1899 } | 1943 } |
1900 break; | 1944 break; |
1901 case "radio": | 1945 case "radio": |
1902 node.id = this.id; | 1946 node.id = this.id; |
1903 var statement = document.createElement("statement"); | 1947 var statement = root.createElement("statement"); |
1904 statement.textContent = this.statement; | 1948 statement.textContent = this.statement; |
1905 node.appendChild(statement); | 1949 node.appendChild(statement); |
1906 for (var i=0; i<this.options.length; i++) | 1950 for (var i=0; i<this.options.length; i++) |
1907 { | 1951 { |
1908 var option = this.option[i]; | 1952 var option = this.options[i]; |
1909 var optionNode = document.createElement("option"); | 1953 var optionNode = root.createElement("option"); |
1910 optionNode.setAttribute("name") = option.name; | 1954 optionNode.setAttribute("name",option.name); |
1911 optionNode.textContent = option.text; | 1955 optionNode.textContent = option.text; |
1912 node.appendChild(option); | 1956 node.appendChild(optionNode); |
1913 } | 1957 } |
1914 break; | 1958 break; |
1915 } | 1959 } |
1916 return node; | 1960 return node; |
1917 }; | 1961 }; |
1918 }; | 1962 }; |
1963 this.construct = function(Collection) | |
1964 { | |
1965 if (Collection.childElementCount != 0) { | |
1966 var child = Collection.firstElementChild; | |
1967 var node = new this.OptionNode(); | |
1968 node.decode(child); | |
1969 this.options.push(node); | |
1970 while (child.nextElementSibling != null) { | |
1971 child = child.nextElementSibling; | |
1972 node = new this.OptionNode(); | |
1973 node.decode(child); | |
1974 this.options.push(node); | |
1975 } | |
1976 } | |
1977 }; | |
1919 }; | 1978 }; |
1979 this.preTest = new this.prepostNode("pretest"); | |
1980 this.postTest = new this.prepostNode("posttest"); | |
1920 | 1981 |
1921 this.metricNode = function(name) { | 1982 this.metricNode = function(name) { |
1922 this.enabled = name; | 1983 this.enabled = name; |
1923 }; | 1984 }; |
1924 | 1985 |
1929 this.hostURL = undefined; | 1990 this.hostURL = undefined; |
1930 this.sampleRate = undefined; | 1991 this.sampleRate = undefined; |
1931 this.randomiseOrder = undefined; | 1992 this.randomiseOrder = undefined; |
1932 this.loop = undefined; | 1993 this.loop = undefined; |
1933 this.elementComments = undefined; | 1994 this.elementComments = undefined; |
1934 this.preTest = new parent.prepostNode('pretest'); | 1995 this.outsideReference = null; |
1935 this.postTest = new parent.prepostNode('posttest'); | 1996 this.preTest = new parent.prepostNode("pretest"); |
1997 this.postTest = new parent.prepostNode("pretest"); | |
1936 this.interfaces = []; | 1998 this.interfaces = []; |
1937 this.commentBoxPrefix = "Comment on track"; | 1999 this.commentBoxPrefix = "Comment on track"; |
1938 this.audioElements = []; | 2000 this.audioElements = []; |
1939 this.commentQuestions = []; | 2001 this.commentQuestions = []; |
1940 | 2002 |
1941 this.interfaceNode = function(DOM) { | 2003 this.decode = function(parent,xml) |
1942 var title = DOM.getElementsByTagName('title'); | 2004 { |
1943 if (title.length == 0) {this.title = null;} | 2005 this.presentedId = parent.audioHolders.length; |
1944 else {this.title = title[0].textContent;} | 2006 this.id = xml.id; |
1945 this.options = parent.commonInterface.options; | 2007 this.hostURL = xml.getAttribute('hostURL'); |
1946 var scale = DOM.getElementsByTagName('scale'); | 2008 this.sampleRate = xml.getAttribute('sampleRate'); |
1947 this.scale = []; | 2009 if (xml.getAttribute('randomiseOrder') == "true") {this.randomiseOrder = true;} |
1948 for (var i=0; i<scale.length; i++) { | 2010 else {this.randomiseOrder = false;} |
1949 var arr = [null, null]; | 2011 this.repeatCount = xml.getAttribute('repeatCount'); |
1950 arr[0] = scale[i].getAttribute('position'); | 2012 if (xml.getAttribute('loop') == 'true') {this.loop = true;} |
1951 arr[1] = scale[i].textContent; | 2013 else {this.loop == false;} |
1952 this.scale.push(arr); | 2014 if (xml.getAttribute('elementComments') == "true") {this.elementComments = true;} |
2015 else {this.elementComments = false;} | |
2016 | |
2017 var setupPreTestNode = xml.getElementsByTagName('PreTest'); | |
2018 if (setupPreTestNode.length != 0) | |
2019 { | |
2020 setupPreTestNode = setupPreTestNode[0]; | |
2021 this.preTest.construct(setupPreTestNode); | |
2022 } | |
2023 | |
2024 var setupPostTestNode = xml.getElementsByTagName('PostTest'); | |
2025 if (setupPostTestNode.length != 0) | |
2026 { | |
2027 setupPostTestNode = setupPostTestNode[0]; | |
2028 this.postTest.construct(setupPostTestNode); | |
2029 } | |
2030 | |
2031 var interfaceDOM = xml.getElementsByTagName('interface'); | |
2032 for (var i=0; i<interfaceDOM.length; i++) { | |
2033 var node = new this.interfaceNode(); | |
2034 node.decode(interfaceDOM[i]); | |
2035 this.interfaces.push(node); | |
2036 } | |
2037 this.commentBoxPrefix = xml.getElementsByTagName('commentBoxPrefix'); | |
2038 if (this.commentBoxPrefix.length != 0) { | |
2039 this.commentBoxPrefix = this.commentBoxPrefix[0].textContent; | |
2040 } else { | |
2041 this.commentBoxPrefix = "Comment on track"; | |
2042 } | |
2043 var audioElementsDOM = xml.getElementsByTagName('audioElements'); | |
2044 for (var i=0; i<audioElementsDOM.length; i++) { | |
2045 var node = new this.audioElementNode(); | |
2046 node.decode(this,audioElementsDOM[i]); | |
2047 if (audioElementsDOM[i].getAttribute('type') == 'outsidereference') { | |
2048 if (this.outsideReference == null) { | |
2049 this.outsideReference = node; | |
2050 } else { | |
2051 console.log('Error only one audioelement can be of type outsidereference per audioholder'); | |
2052 this.audioElements.push(node); | |
2053 console.log('Element id '+audioElementsDOM[i].id+' made into normal node'); | |
2054 } | |
2055 } else { | |
2056 this.audioElements.push(node); | |
2057 } | |
2058 } | |
2059 | |
2060 if (this.randomiseOrder == true && typeof randomiseOrder === "function") | |
2061 { | |
2062 this.audioElements = randomiseOrder(this.audioElements); | |
2063 } | |
2064 | |
2065 var commentQuestionsDOM = xml.getElementsByTagName('CommentQuestion'); | |
2066 for (var i=0; i<commentQuestionsDOM.length; i++) { | |
2067 var node = new this.commentQuestionNode(); | |
2068 node.decode(commentQuestionsDOM[i]); | |
2069 this.commentQuestions.push(node); | |
1953 } | 2070 } |
1954 }; | 2071 }; |
1955 | 2072 |
1956 this.audioElementNode = function(parent,audioObject) { | 2073 this.encode = function(root) |
1957 this.url = audioObject.file.name; | 2074 { |
1958 this.id = audioObject.id; | 2075 var AHNode = root.createElement("audioHolder"); |
1959 this.parent = parent; | 2076 AHNode.id = this.id; |
2077 AHNode.setAttribute("hostURL",this.hostURL); | |
2078 AHNode.setAttribute("sampleRate",this.sampleRate); | |
2079 AHNode.setAttribute("randomiseOrder",this.randomiseOrder); | |
2080 AHNode.setAttribute("repeatCount",this.repeatCount); | |
2081 AHNode.setAttribute("loop",this.loop); | |
2082 AHNode.setAttribute("elementComments",this.elementComments); | |
2083 | |
2084 for (var i=0; i<this.interfaces.length; i++) | |
2085 { | |
2086 AHNode.appendChild(this.interfaces[i].encode(root)); | |
2087 } | |
2088 | |
2089 for (var i=0; i<this.audioElements.length; i++) { | |
2090 AHNode.appendChild(this.audioElements[i].encode(root)); | |
2091 } | |
2092 // Create <CommentQuestion> | |
2093 for (var i=0; i<this.commentQuestions.length; i++) | |
2094 { | |
2095 AHNode.appendChild(this.commentQuestions[i].exportXML(root)); | |
2096 } | |
2097 | |
2098 // Create <PreTest> | |
2099 var AHPreTest = root.createElement("PreTest"); | |
2100 for (var i=0; i<this.preTest.options.length; i++) | |
2101 { | |
2102 AHPreTest.appendChild(this.preTest.options[i].exportXML(root)); | |
2103 } | |
2104 | |
2105 var AHPostTest = root.createElement("PostTest"); | |
2106 for (var i=0; i<this.postTest.options.length; i++) | |
2107 { | |
2108 AHPostTest.appendChild(this.postTest.options[i].exportXML(root)); | |
2109 } | |
2110 AHNode.appendChild(AHPreTest); | |
2111 AHNode.appendChild(AHPostTest); | |
2112 return AHNode; | |
2113 }; | |
2114 | |
2115 this.interfaceNode = function() { | |
2116 this.title = undefined; | |
2117 this.options = []; | |
2118 this.scale = []; | |
2119 this.name = undefined; | |
2120 this.decode = function(DOM) | |
2121 { | |
2122 var title = DOM.getElementsByTagName('title'); | |
2123 if (title.length == 0) {this.title = null;} | |
2124 else {this.title = title[0].textContent;} | |
2125 var name = DOM.getAttribute("name"); | |
2126 if (name != undefined) {this.name = name;} | |
2127 this.options = parent.commonInterface.options; | |
2128 var scale = DOM.getElementsByTagName('scale'); | |
2129 this.scale = []; | |
2130 for (var i=0; i<scale.length; i++) { | |
2131 var arr = [null, null]; | |
2132 arr[0] = scale[i].getAttribute('position'); | |
2133 arr[1] = scale[i].textContent; | |
2134 this.scale.push(arr); | |
2135 } | |
2136 }; | |
2137 this.encode = function(root) | |
2138 { | |
2139 var node = root.createElement("interface"); | |
2140 if (this.title != undefined) | |
2141 { | |
2142 var title = root.createElement("title"); | |
2143 title.textContent = this.title; | |
2144 node.appendChild(title); | |
2145 } | |
2146 for (var i=0; i<this.options.length; i++) | |
2147 { | |
2148 var optionNode = root.createElement(this.options[i].type); | |
2149 if (this.options[i].type == "option") | |
2150 { | |
2151 optionNode.setAttribute("name",this.options[i].name); | |
2152 } else if (this.options[i].type == "check") { | |
2153 optionNode.setAttribute("check",this.options[i].check); | |
2154 } else if (this.options[i].type == "scalerange") { | |
2155 optionNode.setAttribute("min",this.options[i].min*100); | |
2156 optionNode.setAttribute("max",this.options[i].max*100); | |
2157 } | |
2158 node.appendChild(optionNode); | |
2159 } | |
2160 for (var i=0; i<this.scale.length; i++) { | |
2161 var scale = root.createElement("scale"); | |
2162 scale.setAttribute("position",this.scale[i][0]); | |
2163 scale.textContent = this.scale[i][1]; | |
2164 node.appendChild(scale); | |
2165 } | |
2166 return node; | |
2167 }; | |
2168 }; | |
2169 | |
2170 this.audioElementNode = function() { | |
2171 this.url = null; | |
2172 this.id = null; | |
2173 this.parent = null; | |
1960 this.type = "normal"; | 2174 this.type = "normal"; |
1961 | 2175 this.marker = false; |
1962 this.marker = undefined; | 2176 this.enforce = false; |
2177 this.gain = 1.0; | |
2178 this.decode = function(parent,xml) | |
2179 { | |
2180 this.url = xml.getAttribute('url'); | |
2181 this.id = xml.id; | |
2182 this.parent = parent; | |
2183 this.type = xml.getAttribute('type'); | |
2184 var gain = xml.getAttribute('gain'); | |
2185 if (isNaN(gain) == false && gain != null) | |
2186 { | |
2187 this.gain = decibelToLinear(Number(gain)); | |
2188 } | |
2189 if (this.type == null) {this.type = "normal";} | |
2190 if (this.type == 'anchor') {this.anchor = true;} | |
2191 else {this.anchor = false;} | |
2192 if (this.type == 'reference') {this.reference = true;} | |
2193 else {this.reference = false;} | |
2194 if (this.anchor == true || this.reference == true) | |
2195 { | |
2196 this.marker = xml.getAttribute('marker'); | |
2197 if (this.marker != undefined) | |
2198 { | |
2199 this.marker = Number(this.marker); | |
2200 if (isNaN(this.marker) == false) | |
2201 { | |
2202 if (this.marker > 1) | |
2203 { this.marker /= 100.0;} | |
2204 if (this.marker >= 0 && this.marker <= 1) | |
2205 { | |
2206 this.enforce = true; | |
2207 return; | |
2208 } else { | |
2209 console.log("ERROR - Marker of audioElement "+this.id+" is not between 0 and 1 (float) or 0 and 100 (integer)!"); | |
2210 console.log("ERROR - Marker not enforced!"); | |
2211 } | |
2212 } else { | |
2213 console.log("ERROR - Marker of audioElement "+this.id+" is not a number!"); | |
2214 console.log("ERROR - Marker not enforced!"); | |
2215 } | |
2216 } | |
2217 } | |
2218 }; | |
2219 this.encode = function(root) | |
2220 { | |
2221 var AENode = root.createElement("audioElements"); | |
2222 AENode.id = this.id; | |
2223 AENode.setAttribute("url",this.url); | |
2224 AENode.setAttribute("type",this.type); | |
2225 AENode.setAttribute("gain",linearToDecibel(this.gain)); | |
2226 if (this.marker != false) | |
2227 { | |
2228 AENode.setAttribute("marker",this.marker*100); | |
2229 } | |
2230 return AENode; | |
2231 }; | |
1963 }; | 2232 }; |
1964 | 2233 |
1965 this.commentQuestionNode = function(xml) { | 2234 this.commentQuestionNode = function(xml) { |
2235 this.id = null; | |
2236 this.type = undefined; | |
2237 this.question = undefined; | |
2238 this.options = []; | |
2239 this.statement = undefined; | |
2240 | |
2241 this.childOption = function() { | |
2242 this.type = 'option'; | |
2243 this.name = null; | |
2244 this.text = null; | |
2245 }; | |
1966 this.exportXML = function(root) | 2246 this.exportXML = function(root) |
1967 { | 2247 { |
1968 var CQNode = root.createElement("CommentQuestion"); | 2248 var CQNode = root.createElement("CommentQuestion"); |
1969 CQNode.id = this.id; | 2249 CQNode.id = this.id; |
1970 CQNode.setAttribute("type",this.type); | 2250 CQNode.setAttribute("type",this.type); |
1971 switch(this.type) | 2251 switch(this.type) |
1972 { | 2252 { |
1973 case "text": | 2253 case "text": |
1974 CQNode.textContent = this.question; | 2254 CQNode.textContent = this.question; |
1975 break; | 2255 break; |
1976 case "radio" || "checkbox": | 2256 case "radio": |
1977 var statement = document.createElement("statement"); | 2257 var statement = root.createElement("statement"); |
1978 statement.textContent = this.statement; | 2258 statement.textContent = this.statement; |
1979 CQNode.appendChild(statement); | 2259 CQNode.appendChild(statement); |
1980 for (var i=0; i<this.options.length; i++) | 2260 for (var i=0; i<this.options.length; i++) |
1981 { | 2261 { |
1982 var optionNode = document.createElement("option"); | 2262 var optionNode = root.createElement("option"); |
1983 optionNode.setAttribute("name",this.options[i].name); | 2263 optionNode.setAttribute("name",this.options[i].name); |
1984 optionNode.textContent = this.options[i].text; | 2264 optionNode.textContent = this.options[i].text; |
1985 CQNode.appendChild(optionNode); | 2265 CQNode.appendChild(optionNode); |
1986 } | 2266 } |
1987 break; | 2267 break; |
2268 case "checkbox": | |
2269 var statement = root.createElement("statement"); | |
2270 statement.textContent = this.statement; | |
2271 CQNode.appendChild(statement); | |
2272 for (var i=0; i<this.options.length; i++) | |
2273 { | |
2274 var optionNode = root.createElement("option"); | |
2275 optionNode.setAttribute("name",this.options[i].name); | |
2276 optionNode.textContent = this.options[i].text; | |
2277 CQNode.appendChild(optionNode); | |
2278 } | |
2279 break; | |
1988 } | 2280 } |
1989 return CQNode; | 2281 return CQNode; |
1990 }; | 2282 }; |
1991 this.childOption = function(element) { | 2283 this.decode = function(xml) { |
1992 this.type = 'option'; | 2284 this.id = xml.id; |
1993 this.name = element.getAttribute('name'); | 2285 if (xml.getAttribute('mandatory') == 'true') {this.mandatory = true;} |
1994 this.text = element.textContent; | 2286 else {this.mandatory = false;} |
1995 }; | 2287 this.type = xml.getAttribute('type'); |
1996 this.id = xml.id; | 2288 if (this.type == undefined) {this.type = 'text';} |
1997 if (xml.getAttribute('mandatory') == 'true') {this.mandatory = true;} | 2289 switch (this.type) { |
1998 else {this.mandatory = false;} | 2290 case 'text': |
1999 this.type = xml.getAttribute('type'); | 2291 this.question = xml.textContent; |
2000 if (this.type == undefined) {this.type = 'text';} | 2292 break; |
2001 switch (this.type) { | 2293 case 'radio': |
2002 case 'text': | 2294 var child = xml.firstElementChild; |
2003 this.question = xml.textContent; | 2295 this.options = []; |
2004 break; | 2296 while (child != undefined) { |
2005 case 'radio': | 2297 if (child.nodeName == 'statement' && this.statement == undefined) { |
2006 var child = xml.firstElementChild; | 2298 this.statement = child.textContent; |
2007 this.options = []; | 2299 } else if (child.nodeName == 'option') { |
2008 while (child != undefined) { | 2300 var node = new this.childOption(); |
2009 if (child.nodeName == 'statement' && this.statement == undefined) { | 2301 node.name = child.getAttribute('name'); |
2010 this.statement = child.textContent; | 2302 node.text = child.textContent; |
2011 } else if (child.nodeName == 'option') { | 2303 this.options.push(node); |
2012 this.options.push(new this.childOption(child)); | 2304 } |
2305 child = child.nextElementSibling; | |
2013 } | 2306 } |
2014 child = child.nextElementSibling; | 2307 break; |
2015 } | 2308 case 'checkbox': |
2016 break; | 2309 var child = xml.firstElementChild; |
2017 case 'checkbox': | 2310 this.options = []; |
2018 var child = xml.firstElementChild; | 2311 while (child != undefined) { |
2019 this.options = []; | 2312 if (child.nodeName == 'statement' && this.statement == undefined) { |
2020 while (child != undefined) { | 2313 this.statement = child.textContent; |
2021 if (child.nodeName == 'statement' && this.statement == undefined) { | 2314 } else if (child.nodeName == 'option') { |
2022 this.statement = child.textContent; | 2315 var node = new this.childOption(); |
2023 } else if (child.nodeName == 'option') { | 2316 node.name = child.getAttribute('name'); |
2024 this.options.push(new this.childOption(child)); | 2317 node.text = child.textContent; |
2318 this.options.push(node); | |
2319 } | |
2320 child = child.nextElementSibling; | |
2025 } | 2321 } |
2026 child = child.nextElementSibling; | 2322 break; |
2027 } | 2323 } |
2028 break; | 2324 }; |
2029 } | |
2030 }; | 2325 }; |
2031 }; | 2326 }; |
2032 | |
2033 this.preTest = new this.prepostNode("pretest"); | |
2034 this.postTest = new this.prepostNode("posttest"); | |
2035 } | 2327 } |
2036 | 2328 |
2329 function linearToDecibel(gain) | |
2330 { | |
2331 return 20.0*Math.log10(gain); | |
2332 } | |
2333 | |
2334 function decibelToLinear(gain) | |
2335 { | |
2336 return Math.pow(10,gain/20.0); | |
2337 } | |
2338 | |
2037 function createDeleteNodeButton(node) | 2339 function createDeleteNodeButton(node) |
2038 { | 2340 { |
2039 var button = document.createElement("button"); | 2341 var button = document.createElement("button"); |
2040 button.textContent = "Delete"; | 2342 button.textContent = "Delete"; |
2041 button.onclick = function(event) | 2343 button.onclick = function(event) |
2044 node.parentElement.removeChild(node); | 2346 node.parentElement.removeChild(node); |
2045 }; | 2347 }; |
2046 return button; | 2348 return button; |
2047 } | 2349 } |
2048 | 2350 |
2049 function SpecficationToHTML() | 2351 function SpecificationToHTML() |
2050 { | 2352 { |
2051 // Take information from Specification Node and format it into an HTML layout | 2353 // Take information from Specification Node and format it into an HTML layout |
2052 var destination = document.getElementById("content"); | 2354 var destination = document.getElementById("content"); |
2053 // Setup Header Node | 2355 // Setup Header Node |
2054 var setupNode = document.createElement("div"); | 2356 var setupNode = document.createElement("div"); |
2477 audioElems.id = aHTML.id+"-audioElements"; | 2779 audioElems.id = aHTML.id+"-audioElements"; |
2478 audioElems.className = "SecondLevel"; | 2780 audioElems.className = "SecondLevel"; |
2479 var title = document.createElement("h3"); | 2781 var title = document.createElement("h3"); |
2480 title.textContent = "Audio Elements"; | 2782 title.textContent = "Audio Elements"; |
2481 audioElems.appendChild(title); | 2783 audioElems.appendChild(title); |
2482 for (var i=0; i<aH.audioElements.length; i++) | 2784 for (var j=0; j<aH.audioElements.length; j++) |
2483 { | 2785 { |
2484 var entry = document.createElement("div"); | 2786 var entry = document.createElement("div"); |
2485 entry.className = "SecondLevel"; | 2787 entry.className = "SecondLevel"; |
2486 entry.id = audioElems.id+"-"+aH.audioElements[i].id; | 2788 entry.id = audioElems.id+"-"+aH.audioElements[j].id; |
2487 var text = document.createElement("span"); | 2789 var text = document.createElement("span"); |
2488 text.textContent = "ID:"; | 2790 text.textContent = "ID:"; |
2489 var input = document.createElement("input"); | 2791 var input = document.createElement("input"); |
2490 input.id = entry.id+"-id"; | 2792 input.id = entry.id+"-id"; |
2491 input.value = aH.audioElements[i].id; | 2793 input.value = aH.audioElements[j].id; |
2492 input.onchange = function() { | 2794 input.onchange = function() { |
2493 var IDSplit = event.currentTarget.id.split("-"); | 2795 var IDSplit = event.currentTarget.id.split("-"); |
2494 var ahNode = specificationNode.audioHolders[IDSplit[1]]; | 2796 var ahNode = specificationNode.audioHolders[IDSplit[1]]; |
2495 ahNode.audioElements[IDSplit[3]].id = event.currentTarget.value; | 2797 ahNode.audioElements[IDSplit[3]].id = event.currentTarget.value; |
2496 }; | 2798 }; |
2500 entry.appendChild(input); | 2802 entry.appendChild(input); |
2501 text = document.createElement("span"); | 2803 text = document.createElement("span"); |
2502 text.textContent = "URL:"; | 2804 text.textContent = "URL:"; |
2503 input = document.createElement("input"); | 2805 input = document.createElement("input"); |
2504 input.id = entry.id+"-URL"; | 2806 input.id = entry.id+"-URL"; |
2505 input.value = aH.audioElements[i].url; | 2807 input.value = aH.audioElements[j].url; |
2506 input.onchange = function() { | 2808 input.onchange = function() { |
2507 var IDSplit = event.currentTarget.id.split("-"); | 2809 var IDSplit = event.currentTarget.id.split("-"); |
2508 var ahNode = specificationNode.audioHolders[IDSplit[1]]; | 2810 var ahNode = specificationNode.audioHolders[IDSplit[1]]; |
2509 ahNode.audioElements[IDSplit[3]].url = event.currentTarget.value; | 2811 ahNode.audioElements[IDSplit[3]].url = event.currentTarget.value; |
2510 }; | 2812 }; |
2511 text.style.margin = "5px"; | 2813 text.style.margin = "5px"; |
2512 input.style.margin = "5px"; | 2814 input.style.margin = "5px"; |
2513 entry.appendChild(text); | 2815 entry.appendChild(text); |
2514 entry.appendChild(input); | 2816 entry.appendChild(input); |
2817 text = document.createElement("span"); | |
2818 text.textContent = "Gain:"; | |
2819 input = document.createElement("input"); | |
2820 input.type = "range"; | |
2821 input.id = entry.id+"-gain"; | |
2822 input.value = aH.audioElements[j].gain; | |
2823 input.min = -25; | |
2824 input.max = 6; | |
2825 input.step = 1; | |
2826 input.onchange = function() { | |
2827 var IDSplit = event.currentTarget.id.split("-"); | |
2828 var ahNode = specificationNode.audioHolders[IDSplit[1]]; | |
2829 ahNode.audioElements[IDSplit[3]].gain = decibelToLinear(Number(event.currentTarget.value)); | |
2830 var textRet = document.getElementById(event.currentTarget.id+"-ret"); | |
2831 textRet.textContent = String(event.currentTarget.value)+"dB"; | |
2832 }; | |
2833 var textRet = document.createElement("span"); | |
2834 textRet.textContent = String(linearToDecibel(aH.audioElements[j].gain))+"dB"; | |
2835 textRet.id = entry.id+"-gain-ret"; | |
2836 text.style.margin = "5px"; | |
2837 input.style.margin = "5px"; | |
2838 entry.appendChild(text); | |
2839 entry.appendChild(input); | |
2840 entry.appendChild(textRet); | |
2515 var button_delete = document.createElement("button"); | 2841 var button_delete = document.createElement("button"); |
2516 button_delete.textContent = "Delete"; | 2842 button_delete.textContent = "Delete"; |
2517 button_delete.onclick = function() { | 2843 button_delete.onclick = function() { |
2518 var node = event.currentTarget.parentElement; | 2844 var node = event.currentTarget.parentElement; |
2519 var IDSplit = node.id.split("-"); | 2845 var IDSplit = node.id.split("-"); |