comparison test_create/test_create.html @ 372:5ec4279bf846 Dev_main

test_create: Specification Node handles complete XML to DOM and DOM to XML conversions
author Nicholas Jillings <n.g.r.jillings@se14.qmul.ac.uk>
date Fri, 04 Dec 2015 18:34:04 +0000
parents fe049caed3ae
children 5ca2b999be88
comparison
equal deleted inserted replaced
369:fe049caed3ae 372:5ec4279bf846
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
1590 this.collectMetrics = null; 1622 this.collectMetrics = null;
1591 this.testPages = null; 1623 this.testPages = null;
1592 this.audioHolders = []; 1624 this.audioHolders = [];
1593 this.metrics = []; 1625 this.metrics = [];
1594 1626
1595 this.decode = function() { 1627 this.decode = function(projectXML) {
1596 // projectXML - DOM Parsed document 1628 // projectXML - DOM Parsed document
1597 this.projectXML = projectXML.childNodes[0]; 1629 this.projectXML = projectXML.childNodes[0];
1598 var setupNode = projectXML.getElementsByTagName('setup')[0]; 1630 var setupNode = projectXML.getElementsByTagName('setup')[0];
1599 this.interfaceType = setupNode.getAttribute('interface'); 1631 this.interfaceType = setupNode.getAttribute('interface');
1600 this.projectReturn = setupNode.getAttribute('projectReturn'); 1632 this.projectReturn = setupNode.getAttribute('projectReturn');
1612 this.testPages = Number(this.testPages); 1644 this.testPages = Number(this.testPages);
1613 if (this.testPages == 0) {this.testPages = null;} 1645 if (this.testPages == 0) {this.testPages = null;}
1614 } 1646 }
1615 var metricCollection = setupNode.getElementsByTagName('Metric'); 1647 var metricCollection = setupNode.getElementsByTagName('Metric');
1616 1648
1617 this.preTest = new this.prepostNode('pretest',setupNode.getElementsByTagName('PreTest')); 1649 var setupPreTestNode = setupNode.getElementsByTagName('PreTest');
1618 this.postTest = new this.prepostNode('posttest',setupNode.getElementsByTagName('PostTest')); 1650 if (setupPreTestNode.length != 0)
1651 {
1652 setupPreTestNode = setupPreTestNode[0];
1653 this.preTest.construct(setupPreTestNode);
1654 }
1655
1656 var setupPostTestNode = setupNode.getElementsByTagName('PostTest');
1657 if (setupPostTestNode.length != 0)
1658 {
1659 setupPostTestNode = setupPostTestNode[0];
1660 this.postTest.construct(setupPostTestNode);
1661 }
1619 1662
1620 if (metricCollection.length > 0) { 1663 if (metricCollection.length > 0) {
1621 metricCollection = metricCollection[0].getElementsByTagName('metricEnable'); 1664 metricCollection = metricCollection[0].getElementsByTagName('metricEnable');
1622 for (var i=0; i<metricCollection.length; i++) { 1665 for (var i=0; i<metricCollection.length; i++) {
1623 this.metrics.push(new this.metricNode(metricCollection[i].textContent)); 1666 this.metrics.push(new this.metricNode(metricCollection[i].textContent));
1673 } 1716 }
1674 }; 1717 };
1675 1718
1676 var audioHolders = projectXML.getElementsByTagName('audioHolder'); 1719 var audioHolders = projectXML.getElementsByTagName('audioHolder');
1677 for (var i=0; i<audioHolders.length; i++) { 1720 for (var i=0; i<audioHolders.length; i++) {
1678 this.audioHolders.push(new this.audioHolderNode(this,audioHolders[i])); 1721 var node = new this.audioHolderNode(this);
1722 node.decode(this,audioHolders[i]);
1723 this.audioHolders.push(node);
1679 } 1724 }
1680 1725
1681 // New check if we need to randomise the test order 1726 // New check if we need to randomise the test order
1682 if (this.randomiseOrder) 1727 if (this.randomiseOrder)
1683 { 1728 {
1716 setupNode.setAttribute('testPages',this.testPages); 1761 setupNode.setAttribute('testPages',this.testPages);
1717 1762
1718 var setupPreTest = root.createElement("PreTest"); 1763 var setupPreTest = root.createElement("PreTest");
1719 for (var i=0; i<this.preTest.options.length; i++) 1764 for (var i=0; i<this.preTest.options.length; i++)
1720 { 1765 {
1721 setupPreTest.appendChild(this.preTest.options.exportXML(root)); 1766 setupPreTest.appendChild(this.preTest.options[i].exportXML(root));
1722 } 1767 }
1723 1768
1724 var setupPostTest = root.createElement("PostTest"); 1769 var setupPostTest = root.createElement("PostTest");
1725 for (var i=0; i<this.preTest.options.length; i++) 1770 for (var i=0; i<this.postTest.options.length; i++)
1726 { 1771 {
1727 setupPostTest.appendChild(this.postTest.options.exportXML(root)); 1772 setupPostTest.appendChild(this.postTest.options[i].exportXML(root));
1728 } 1773 }
1729 1774
1730 setupNode.appendChild(setupPreTest); 1775 setupNode.appendChild(setupPreTest);
1731 setupNode.appendChild(setupPostTest); 1776 setupNode.appendChild(setupPostTest);
1732 1777
1733 // <Metric> tag 1778 // <Metric> tag
1734 var Metric = root.createElement("Metric"); 1779 var Metric = root.createElement("Metric");
1735 for (var i=0; i<this.metrics.length; i++) 1780 for (var i=0; i<this.metrics.length; i++)
1736 { 1781 {
1737 var metricEnable = document.createElement("metricEnable"); 1782 var metricEnable = root.createElement("metricEnable");
1738 metricEnable.textContent = this.metrics[i].enabled; 1783 metricEnable.textContent = this.metrics[i].enabled;
1739 Metric.appendChild(metricEnable); 1784 Metric.appendChild(metricEnable);
1740 } 1785 }
1741 setupNode.appendChild(Metric); 1786 setupNode.appendChild(Metric);
1742 1787
1743 // <interface> tag 1788 // <interface> tag
1744 var CommonInterface = root.createElement("interface"); 1789 var CommonInterface = root.createElement("interface");
1745 for (var i=0; i<this.commonInterface.options.length; i++) 1790 for (var i=0; i<this.commonInterface.options.length; i++)
1746 { 1791 {
1747 var CIObj = this.commonInterface.options[i]; 1792 var CIObj = this.commonInterface.options[i];
1748 var CINode = document.createElement(CIObj.type); 1793 var CINode = root.createElement(CIObj.type);
1749 if (CIObj.type == "check") {CINode.setAttribute("name",CIObj.check);} 1794 if (CIObj.type == "check") {CINode.setAttribute("name",CIObj.check);}
1750 else {CINode.setAttribute("name",CIObj.name);} 1795 else {CINode.setAttribute("name",CIObj.name);}
1751 CommonInterface.appendChild(CINode); 1796 CommonInterface.appendChild(CINode);
1752 } 1797 }
1753 setupNode.appendChild(CommonInterface); 1798 setupNode.appendChild(CommonInterface);
1754 1799
1755 root.getElementsByTagName("BrowserEvalProjectDocument")[0].appendChild(setupNode); 1800 root.getElementsByTagName("BrowserEvalProjectDocument")[0].appendChild(setupNode);
1756 // Time for the <audioHolder> tags 1801 // Time for the <audioHolder> tags
1757 for (var ahIndex = 0; ahIndex < this.audioHolders.length; ahIndex++) 1802 for (var ahIndex = 0; ahIndex < this.audioHolders.length; ahIndex++)
1758 { 1803 {
1759 var AHObj = this.audioHolders[ahIndex]; 1804 var node = this.audioHolders[ahIndex].encode(root);
1760 var AHNode = root.createElement("audioHolder"); 1805 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 } 1806 }
1839 return root; 1807 return root;
1840 }; 1808 };
1841 1809
1842 this.prepostNode = function(type) { 1810 this.prepostNode = function(type) {
1845 1813
1846 this.OptionNode = function() { 1814 this.OptionNode = function() {
1847 1815
1848 this.childOption = function() { 1816 this.childOption = function() {
1849 this.type = 'option'; 1817 this.type = 'option';
1850 this.id = element.id; 1818 this.id = null;
1851 this.name = element.getAttribute('name'); 1819 this.name = undefined;
1852 this.text = element.textContent; 1820 this.text = null;
1853 }; 1821 };
1854 1822
1855 this.type = undefined; 1823 this.type = undefined;
1856 this.id = undefined; 1824 this.id = undefined;
1857 this.mandatory = undefined; 1825 this.mandatory = undefined;
1861 this.options = []; 1829 this.options = [];
1862 this.min = undefined; 1830 this.min = undefined;
1863 this.max = undefined; 1831 this.max = undefined;
1864 this.step = undefined; 1832 this.step = undefined;
1865 1833
1834 this.decode = function(child)
1835 {
1836 this.type = child.nodeName;
1837 if (child.nodeName == "question") {
1838 this.id = child.id;
1839 this.mandatory;
1840 if (child.getAttribute('mandatory') == "true") {this.mandatory = true;}
1841 else {this.mandatory = false;}
1842 this.question = child.textContent;
1843 if (child.getAttribute('boxsize') == null) {
1844 this.boxsize = 'normal';
1845 } else {
1846 this.boxsize = child.getAttribute('boxsize');
1847 }
1848 } else if (child.nodeName == "statement") {
1849 this.statement = child.textContent;
1850 } else if (child.nodeName == "checkbox" || child.nodeName == "radio") {
1851 var element = child.firstElementChild;
1852 this.id = child.id;
1853 if (element == null) {
1854 console.log('Malformed' +child.nodeName+ 'entry');
1855 this.statement = 'Malformed' +child.nodeName+ 'entry';
1856 this.type = 'statement';
1857 } else {
1858 this.options = [];
1859 while (element != null) {
1860 if (element.nodeName == 'statement' && this.statement == undefined){
1861 this.statement = element.textContent;
1862 } else if (element.nodeName == 'option') {
1863 var node = new this.childOption();
1864 node.id = element.id;
1865 node.name = element.getAttribute('name');
1866 node.text = element.textContent;
1867 this.options.push(node);
1868 }
1869 element = element.nextElementSibling;
1870 }
1871 }
1872 } else if (child.nodeName == "number") {
1873 this.statement = child.textContent;
1874 this.id = child.id;
1875 this.min = child.getAttribute('min');
1876 this.max = child.getAttribute('max');
1877 this.step = child.getAttribute('step');
1878 }
1879 };
1880
1866 this.exportXML = function(root) 1881 this.exportXML = function(root)
1867 { 1882 {
1868 var node = root.createElement(this.type); 1883 var node = root.createElement(this.type);
1869 switch(this.type) 1884 switch(this.type)
1870 { 1885 {
1878 node.textContent = this.question; 1893 node.textContent = this.question;
1879 break; 1894 break;
1880 case "number": 1895 case "number":
1881 node.id = this.id; 1896 node.id = this.id;
1882 node.setAttribute("mandatory",this.mandatory); 1897 node.setAttribute("mandatory",this.mandatory);
1883 node.setAttribute("min"), this.min; 1898 node.setAttribute("min", this.min);
1884 node.setAttribute("max"), this.max; 1899 node.setAttribute("max", this.max);
1885 node.setAttribute("step"), this.step; 1900 node.setAttribute("step", this.step);
1886 break; 1901 break;
1887 case "checkbox": 1902 case "checkbox":
1888 node.id = this.id; 1903 node.id = this.id;
1889 var statement = document.createElement("statement"); 1904 var statement = root.createElement("statement");
1890 statement.textContent = this.statement; 1905 statement.textContent = this.statement;
1891 node.appendChild(statement); 1906 node.appendChild(statement);
1892 for (var i=0; i<this.options.length; i++) 1907 for (var i=0; i<this.options.length; i++)
1893 { 1908 {
1894 var option = this.option[i]; 1909 var option = this.options[i];
1895 var optionNode = document.createElement("option"); 1910 var optionNode = root.createElement("option");
1896 optionNode.id = option.id; 1911 optionNode.id = option.id;
1897 optionNode.textContent = option.text; 1912 optionNode.textContent = option.text;
1898 node.appendChild(option); 1913 node.appendChild(optionNode);
1899 } 1914 }
1900 break; 1915 break;
1901 case "radio": 1916 case "radio":
1902 node.id = this.id; 1917 node.id = this.id;
1903 var statement = document.createElement("statement"); 1918 var statement = root.createElement("statement");
1904 statement.textContent = this.statement; 1919 statement.textContent = this.statement;
1905 node.appendChild(statement); 1920 node.appendChild(statement);
1906 for (var i=0; i<this.options.length; i++) 1921 for (var i=0; i<this.options.length; i++)
1907 { 1922 {
1908 var option = this.option[i]; 1923 var option = this.options[i];
1909 var optionNode = document.createElement("option"); 1924 var optionNode = root.createElement("option");
1910 optionNode.setAttribute("name") = option.name; 1925 optionNode.setAttribute("name",option.name);
1911 optionNode.textContent = option.text; 1926 optionNode.textContent = option.text;
1912 node.appendChild(option); 1927 node.appendChild(optionNode);
1913 } 1928 }
1914 break; 1929 break;
1915 } 1930 }
1916 return node; 1931 return node;
1917 }; 1932 };
1918 }; 1933 };
1934 this.construct = function(Collection)
1935 {
1936 if (Collection.childElementCount != 0) {
1937 var child = Collection.firstElementChild;
1938 var node = new this.OptionNode();
1939 node.decode(child);
1940 this.options.push(node);
1941 while (child.nextElementSibling != null) {
1942 child = child.nextElementSibling;
1943 node = new this.OptionNode();
1944 node.decode(child);
1945 this.options.push(node);
1946 }
1947 }
1948 };
1919 }; 1949 };
1950 this.preTest = new this.prepostNode("pretest");
1951 this.postTest = new this.prepostNode("posttest");
1920 1952
1921 this.metricNode = function(name) { 1953 this.metricNode = function(name) {
1922 this.enabled = name; 1954 this.enabled = name;
1923 }; 1955 };
1924 1956
1929 this.hostURL = undefined; 1961 this.hostURL = undefined;
1930 this.sampleRate = undefined; 1962 this.sampleRate = undefined;
1931 this.randomiseOrder = undefined; 1963 this.randomiseOrder = undefined;
1932 this.loop = undefined; 1964 this.loop = undefined;
1933 this.elementComments = undefined; 1965 this.elementComments = undefined;
1934 this.preTest = new parent.prepostNode('pretest'); 1966 this.outsideReference = null;
1935 this.postTest = new parent.prepostNode('posttest'); 1967 this.preTest = new parent.prepostNode("pretest");
1968 this.postTest = new parent.prepostNode("pretest");
1936 this.interfaces = []; 1969 this.interfaces = [];
1937 this.commentBoxPrefix = "Comment on track"; 1970 this.commentBoxPrefix = "Comment on track";
1938 this.audioElements = []; 1971 this.audioElements = [];
1939 this.commentQuestions = []; 1972 this.commentQuestions = [];
1940 1973
1941 this.interfaceNode = function(DOM) { 1974 this.decode = function(parent,xml)
1942 var title = DOM.getElementsByTagName('title'); 1975 {
1943 if (title.length == 0) {this.title = null;} 1976 this.presentedId = parent.audioHolders.length;
1944 else {this.title = title[0].textContent;} 1977 this.id = xml.id;
1945 this.options = parent.commonInterface.options; 1978 this.hostURL = xml.getAttribute('hostURL');
1946 var scale = DOM.getElementsByTagName('scale'); 1979 this.sampleRate = xml.getAttribute('sampleRate');
1947 this.scale = []; 1980 if (xml.getAttribute('randomiseOrder') == "true") {this.randomiseOrder = true;}
1948 for (var i=0; i<scale.length; i++) { 1981 else {this.randomiseOrder = false;}
1949 var arr = [null, null]; 1982 this.repeatCount = xml.getAttribute('repeatCount');
1950 arr[0] = scale[i].getAttribute('position'); 1983 if (xml.getAttribute('loop') == 'true') {this.loop = true;}
1951 arr[1] = scale[i].textContent; 1984 else {this.loop == false;}
1952 this.scale.push(arr); 1985 if (xml.getAttribute('elementComments') == "true") {this.elementComments = true;}
1986 else {this.elementComments = false;}
1987
1988 var setupPreTestNode = xml.getElementsByTagName('PreTest');
1989 if (setupPreTestNode.length != 0)
1990 {
1991 setupPreTestNode = setupPreTestNode[0];
1992 this.preTest.construct(setupPreTestNode);
1993 }
1994
1995 var setupPostTestNode = xml.getElementsByTagName('PostTest');
1996 if (setupPostTestNode.length != 0)
1997 {
1998 setupPostTestNode = setupPostTestNode[0];
1999 this.postTest.construct(setupPostTestNode);
2000 }
2001
2002 var interfaceDOM = xml.getElementsByTagName('interface');
2003 for (var i=0; i<interfaceDOM.length; i++) {
2004 var node = new this.interfaceNode();
2005 node.decode(interfaceDOM[i]);
2006 this.interfaces.push(node);
2007 }
2008 this.commentBoxPrefix = xml.getElementsByTagName('commentBoxPrefix');
2009 if (this.commentBoxPrefix.length != 0) {
2010 this.commentBoxPrefix = this.commentBoxPrefix[0].textContent;
2011 } else {
2012 this.commentBoxPrefix = "Comment on track";
2013 }
2014 var audioElementsDOM = xml.getElementsByTagName('audioElements');
2015 for (var i=0; i<audioElementsDOM.length; i++) {
2016 var node = new this.audioElementNode();
2017 if (audioElementsDOM[i].getAttribute('type') == 'outsidereference') {
2018 if (this.outsideReference == null) {
2019 this.outsideReference = node.decode(this,audioElementsDOM[i]);
2020 } else {
2021 console.log('Error only one audioelement can be of type outsidereference per audioholder');
2022 node.decode(this,audioElementsDOM[i]);
2023 this.audioElements.push(node);
2024 console.log('Element id '+audioElementsDOM[i].id+' made into normal node');
2025 }
2026 } else {
2027 node.decode(this,audioElementsDOM[i]);
2028 this.audioElements.push(node);
2029 }
2030 }
2031
2032 var commentQuestionsDOM = xml.getElementsByTagName('CommentQuestion');
2033 for (var i=0; i<commentQuestionsDOM.length; i++) {
2034 var node = new this.commentQuestionNode();
2035 node.decode(commentQuestionsDOM[i]);
2036 this.commentQuestions.push(node);
1953 } 2037 }
1954 }; 2038 };
1955 2039
1956 this.audioElementNode = function(parent,audioObject) { 2040 this.encode = function(root)
1957 this.url = audioObject.file.name; 2041 {
1958 this.id = audioObject.id; 2042 var AHNode = root.createElement("audioHolder");
1959 this.parent = parent; 2043 AHNode.id = this.id;
2044 AHNode.setAttribute("hostURL",this.hostURL);
2045 AHNode.setAttribute("sampleRate",this.sampleRate);
2046 AHNode.setAttribute("randomiseOrder",this.randomiseOrder);
2047 AHNode.setAttribute("repeatCount",this.repeatCount);
2048 AHNode.setAttribute("loop",this.loop);
2049 AHNode.setAttribute("elementComments",this.elementComments);
2050
2051 for (var i=0; i<this.interfaces.length; i++)
2052 {
2053 AHNode.appendChild(this.interfaces[i].encode(root));
2054 }
2055
2056 for (var i=0; i<this.audioElements.length; i++) {
2057 AHNode.appendChild(this.audioElements[i].encode(root));
2058 }
2059 // Create <CommentQuestion>
2060 for (var i=0; i<this.commentQuestions.length; i++)
2061 {
2062 AHNode.appendChild(this.commentQuestions[i].exportXML(root));
2063 }
2064
2065 // Create <PreTest>
2066 var AHPreTest = root.createElement("PreTest");
2067 for (var i=0; i<this.preTest.options.length; i++)
2068 {
2069 AHPreTest.appendChild(this.preTest.options[i].exportXML(root));
2070 }
2071
2072 var AHPostTest = root.createElement("PostTest");
2073 for (var i=0; i<this.postTest.options.length; i++)
2074 {
2075 AHPostTest.appendChild(this.postTest.options[i].exportXML(root));
2076 }
2077 AHNode.appendChild(AHPreTest);
2078 AHNode.appendChild(AHPostTest);
2079 return AHNode;
2080 };
2081
2082 this.interfaceNode = function() {
2083 this.title = undefined;
2084 this.options = [];
2085 this.scale = [];
2086 this.decode = function(DOM)
2087 {
2088 var title = DOM.getElementsByTagName('title');
2089 if (title.length == 0) {this.title = null;}
2090 else {this.title = title[0].textContent;}
2091 this.options = parent.commonInterface.options;
2092 var scale = DOM.getElementsByTagName('scale');
2093 this.scale = [];
2094 for (var i=0; i<scale.length; i++) {
2095 var arr = [null, null];
2096 arr[0] = scale[i].getAttribute('position');
2097 arr[1] = scale[i].textContent;
2098 this.scale.push(arr);
2099 }
2100 };
2101 this.encode = function(root)
2102 {
2103 var node = root.createElement("interface");
2104 if (this.title != undefined)
2105 {
2106 var title = root.createElement("title");
2107 title.textContent = this.title;
2108 node.appendChild(title);
2109 }
2110 for (var i=0; i<this.options.length; i++)
2111 {
2112 var optionNode = root.createElement(this.options[i].type);
2113 if (this.options[i].type == "option")
2114 {
2115 optionNode.setAttribute("name",this.options[i].name);
2116 } else if (this.options[i].type == "check") {
2117 optionNode.setAttribute("check",this.options[i].check);
2118 } else if (this.options[i].type == "scalerange") {
2119 optionNode.setAttribute("min",this.options[i].min*100);
2120 optionNode.setAttribute("max",this.options[i].max*100);
2121 }
2122 node.appendChild(optionNode);
2123 }
2124 for (var i=0; i<this.scale.length; i++) {
2125 var scale = root.createElement("scale");
2126 scale.setAttribute("position",this.scale[i][0]);
2127 scale.textContent = this.scale[i][1];
2128 node.appendChild(scale);
2129 }
2130 return node;
2131 };
2132 };
2133
2134 this.audioElementNode = function() {
2135 this.url = null;
2136 this.id = null;
2137 this.parent = null;
1960 this.type = "normal"; 2138 this.type = "normal";
1961 2139 this.marker = false;
1962 this.marker = undefined; 2140 this.enforce = false;
2141 this.decode = function(parent,xml)
2142 {
2143 this.url = xml.getAttribute('url');
2144 this.id = xml.id;
2145 this.parent = parent;
2146 this.type = xml.getAttribute('type');
2147 if (this.type == null) {this.type = "normal";}
2148 if (this.type == 'anchor') {this.anchor = true;}
2149 else {this.anchor = false;}
2150 if (this.type == 'reference') {this.reference = true;}
2151 else {this.reference = false;}
2152
2153 if (this.anchor == true || this.reference == true)
2154 {
2155 this.marker = xml.getAttribute('marker');
2156 if (this.marker != undefined)
2157 {
2158 this.marker = Number(this.marker);
2159 if (isNaN(this.marker) == false)
2160 {
2161 if (this.marker > 1)
2162 { this.marker /= 100.0;}
2163 if (this.marker >= 0 && this.marker <= 1)
2164 {
2165 this.enforce = true;
2166 return;
2167 } else {
2168 console.log("ERROR - Marker of audioElement "+this.id+" is not between 0 and 1 (float) or 0 and 100 (integer)!");
2169 console.log("ERROR - Marker not enforced!");
2170 }
2171 } else {
2172 console.log("ERROR - Marker of audioElement "+this.id+" is not a number!");
2173 console.log("ERROR - Marker not enforced!");
2174 }
2175 }
2176 }
2177 };
2178 this.encode = function(root)
2179 {
2180 var AENode = root.createElement("audioElements");
2181 AENode.id = this.id;
2182 AENode.setAttribute("url",this.url);
2183 AENode.setAttribute("type",this.type);
2184 if (this.marker != false)
2185 {
2186 AENode.setAttribute("marker",this.marker*100);
2187 }
2188 return AENode;
2189 };
1963 }; 2190 };
1964 2191
1965 this.commentQuestionNode = function(xml) { 2192 this.commentQuestionNode = function(xml) {
2193 this.id = null;
2194 this.type = undefined;
2195 this.question = undefined;
2196 this.options = [];
2197 this.statement = undefined;
2198
2199 this.childOption = function() {
2200 this.type = 'option';
2201 this.name = null;
2202 this.text = null;
2203 };
1966 this.exportXML = function(root) 2204 this.exportXML = function(root)
1967 { 2205 {
1968 var CQNode = root.createElement("CommentQuestion"); 2206 var CQNode = root.createElement("CommentQuestion");
1969 CQNode.id = this.id; 2207 CQNode.id = this.id;
1970 CQNode.setAttribute("type",this.type); 2208 CQNode.setAttribute("type",this.type);
1972 { 2210 {
1973 case "text": 2211 case "text":
1974 CQNode.textContent = this.question; 2212 CQNode.textContent = this.question;
1975 break; 2213 break;
1976 case "radio" || "checkbox": 2214 case "radio" || "checkbox":
1977 var statement = document.createElement("statement"); 2215 var statement = root.createElement("statement");
1978 statement.textContent = this.statement; 2216 statement.textContent = this.statement;
1979 CQNode.appendChild(statement); 2217 CQNode.appendChild(statement);
1980 for (var i=0; i<this.options.length; i++) 2218 for (var i=0; i<this.options.length; i++)
1981 { 2219 {
1982 var optionNode = document.createElement("option"); 2220 var optionNode = root.createElement("option");
1983 optionNode.setAttribute("name",this.options[i].name); 2221 optionNode.setAttribute("name",this.options[i].name);
1984 optionNode.textContent = this.options[i].text; 2222 optionNode.textContent = this.options[i].text;
1985 CQNode.appendChild(optionNode); 2223 CQNode.appendChild(optionNode);
1986 } 2224 }
1987 break; 2225 break;
1988 } 2226 }
1989 return CQNode; 2227 return CQNode;
1990 }; 2228 };
1991 this.childOption = function(element) { 2229 this.decode = function(xml) {
1992 this.type = 'option'; 2230 this.id = xml.id;
1993 this.name = element.getAttribute('name'); 2231 if (xml.getAttribute('mandatory') == 'true') {this.mandatory = true;}
1994 this.text = element.textContent; 2232 else {this.mandatory = false;}
1995 }; 2233 this.type = xml.getAttribute('type');
1996 this.id = xml.id; 2234 if (this.type == undefined) {this.type = 'text';}
1997 if (xml.getAttribute('mandatory') == 'true') {this.mandatory = true;} 2235 switch (this.type) {
1998 else {this.mandatory = false;} 2236 case 'text':
1999 this.type = xml.getAttribute('type'); 2237 this.question = xml.textContent;
2000 if (this.type == undefined) {this.type = 'text';} 2238 break;
2001 switch (this.type) { 2239 case 'radio':
2002 case 'text': 2240 var child = xml.firstElementChild;
2003 this.question = xml.textContent; 2241 this.options = [];
2004 break; 2242 while (child != undefined) {
2005 case 'radio': 2243 if (child.nodeName == 'statement' && this.statement == undefined) {
2006 var child = xml.firstElementChild; 2244 this.statement = child.textContent;
2007 this.options = []; 2245 } else if (child.nodeName == 'option') {
2008 while (child != undefined) { 2246 var node = new this.childOption();
2009 if (child.nodeName == 'statement' && this.statement == undefined) { 2247 node.name = child.getAttribute('name');
2010 this.statement = child.textContent; 2248 node.text = child.textContent;
2011 } else if (child.nodeName == 'option') { 2249 this.options.push(node);
2012 this.options.push(new this.childOption(child)); 2250 }
2251 child = child.nextElementSibling;
2013 } 2252 }
2014 child = child.nextElementSibling; 2253 break;
2015 } 2254 case 'checkbox':
2016 break; 2255 var child = xml.firstElementChild;
2017 case 'checkbox': 2256 this.options = [];
2018 var child = xml.firstElementChild; 2257 while (child != undefined) {
2019 this.options = []; 2258 if (child.nodeName == 'statement' && this.statement == undefined) {
2020 while (child != undefined) { 2259 this.statement = child.textContent;
2021 if (child.nodeName == 'statement' && this.statement == undefined) { 2260 } else if (child.nodeName == 'option') {
2022 this.statement = child.textContent; 2261 var node = new this.childOption();
2023 } else if (child.nodeName == 'option') { 2262 node.name = child.getAttribute('name');
2024 this.options.push(new this.childOption(child)); 2263 node.text = child.textContent;
2264 this.options.push(node);
2265 }
2266 child = child.nextElementSibling;
2025 } 2267 }
2026 child = child.nextElementSibling; 2268 break;
2027 } 2269 }
2028 break; 2270 };
2029 }
2030 }; 2271 };
2031 }; 2272 };
2032
2033 this.preTest = new this.prepostNode("pretest");
2034 this.postTest = new this.prepostNode("posttest");
2035 } 2273 }
2036 2274
2037 function createDeleteNodeButton(node) 2275 function createDeleteNodeButton(node)
2038 { 2276 {
2039 var button = document.createElement("button"); 2277 var button = document.createElement("button");
2044 node.parentElement.removeChild(node); 2282 node.parentElement.removeChild(node);
2045 }; 2283 };
2046 return button; 2284 return button;
2047 } 2285 }
2048 2286
2049 function SpecficationToHTML() 2287 function SpecificationToHTML()
2050 { 2288 {
2051 // Take information from Specification Node and format it into an HTML layout 2289 // Take information from Specification Node and format it into an HTML layout
2052 var destination = document.getElementById("content"); 2290 var destination = document.getElementById("content");
2053 // Setup Header Node 2291 // Setup Header Node
2054 var setupNode = document.createElement("div"); 2292 var setupNode = document.createElement("div");