nickjillings@1370: var interfaceSpecs; nickjillings@1370: var xmlHttp; nickjillings@1370: var popupObject; nickjillings@1370: var popupStateNodes; nickjillings@1370: var specification; nickjillings@1370: var convert; nickjillings@1370: var attributeText; nicholas@2355: var page_lang = "en"; nickjillings@1370: nickjillings@1370: // Firefox does not have an XMLDocument.prototype.getElementsByName nickjillings@1370: // and there is no searchAll style command, this custom function will nickjillings@1370: // search all children recusrively for the name. Used for XSD where all nickjillings@1370: // element nodes must have a name and therefore can pull the schema node nicholas@2535: XMLDocument.prototype.getAllElementsByName = function (name) { nickjillings@1370: name = String(name); nickjillings@1370: var selected = this.documentElement.getAllElementsByName(name); nickjillings@1370: return selected; nickjillings@1370: } nickjillings@1370: nicholas@2535: Element.prototype.getAllElementsByName = function (name) { nickjillings@1370: name = String(name); nickjillings@1370: var selected = []; nickjillings@1370: var node = this.firstElementChild; nicholas@2535: while (node != null) { nicholas@2535: if (node.getAttribute('name') == name) { nickjillings@1370: selected.push(node); nickjillings@1370: } nicholas@2535: if (node.childElementCount > 0) { nickjillings@1370: selected = selected.concat(node.getAllElementsByName(name)); nickjillings@1370: } nickjillings@1370: node = node.nextElementSibling; nickjillings@1370: } nickjillings@1370: return selected; nickjillings@1370: } nickjillings@1370: nicholas@2535: XMLDocument.prototype.getAllElementsByTagName = function (name) { nickjillings@1370: name = String(name); nickjillings@1370: var selected = this.documentElement.getAllElementsByTagName(name); nickjillings@1370: return selected; nickjillings@1370: } nickjillings@1370: nicholas@2535: Element.prototype.getAllElementsByTagName = function (name) { nickjillings@1370: name = String(name); nickjillings@1370: var selected = []; nickjillings@1370: var node = this.firstElementChild; nicholas@2535: while (node != null) { nicholas@2535: if (node.nodeName == name) { nickjillings@1370: selected.push(node); nickjillings@1370: } nicholas@2535: if (node.childElementCount > 0) { nickjillings@1370: selected = selected.concat(node.getAllElementsByTagName(name)); nickjillings@1370: } nickjillings@1370: node = node.nextElementSibling; nickjillings@1370: } nickjillings@1370: return selected; nickjillings@1370: } nickjillings@1370: nickjillings@1370: // Firefox does not have an XMLDocument.prototype.getElementsByName nickjillings@1370: if (typeof XMLDocument.prototype.getElementsByName != "function") { nicholas@2535: XMLDocument.prototype.getElementsByName = function (name) { nickjillings@1370: name = String(name); nickjillings@1370: var node = this.documentElement.firstElementChild; nickjillings@1370: var selected = []; nicholas@2535: while (node != null) { nicholas@2535: if (node.getAttribute('name') == name) { nickjillings@1370: selected.push(node); nickjillings@1370: } nickjillings@1370: node = node.nextElementSibling; nickjillings@1370: } nickjillings@1370: return selected; nickjillings@1370: } nickjillings@1370: } nickjillings@1370: nicholas@2535: window.onload = function () { nickjillings@1370: specification = new Specification(); nickjillings@1370: convert = new SpecificationToHTML(); nickjillings@1370: xmlHttp = new XMLHttpRequest(); nicholas@2535: xmlHttp.open("GET", "test_create/interface-specs.xml", true); nicholas@2535: xmlHttp.onload = function () { nickjillings@1370: var parse = new DOMParser(); nicholas@2535: interfaceSpecs = parse.parseFromString(xmlHttp.response, 'text/xml'); nickjillings@1370: buildPage(); nickjillings@1370: popupObject.postNode(popupStateNodes.state[0]) nickjillings@1370: } nickjillings@1370: xmlHttp.send(); nicholas@2535: nickjillings@1370: var xsdGet = new XMLHttpRequest(); nicholas@2535: xsdGet.open("GET", "xml/test-schema.xsd", true); nicholas@2535: xsdGet.onload = function () { nickjillings@1370: var parse = new DOMParser(); nicholas@2535: specification.schema = parse.parseFromString(xsdGet.response, 'text/xml');; nickjillings@1370: } nickjillings@1370: xsdGet.send(); nicholas@2535: nickjillings@1370: var jsonAttribute = new XMLHttpRequest(); nicholas@2535: jsonAttribute.open("GET", "test_create/attributes.json", true); nicholas@2535: jsonAttribute.onload = function () { nickjillings@1370: attributeText = JSON.parse(jsonAttribute.response) nickjillings@1370: } nickjillings@1370: jsonAttribute.send(); nickjillings@1370: } nickjillings@1370: nicholas@2535: function buildPage() { nicholas@2535: popupObject = new function () { nickjillings@1370: this.object = document.getElementById("popupHolder"); nickjillings@1370: this.blanket = document.getElementById("blanket"); nickjillings@1370: nickjillings@1370: this.popupTitle = document.createElement("div"); nickjillings@1370: this.popupTitle.id = "popup-title-holder"; nickjillings@1370: this.popupTitle.align = "center"; nickjillings@1370: this.titleDOM = document.createElement("span"); nickjillings@1370: this.titleDOM.id = "popup-title"; nickjillings@1370: this.popupTitle.appendChild(this.titleDOM); nickjillings@1370: this.object.appendChild(this.popupTitle); nickjillings@1370: nickjillings@1370: this.popupContent = document.createElement("div"); nickjillings@1370: this.popupContent.id = "popup-content"; nickjillings@1370: this.object.appendChild(this.popupContent); nicholas@2535: nickjillings@1370: this.proceedButton = document.createElement("button"); nickjillings@1370: this.proceedButton.id = "popup-proceed"; nickjillings@2108: this.proceedButton.className = "popup-button"; nickjillings@1370: this.proceedButton.textContent = "Next"; nicholas@2535: this.proceedButton.onclick = function () { nickjillings@1370: popupObject.popupContent.innerHTML = null; nicholas@2535: if (typeof popupObject.shownObject.continue == "function") { nickjillings@2110: popupObject.shownObject.continue(); nickjillings@2110: } else { nickjillings@2110: popupObject.hide(); nickjillings@2110: } nickjillings@1370: }; nickjillings@1370: this.object.appendChild(this.proceedButton); nicholas@2535: nickjillings@2108: this.backButton = document.createElement("button"); nickjillings@2108: this.backButton.id = "popup-back"; nickjillings@2108: this.backButton.className = "popup-button"; nickjillings@2108: this.backButton.textContent = "Back"; nicholas@2535: this.backButton.onclick = function () { nickjillings@2108: popupObject.popupContent.innerHTML = null; nickjillings@2108: popupObject.shownObject.back(); nickjillings@2108: }; nickjillings@2108: this.object.appendChild(this.backButton); nicholas@2535: nickjillings@1370: this.shownObject; nickjillings@1370: nicholas@2535: this.resize = function () { nickjillings@1370: var w = window.innerWidth; nickjillings@1370: var h = window.innerHeight; nicholas@2535: this.object.style.left = Math.floor((w - 750) / 2) + 'px'; nicholas@2535: this.object.style.top = Math.floor((h - 500) / 2) + 'px'; nickjillings@1370: } nickjillings@1370: nicholas@2535: this.show = function () { nickjillings@1370: this.object.style.visibility = "visible"; nickjillings@1370: this.blanket.style.visibility = "visible"; nickjillings@2108: if (typeof this.shownObject.back == "function") { nickjillings@2108: this.backButton.style.visibility = "visible"; nickjillings@2108: } else { nickjillings@2108: this.backButton.style.visibility = "hidden"; nickjillings@2108: } nickjillings@1370: } nickjillings@1370: nicholas@2535: this.hide = function () { nickjillings@1370: this.object.style.visibility = "hidden"; nickjillings@1370: this.blanket.style.visibility = "hidden"; nickjillings@2108: this.backButton.style.visibility = "hidden"; nickjillings@1370: } nickjillings@1370: nicholas@2535: this.postNode = function (postObject) { nickjillings@1370: //Passed object must have the following: nickjillings@1370: // Title: text to show in the title nickjillings@1370: // Content: HTML DOM to show on the page nickjillings@1370: // On complete this HTML DOM is destroyed so make sure it is referenced elsewhere for processing nickjillings@1370: this.titleDOM.textContent = postObject.title; nickjillings@1370: this.popupContent.appendChild(postObject.content); nickjillings@1370: this.shownObject = postObject; nickjillings@2108: if (typeof this.shownObject.back == "function") { nickjillings@2108: this.backButton.style.visibility = "visible"; nickjillings@2108: } else { nickjillings@2108: this.backButton.style.visibility = "hidden"; nickjillings@2108: } nickjillings@2110: if (typeof this.shownObject.continue == "function") { nickjillings@2110: this.proceedButton.textContent = "Next"; nickjillings@2110: } else { nickjillings@2110: this.proceedButton.textContent = "Finish"; nickjillings@2110: } nickjillings@2108: this.show(); nickjillings@1370: } nickjillings@1370: nickjillings@1370: this.resize(); nickjillings@1370: this.hide(); nickjillings@1370: }; nicholas@2535: nicholas@2535: popupStateNodes = new function () { nickjillings@1370: // This defines the several popup states wanted nickjillings@1370: this.state = []; nicholas@2535: this.state[0] = new function () { nickjillings@1370: this.title = "Welcome"; nickjillings@1370: this.content = document.createElement("div"); nickjillings@1370: this.content.id = "state-0"; nickjillings@1370: var span = document.createElement("span"); nickjillings@1370: span.textContent = "Welcome to the WAET test creator tool. This will allow you to create a new test from scratch to suit your testing needs. If you wish to update a test file, please drag and drop the XML document into the area below for processing, otherwise press 'Next' to start a new test. This tool generates files for the WAET 1.2.0 version." nickjillings@1370: this.content.appendChild(span); nickjillings@1370: this.dragArea = document.createElement("div"); nickjillings@1373: this.dragArea.className = "drag-area"; nickjillings@1373: this.dragArea.id = "project-drop"; nickjillings@1370: this.content.appendChild(this.dragArea); nicholas@2535: nicholas@2535: this.dragArea.addEventListener('dragover', function (e) { nickjillings@1373: e.stopPropagation(); nickjillings@1373: e.preventDefault(); nickjillings@1373: e.dataTransfer.dropEffect = 'copy'; nickjillings@1373: e.currentTarget.className = "drag-area drag-over"; nickjillings@1373: }); nicholas@2535: nicholas@2535: this.dragArea.addEventListener('dragexit', function (e) { nickjillings@1373: e.stopPropagation(); nickjillings@1373: e.preventDefault(); nickjillings@1373: e.dataTransfer.dropEffect = 'copy'; nickjillings@1373: e.currentTarget.className = "drag-area"; nickjillings@1373: }); nicholas@2535: nicholas@2535: this.dragArea.addEventListener('drop', function (e) { nickjillings@1373: e.stopPropagation(); nickjillings@1373: e.preventDefault(); nickjillings@1373: e.currentTarget.className = "drag-area drag-dropped"; nickjillings@1373: var files = e.dataTransfer.files[0]; nickjillings@1374: var reader = new FileReader(); nicholas@2535: reader.onload = function (decoded) { nickjillings@1374: var parse = new DOMParser(); nicholas@2535: specification.decode(parse.parseFromString(decoded.target.result, 'text/xml')); nickjillings@1374: popupObject.hide(); nickjillings@1375: popupObject.popupContent.innerHTML = null; nickjillings@1374: convert.convert(document.getElementById('content')); nickjillings@1374: } nickjillings@1374: reader.readAsText(files); nickjillings@1373: }); nickjillings@1370: nicholas@2535: nicholas@2535: this.continue = function () { nickjillings@1370: popupObject.postNode(popupStateNodes.state[1]); nickjillings@1370: } nickjillings@1370: } nicholas@2535: this.state[1] = new function () { nickjillings@1370: this.title = "Select your interface"; nickjillings@1370: this.content = document.createElement("div"); nickjillings@1370: this.content.id = "state-1"; nickjillings@1370: var spnH = document.createElement('div'); nickjillings@1370: var span = document.createElement("span"); nickjillings@1370: span.textContent = "Please select your interface from the list shown below. This will define the various options which are available. This can later be changed."; nickjillings@1370: spnH.appendChild(span); nickjillings@1370: this.content.appendChild(spnH); nickjillings@1370: this.select = document.createElement("select"); nicholas@2355: this.content.appendChild(this.select); nicholas@2355: this.description = document.createElement("p"); nicholas@2355: this.content.appendChild(this.description); nicholas@2390: this.testsXML = interfaceSpecs.getElementsByTagName('tests')[0].getElementsByTagName('test'); nicholas@2535: for (var i = 0; i < this.testsXML.length; i++) { nickjillings@1370: var option = document.createElement('option'); nickjillings@1370: option.value = this.testsXML[i].getAttribute('name'); nickjillings@1370: option.textContent = this.testsXML[i].getAttribute('name'); nickjillings@1370: this.select.appendChild(option); nickjillings@1370: } nicholas@2535: this.handleEvent = function (event) { nicholas@2355: var testXML = interfaceSpecs.getElementsByTagName("tests")[0].getAllElementsByName(this.select.value)[0]; nicholas@2355: var descriptors = testXML.getAllElementsByTagName("description"); nicholas@2355: this.description.textContent = ""; nicholas@2535: for (var i = 0; i < descriptors.length; i++) { nicholas@2355: if (descriptors[i].getAttribute("lang") == page_lang) { nicholas@2355: this.description.textContent = descriptors[i].textContent; nicholas@2355: } nicholas@2355: } nicholas@2355: } nicholas@2535: this.select.addEventListener("change", this); nicholas@2355: this.handleEvent(); nicholas@2535: this.continue = function () { nickjillings@1370: var testXML = interfaceSpecs.getElementsByTagName("tests")[0].getAllElementsByName(this.select.value)[0]; nickjillings@1370: specification.interface = testXML.getAttribute("interface"); nicholas@2535: if (specification.interfaces == null) { nickjillings@2194: specification.interfaces = new specification.interfaceNode(specification); nickjillings@2108: } nicholas@2535: if (specification.metrics == null) { nickjillings@2108: specification.metrics = new specification.metricNode(); nickjillings@2108: } nickjillings@1370: popupStateNodes.state[2].generate(); nickjillings@1370: popupObject.postNode(popupStateNodes.state[2]); nickjillings@1370: } nicholas@2535: this.back = function () { nickjillings@2108: popupObject.postNode(popupStateNodes.state[0]); nickjillings@2108: } nickjillings@1370: } nicholas@2535: this.state[2] = new function () { nickjillings@1370: this.title = "Test Checks & Restrictions"; nickjillings@1370: this.content = document.createElement("div"); nickjillings@1370: this.content.id = "state-1"; nickjillings@1370: var spnH = document.createElement('div'); nickjillings@1370: var span = document.createElement("span"); nickjillings@1370: span.textContent = "Select your test checks and restrictions. Greyed out items are fixed by the test/interface and cannot be changed"; nickjillings@1370: spnH.appendChild(span); nickjillings@1370: this.content.appendChild(spnH); nickjillings@1370: var holder = document.createElement("div"); nickjillings@1370: this.options = []; nickjillings@1370: this.testXML = null; nickjillings@1370: this.interfaceXML = null; nickjillings@2108: this.dynamicContent = document.createElement("div"); nickjillings@2108: this.content.appendChild(this.dynamicContent); nicholas@2535: this.generate = function () { nickjillings@2108: this.options = []; nickjillings@2108: this.dynamicContent.innerHTML = null; nickjillings@1370: var interfaceName = popupStateNodes.state[1].select.value; nickjillings@1370: this.checkText = interfaceSpecs.getElementsByTagName("global")[0].getAllElementsByTagName("checks")[0]; nickjillings@1370: this.testXML = interfaceSpecs.getElementsByTagName("tests")[0].getAllElementsByName(interfaceName)[0]; nickjillings@1370: this.interfaceXML = interfaceSpecs.getAllElementsByTagName("interfaces")[0].getAllElementsByName(this.testXML.getAttribute("interface"))[0].getAllElementsByTagName("checks")[0]; nickjillings@1370: this.testXML = this.testXML.getAllElementsByTagName("checks"); nicholas@2390: var interfaceXMLChildren = this.interfaceXML.getElementsByTagName('entry'); nicholas@2535: for (var i = 0; i < interfaceXMLChildren.length; i++) { nicholas@2390: var interfaceNode = interfaceXMLChildren[i]; nickjillings@1370: var checkName = interfaceNode.getAttribute('name'); nickjillings@1370: var testNode nicholas@2535: if (this.testXML.length > 0) { nickjillings@1370: testNode = this.testXML[0].getAllElementsByName(checkName); nicholas@2535: if (testNode.length != 0) { nicholas@2535: testNode = testNode[0]; nicholas@2535: } else { nicholas@2535: testNode = undefined; nicholas@2535: } nickjillings@1370: } else { nickjillings@1370: testNode = undefined; nickjillings@1370: } nickjillings@2108: var obj = { nickjillings@2108: root: document.createElement("div"), nickjillings@2109: text: document.createElement("label"), nickjillings@2108: input: document.createElement("input"), nickjillings@2108: parent: this, nickjillings@2108: name: checkName, nicholas@2535: handleEvent: function (event) { nickjillings@2108: if (this.input.checked) { nickjillings@2108: // Add to specification.interfaces.option nicholas@2535: var included = specification.interfaces.options.find(function (element, index, array) { nicholas@2535: if (element.name == this.name) { nicholas@2535: return true; nicholas@2535: } else { nicholas@2535: return false; nicholas@2535: } nicholas@2535: }, this); nickjillings@2108: if (included == null) { nicholas@2535: specification.interfaces.options.push({ nicholas@2535: type: "check", nicholas@2535: name: this.name nicholas@2535: }); nickjillings@2108: } nickjillings@2108: } else { nickjillings@2108: // Remove from specification.interfaces.option nicholas@2535: var position = specification.interfaces.options.findIndex(function (element, index, array) { nicholas@2535: if (element.name == this.name) { nicholas@2535: return true; nicholas@2535: } else { nicholas@2535: return false; nicholas@2535: } nicholas@2535: }, this); nickjillings@2108: if (position >= 0) { nicholas@2535: specification.interfaces.options.splice(position, 1); nickjillings@2108: } nickjillings@2108: } nickjillings@2108: } nickjillings@1370: } nicholas@2535: nicholas@2535: obj.input.addEventListener("click", obj); nickjillings@2108: obj.root.className = "popup-checkbox"; nickjillings@2108: obj.input.type = "checkbox"; nicholas@2535: obj.input.setAttribute('id', checkName); nicholas@2535: obj.text.setAttribute("for", checkName); nickjillings@2108: obj.text.textContent = this.checkText.getAllElementsByName(checkName)[0].textContent; nickjillings@2108: obj.root.appendChild(obj.input); nickjillings@2108: obj.root.appendChild(obj.text); nicholas@2535: if (testNode != undefined) { nicholas@2535: if (testNode.getAttribute('default') == 'on') { nickjillings@2108: obj.input.checked = true; nickjillings@1370: } nicholas@2535: if (testNode.getAttribute('support') == "none") { nickjillings@2108: obj.input.disabled = true; nickjillings@2108: obj.input.checked = false; nickjillings@2108: obj.root.className = "popup-checkbox disabled"; nicholas@2535: } else if (interfaceNode.getAttribute('support') == "mandatory") { nickjillings@2108: obj.input.disabled = true; nickjillings@2108: obj.input.checked = true; nickjillings@2108: obj.root.className = "popup-checkbox disabled"; nickjillings@2108: } nickjillings@2108: } else { nicholas@2535: if (interfaceNode.getAttribute('default') == 'on') { nickjillings@2108: obj.input.checked = true; nickjillings@2108: } nicholas@2535: if (interfaceNode.getAttribute('support') == "none") { nickjillings@2108: obj.input.disabled = true; nickjillings@2108: obj.input.checked = false; nickjillings@2108: obj.root.className = "popup-checkbox disabled"; nicholas@2535: } else if (interfaceNode.getAttribute('support') == "mandatory") { nickjillings@2108: obj.input.disabled = true; nickjillings@2108: obj.input.checked = true; nickjillings@2108: obj.root.className = "popup-checkbox disabled"; nickjillings@1370: } nickjillings@1370: } nicholas@2535: var included = specification.interfaces.options.find(function (element, index, array) { nicholas@2535: if (element.name == this.name) { nicholas@2535: return true; nicholas@2535: } else { nicholas@2535: return false; nicholas@2535: } nicholas@2535: }, obj); nickjillings@2108: if (included != undefined) { nickjillings@2108: obj.input.checked = true; nickjillings@2108: } nickjillings@2108: obj.handleEvent(); nickjillings@2108: this.options.push(obj); nickjillings@2108: this.dynamicContent.appendChild(obj.root); nickjillings@1370: } nickjillings@1370: } nicholas@2535: this.continue = function () { nickjillings@1370: popupStateNodes.state[3].generate(); nickjillings@1370: popupObject.postNode(popupStateNodes.state[3]); nickjillings@1370: } nicholas@2535: this.back = function () { nickjillings@2108: popupObject.postNode(popupStateNodes.state[1]); nickjillings@2108: } nickjillings@1370: } nicholas@2535: this.state[3] = new function () { nickjillings@1370: this.title = "Test Metrics"; nickjillings@1370: this.content = document.createElement("div"); nickjillings@1370: this.content.id = "state-1"; nickjillings@1370: var spnH = document.createElement('div'); nickjillings@1370: var span = document.createElement("span"); nickjillings@1370: span.textContent = "Select which data points to include in the exported results XML. Some of this is required for certain post script analysis. See the documentation for further details"; nickjillings@1370: spnH.appendChild(span); nickjillings@1370: this.content.appendChild(spnH); nickjillings@1370: this.options = []; nickjillings@1370: this.checkText; nickjillings@1370: this.testXML; nickjillings@1370: this.interfaceXML; nickjillings@2108: this.dynamicContent = document.createElement("div"); nickjillings@2108: this.content.appendChild(this.dynamicContent); nicholas@2535: this.generate = function () { nickjillings@2108: this.options = []; nickjillings@2108: this.dynamicContent.innerHTML = null; nickjillings@1370: var interfaceName = popupStateNodes.state[1].select.value; nickjillings@1370: this.checkText = interfaceSpecs.getElementsByTagName("global")[0].getAllElementsByTagName("metrics")[0]; nickjillings@1370: this.testXML = interfaceSpecs.getElementsByTagName("tests")[0].getAllElementsByName(interfaceName)[0]; nickjillings@1370: this.interfaceXML = interfaceSpecs.getAllElementsByTagName("interfaces")[0].getAllElementsByName(this.testXML.getAttribute("interface"))[0].getAllElementsByTagName("metrics")[0]; nickjillings@1370: this.testXML = this.testXML.getAllElementsByTagName("metrics"); nicholas@2390: var interfaceXMLChildren = this.interfaceXML.getElementsByTagName('entry'); nicholas@2535: for (var i = 0; i < interfaceXMLChildren.length; i++) { nicholas@2390: var interfaceNode = interfaceXMLChildren[i]; nickjillings@1370: var checkName = interfaceNode.getAttribute('name'); nickjillings@1370: var testNode nicholas@2535: if (this.testXML.length > 0) { nickjillings@1370: testNode = this.testXML[0].getAllElementsByName(checkName); nicholas@2535: if (testNode.length != 0) { nicholas@2535: testNode = testNode[0]; nicholas@2535: } else { nicholas@2535: testNode = undefined; nicholas@2535: } nickjillings@1370: } else { nickjillings@1370: testNode = undefined; nickjillings@1370: } nickjillings@2108: var obj = { nickjillings@2108: root: document.createElement("div"), nickjillings@2109: text: document.createElement("label"), nickjillings@2108: input: document.createElement("input"), nickjillings@2108: parent: this, nickjillings@2108: name: checkName, nicholas@2535: handleEvent: function (event) { nickjillings@2108: if (this.input.checked) { nickjillings@2108: // Add to specification.interfaces.option nicholas@2535: var included = specification.metrics.enabled.find(function (element, index, array) { nicholas@2535: if (element == this.name) { nicholas@2535: return true; nicholas@2535: } else { nicholas@2535: return false; nicholas@2535: } nicholas@2535: }, this); nickjillings@2108: if (included == null) { nickjillings@2108: specification.metrics.enabled.push(this.name); nickjillings@2108: } nickjillings@2108: } else { nickjillings@2108: // Remove from specification.interfaces.option nicholas@2535: var position = specification.metrics.enabled.findIndex(function (element, index, array) { nicholas@2535: if (element == this.name) { nicholas@2535: return true; nicholas@2535: } else { nicholas@2535: return false; nicholas@2535: } nicholas@2535: }, this); nickjillings@2108: if (position >= 0) { nicholas@2535: specification.metrics.enabled.splice(position, 1); nickjillings@2108: } nickjillings@2108: } nickjillings@2108: } nickjillings@1370: } nicholas@2535: nicholas@2535: obj.input.addEventListener("click", obj); nickjillings@2108: obj.root.className = "popup-checkbox"; nickjillings@2108: obj.input.type = "checkbox"; nicholas@2535: obj.input.setAttribute('id', checkName); nicholas@2535: obj.text.setAttribute("for", checkName); nickjillings@2108: obj.text.textContent = this.checkText.getAllElementsByName(checkName)[0].textContent; nickjillings@2108: obj.root.appendChild(obj.input); nickjillings@2108: obj.root.appendChild(obj.text); nicholas@2535: if (testNode != undefined) { nicholas@2535: if (testNode.getAttribute('default') == 'on') { nickjillings@2108: obj.input.checked = true; nickjillings@1370: } nicholas@2535: if (testNode.getAttribute('support') == "none") { nickjillings@2108: obj.input.disabled = true; nickjillings@2108: obj.input.checked = false; nickjillings@2108: obj.root.className = "popup-checkbox disabled"; nicholas@2535: } else if (interfaceNode.getAttribute('support') == "mandatory") { nickjillings@2108: obj.input.disabled = true; nickjillings@2108: obj.input.checked = true; nickjillings@2108: obj.root.className = "popup-checkbox disabled"; nickjillings@2108: } nickjillings@2108: } else { nicholas@2535: if (interfaceNode.getAttribute('default') == 'on') { nickjillings@2108: obj.input.checked = true; nickjillings@2108: } nicholas@2535: if (interfaceNode.getAttribute('support') == "none") { nickjillings@2108: obj.input.disabled = true; nickjillings@2108: obj.input.checked = false; nickjillings@2108: obj.root.className = "popup-checkbox disabled"; nicholas@2535: } else if (interfaceNode.getAttribute('support') == "mandatory") { nickjillings@2108: obj.input.disabled = true; nickjillings@2108: obj.input.checked = true; nickjillings@2108: obj.root.className = "popup-checkbox disabled"; nickjillings@1370: } nickjillings@1370: } nicholas@2535: var included = specification.metrics.enabled.find(function (element, index, array) { nicholas@2535: if (element == this.name) { nicholas@2535: return true; nicholas@2535: } else { nicholas@2535: return false; nicholas@2535: } nicholas@2535: }, obj); nickjillings@2108: obj.handleEvent(); nickjillings@2108: if (included != undefined) { nickjillings@2108: obj.input.checked = true; nickjillings@2108: } nickjillings@2108: this.options.push(obj); nickjillings@2108: this.dynamicContent.appendChild(obj.root); nickjillings@1370: } nickjillings@1370: } nicholas@2535: this.continue = function () { nickjillings@1370: popupStateNodes.state[4].generate(); nickjillings@1370: popupObject.postNode(popupStateNodes.state[4]); nickjillings@1370: } nicholas@2535: this.back = function () { nickjillings@2108: popupObject.postNode(popupStateNodes.state[2]); nickjillings@2108: } nickjillings@1370: } nicholas@2535: this.state[4] = new function () { nickjillings@1370: this.title = "Test Visuals"; nickjillings@1370: this.content = document.createElement("div"); nickjillings@1370: this.content.id = "state-1"; nickjillings@1370: var spnH = document.createElement('div'); nickjillings@1370: var span = document.createElement("span"); nickjillings@1370: span.textContent = "You can display extra visual content with your interface for the test user to interact with. Select from the available options below. Greyed out options are unavailable for your selected interface"; nickjillings@1370: spnH.appendChild(span); nickjillings@1370: this.content.appendChild(spnH); nickjillings@1370: this.options = []; nickjillings@1370: this.checkText; nickjillings@1370: this.testXML; nickjillings@1370: this.interfaceXML; nickjillings@2108: this.dynamicContent = document.createElement("div"); nickjillings@2108: this.content.appendChild(this.dynamicContent); nicholas@2535: this.generate = function () { nickjillings@2108: this.options = []; nickjillings@2108: this.dynamicContent.innerHTML = null; nickjillings@1370: var interfaceName = popupStateNodes.state[1].select.value; nickjillings@1370: this.checkText = interfaceSpecs.getElementsByTagName("global")[0].getAllElementsByTagName("show")[0]; nickjillings@1370: this.testXML = interfaceSpecs.getElementsByTagName("tests")[0].getAllElementsByName(interfaceName)[0]; nickjillings@1370: this.interfaceXML = interfaceSpecs.getAllElementsByTagName("interfaces")[0].getAllElementsByName(this.testXML.getAttribute("interface"))[0].getAllElementsByTagName("show")[0]; nickjillings@2108: this.testXML = this.testXML.getAllElementsByTagName("show"); nicholas@2390: var interfaceXMLChildren = this.interfaceXML.getElementsByTagName('entry'); nicholas@2535: for (var i = 0; i < interfaceXMLChildren.length; i++) { nicholas@2390: var interfaceNode = interfaceXMLChildren[i]; nickjillings@1370: var checkName = interfaceNode.getAttribute('name'); nickjillings@1370: var testNode nicholas@2535: if (this.testXML.length > 0) { nickjillings@1370: testNode = this.testXML[0].getAllElementsByName(checkName); nicholas@2535: if (testNode.length != 0) { nicholas@2535: testNode = testNode[0]; nicholas@2535: } else { nicholas@2535: testNode = undefined; nicholas@2535: } nickjillings@1370: } else { nickjillings@1370: testNode = undefined; nickjillings@1370: } nickjillings@2108: var obj = { nickjillings@2108: root: document.createElement("div"), nickjillings@2109: text: document.createElement("label"), nickjillings@2108: input: document.createElement("input"), nickjillings@2108: parent: this, nickjillings@2108: name: checkName, nicholas@2535: handleEvent: function (event) { nickjillings@2108: if (this.input.checked) { nickjillings@2108: // Add to specification.interfaces.option nicholas@2535: var included = specification.interfaces.options.find(function (element, index, array) { nicholas@2535: if (element.name == this.name) { nicholas@2535: return true; nicholas@2535: } else { nicholas@2535: return false; nicholas@2535: } nicholas@2535: }, this); nickjillings@2108: if (included == null) { nicholas@2535: specification.interfaces.options.push({ nicholas@2535: type: "show", nicholas@2535: name: this.name nicholas@2535: }); nickjillings@2108: } nickjillings@2108: } else { nickjillings@2108: // Remove from specification.interfaces.option nicholas@2535: var position = specification.interfaces.options.findIndex(function (element, index, array) { nicholas@2535: if (element.name == this.name) { nicholas@2535: return true; nicholas@2535: } else { nicholas@2535: return false; nicholas@2535: } nicholas@2535: }, this); nickjillings@2108: if (position >= 0) { nicholas@2535: specification.interfaces.options.splice(position, 1); nickjillings@2108: } nickjillings@2108: } nickjillings@2108: } nickjillings@1370: } nicholas@2535: nicholas@2535: obj.input.addEventListener("click", obj); nickjillings@2108: obj.root.className = "popup-checkbox"; nickjillings@2108: obj.input.type = "checkbox"; nicholas@2535: obj.input.setAttribute('id', checkName); nicholas@2535: obj.text.setAttribute("for", checkName); nickjillings@2108: obj.text.textContent = this.checkText.getAllElementsByName(checkName)[0].textContent; nickjillings@2108: obj.root.appendChild(obj.input); nickjillings@2108: obj.root.appendChild(obj.text); nicholas@2535: if (testNode != undefined) { nicholas@2535: if (testNode.getAttribute('default') == 'on') { nickjillings@2108: obj.input.checked = true; nickjillings@1370: } nicholas@2535: if (testNode.getAttribute('support') == "none") { nickjillings@2108: obj.input.disabled = true; nickjillings@2108: obj.input.checked = false; nickjillings@2108: obj.root.className = "popup-checkbox disabled"; nicholas@2535: } else if (interfaceNode.getAttribute('support') == "mandatory") { nickjillings@2108: obj.input.disabled = true; nickjillings@2108: obj.input.checked = true; nickjillings@2108: obj.root.className = "popup-checkbox disabled"; nickjillings@2108: } nickjillings@2108: } else { nicholas@2535: if (interfaceNode.getAttribute('default') == 'on') { nickjillings@2108: obj.input.checked = true; nickjillings@2108: } nicholas@2535: if (interfaceNode.getAttribute('support') == "none") { nickjillings@2108: obj.input.disabled = true; nickjillings@2108: obj.input.checked = false; nickjillings@2108: obj.root.className = "popup-checkbox disabled"; nicholas@2535: } else if (interfaceNode.getAttribute('support') == "mandatory") { nickjillings@2108: obj.input.disabled = true; nickjillings@2108: obj.input.checked = true; nickjillings@2108: obj.root.className = "popup-checkbox disabled"; nickjillings@1370: } nickjillings@1370: } nicholas@2535: var included = specification.interfaces.options.find(function (element, index, array) { nicholas@2535: if (element.name == this.name) { nicholas@2535: return true; nicholas@2535: } else { nicholas@2535: return false; nicholas@2535: } nicholas@2535: }, obj); nickjillings@2108: if (included != undefined) { nickjillings@2108: obj.input.checked = true; nickjillings@2108: } nickjillings@2108: obj.handleEvent(); nickjillings@2108: this.options.push(obj); nickjillings@2108: this.dynamicContent.appendChild(obj.root); nickjillings@1370: } nickjillings@1370: } nicholas@2535: this.continue = function () { nickjillings@1370: popupObject.hide(); nickjillings@1370: convert.convert(document.getElementById('content')); nickjillings@1370: } nicholas@2535: this.back = function () { nickjillings@2108: popupObject.postNode(popupStateNodes.state[3]); nickjillings@2108: } nickjillings@1370: } nicholas@2535: this.state[5] = new function () { nickjillings@1370: this.title = "Add/Edit Survey Element"; nickjillings@1370: this.content = document.createElement("div"); nickjillings@1370: this.content.id = "state-1"; nickjillings@1370: var spnH = document.createElement('div'); nickjillings@1370: var span = document.createElement("span"); nickjillings@1370: span.textContent = "You can configure your survey element here. Press 'Continue' to complete your changes."; nickjillings@1370: spnH.appendChild(span); nickjillings@1370: this.content.appendChild(spnH); nickjillings@1370: this.dynamic = document.createElement("div"); nickjillings@1370: this.option = null; nickjillings@1370: this.parent = null; nickjillings@1375: this.optionLists = []; nickjillings@2158: this.select = document.createElement("select"); nicholas@2535: this.select.setAttribute("name", "type"); nicholas@2535: this.select.addEventListener("change", this, false); nickjillings@2158: this.content.appendChild(this.select); nickjillings@1370: this.content.appendChild(this.dynamic); nicholas@2535: this.generate = function (option, parent) { nickjillings@1370: this.option = option; nickjillings@1370: this.parent = parent; nickjillings@2158: if (this.select.childElementCount == 0) { nickjillings@2158: var optionList = specification.schema.getAllElementsByName("survey")[0].getAllElementsByName("type")[0].getAllElementsByTagName("xs:enumeration"); nicholas@2535: for (var i = 0; i < optionList.length; i++) { nickjillings@2158: var selectOption = document.createElement("option"); nickjillings@2158: selectOption.value = optionList[i].getAttribute("value"); nickjillings@2158: selectOption.textContent = selectOption.value; nickjillings@2158: this.select.appendChild(selectOption); nickjillings@2158: } nickjillings@1370: } nicholas@2535: if (this.option.type != undefined) { nickjillings@2158: this.select.value = this.option.type nickjillings@1370: } else { nickjillings@2158: this.select.value = "statement"; nickjillings@1370: this.option.type = "statement"; nickjillings@1370: } nicholas@2535: nickjillings@1370: this.dynamic.innerHTML = null; nickjillings@1370: var statement = document.createElement("div"); nickjillings@1370: var statementText = document.createElement("span"); nickjillings@2159: var statementEntry = document.createElement("input"); nickjillings@1370: statement.appendChild(statementText); nickjillings@1370: statement.appendChild(statementEntry); nickjillings@2159: statement.className = "survey-entry-attribute"; nickjillings@1370: statementText.textContent = "Statement/Question"; nickjillings@2159: statementEntry.style.width = "500px"; nicholas@2535: statementEntry.addEventListener("change", this, false); nicholas@2535: statementEntry.setAttribute("name", "statement"); nickjillings@1370: statementEntry.value = this.option.statement; nickjillings@1370: this.dynamic.appendChild(statement); nicholas@2535: nickjillings@1375: var id = document.createElement("div"); nickjillings@1375: var idText = document.createElement("span"); nickjillings@1375: var idEntry = document.createElement("input"); nickjillings@1375: id.appendChild(idText); nickjillings@1375: id.appendChild(idEntry); nickjillings@2159: id.className = "survey-entry-attribute"; nickjillings@1375: idText.textContent = "ID: "; nicholas@2535: idEntry.addEventListener("change", this, false); nicholas@2535: idEntry.setAttribute("name", "id"); nickjillings@1375: idEntry.value = this.option.id; nicholas@2535: nickjillings@2158: this.dynamic.appendChild(id); nicholas@2535: nicholas@2535: switch (this.option.type) { nickjillings@1370: case "statement": nickjillings@1370: break; nickjillings@1370: case "question": nickjillings@1370: var boxsizeSelect = document.createElement("select"); nickjillings@1370: var optionList = specification.schema.getAllElementsByName("survey")[0].getAllElementsByName("boxsize")[0].getAllElementsByTagName("xs:enumeration"); nicholas@2535: for (var i = 0; i < optionList.length; i++) { nickjillings@1370: var selectOption = document.createElement("option"); nickjillings@1370: selectOption.value = optionList[i].getAttribute("value"); nickjillings@1370: selectOption.textContent = selectOption.value; nickjillings@1370: boxsizeSelect.appendChild(selectOption); nickjillings@1370: } nicholas@2535: if (this.option.boxsize != undefined) { nickjillings@1370: boxsizeSelect.value = this.option.boxsize; nickjillings@1370: } else { nickjillings@1370: boxsizeSelect.value = "normal"; nickjillings@1370: this.option.boxsize = "normal"; nickjillings@1370: } nicholas@2535: boxsizeSelect.setAttribute("name", "boxsize"); nicholas@2535: boxsizeSelect.addEventListener("change", this, false); nickjillings@1370: var boxsize = document.createElement("div"); nickjillings@1370: var boxsizeText = document.createElement("span"); nickjillings@1370: boxsizeText.textContent = "Entry Size: "; nickjillings@1370: boxsize.appendChild(boxsizeText); nickjillings@1370: boxsize.appendChild(boxsizeSelect); nickjillings@2159: boxsize.className = "survey-entry-attribute"; nickjillings@1370: this.dynamic.appendChild(boxsize); nicholas@2535: nickjillings@1370: var mandatory = document.createElement("div"); nickjillings@1370: var mandatoryInput = document.createElement("input"); nickjillings@1370: var mandatoryText = document.createElement("span"); nickjillings@1370: mandatoryText.textContent = "Mandatory: "; nickjillings@1370: mandatory.appendChild(mandatoryText); nickjillings@1370: mandatory.appendChild(mandatoryInput); nickjillings@2159: mandatory.className = "survey-entry-attribute"; nickjillings@1370: mandatoryInput.type = "checkbox"; nicholas@2535: if (this.option.mandatory) { nicholas@2535: mandatoryInput.checked = true; nicholas@2535: } else { nicholas@2535: mandatoryInput.checked = false; nicholas@2535: } nicholas@2535: mandatoryInput.setAttribute("name", "mandatory"); nicholas@2535: mandatoryInput.addEventListener("change", this, false); nickjillings@1375: this.dynamic.appendChild(mandatory); nickjillings@1375: break; nickjillings@1375: case "number": nickjillings@1375: this.dynamic.appendChild(id); nicholas@2535: nickjillings@1375: var mandatory = document.createElement("div"); nickjillings@1375: var mandatoryInput = document.createElement("input"); nickjillings@1375: var mandatoryText = document.createElement("span"); nickjillings@1375: mandatoryText.textContent = "Mandatory: "; nickjillings@1370: mandatory.appendChild(mandatoryText); nickjillings@1370: mandatory.appendChild(mandatoryInput); nickjillings@2159: mandatory.className = "survey-entry-attribute"; nickjillings@1375: mandatoryInput.type = "checkbox"; nicholas@2535: if (this.option.mandatory) { nicholas@2535: mandatoryInput.checked = true; nicholas@2535: } else { nicholas@2535: mandatoryInput.checked = false; nicholas@2535: } nicholas@2535: mandatoryInput.setAttribute("name", "mandatory"); nicholas@2535: mandatoryInput.addEventListener("change", this, false); nickjillings@1370: this.dynamic.appendChild(mandatory); nicholas@2535: nickjillings@1375: var minimum = document.createElement("div"); nickjillings@1375: var minimumEntry = document.createElement("input"); nickjillings@1375: var minimumText = document.createElement("span"); nickjillings@1375: minimumText.textContent = "Minimum: "; nickjillings@1375: minimum.appendChild(minimumText); nickjillings@1375: minimum.appendChild(minimumEntry); nickjillings@2159: minimum.className = "survey-entry-attribute"; nickjillings@1375: minimumEntry.type = "number"; nicholas@2535: minimumEntry.setAttribute("name", "min"); nicholas@2535: minimumEntry.addEventListener("change", this, false); nickjillings@1375: minimumEntry.value = this.option.min; nickjillings@1375: this.dynamic.appendChild(minimum); nicholas@2535: nickjillings@1375: var maximum = document.createElement("div"); nickjillings@1375: var maximumEntry = document.createElement("input"); nickjillings@1375: var maximumText = document.createElement("span"); nickjillings@1375: maximumText.textContent = "Maximum: "; nickjillings@1375: maximum.appendChild(maximumText); nickjillings@1375: maximum.appendChild(maximumEntry); nickjillings@2159: maximum.className = "survey-entry-attribute"; nickjillings@1375: maximumEntry.type = "number"; nicholas@2535: maximumEntry.setAttribute("name", "max"); nicholas@2535: maximumEntry.addEventListener("change", this, false); nickjillings@1375: maximumEntry.value = this.option.max; nickjillings@1375: this.dynamic.appendChild(maximum); nickjillings@1370: break; nickjillings@1375: case "checkbox": nickjillings@1375: case "radio": nickjillings@1375: this.dynamic.appendChild(id); nickjillings@1375: var optionHolder = document.createElement("div"); nickjillings@1375: optionHolder.className = 'node'; nickjillings@1375: optionHolder.id = 'popup-option-holder'; nicholas@2535: var optionObject = function (parent, option) { nickjillings@1375: this.rootDOM = document.createElement("div"); nickjillings@1375: this.rootDOM.className = "popup-option-entry"; nickjillings@1375: this.inputName = document.createElement("input"); nicholas@2535: this.inputName.setAttribute("name", "name"); nickjillings@1375: this.inputLabel = document.createElement("input"); nicholas@2535: this.inputLabel.setAttribute("name", "text"); nickjillings@1375: this.specification = option; nickjillings@1375: this.parent = parent; nicholas@2535: this.handleEvent = function () { nickjillings@1375: var target = event.currentTarget.getAttribute("name"); nicholas@2535: eval("this.specification." + target + " = event.currentTarget.value"); nickjillings@1375: }; nicholas@2535: nickjillings@1375: var nameText = document.createElement("span"); nickjillings@1375: nameText.textContent = "Name: "; nickjillings@1375: var labelText = document.createElement("span"); nickjillings@1375: labelText.textContent = "Label: "; nickjillings@1375: this.rootDOM.appendChild(nameText); nickjillings@1375: this.rootDOM.appendChild(this.inputName); nickjillings@1375: this.rootDOM.appendChild(labelText); nickjillings@1375: this.rootDOM.appendChild(this.inputLabel); nicholas@2535: this.inputName.addEventListener("change", this, false); nicholas@2535: this.inputLabel.addEventListener("change", this, false); nickjillings@1375: this.inputName.value = this.specification.name; nickjillings@1375: this.inputLabel.value = this.specification.text; nickjillings@2180: this.inputLabel.style.width = "350px"; nicholas@2535: nickjillings@1375: this.deleteEntry = { nickjillings@1375: root: document.createElement("button"), nickjillings@1375: parent: this, nicholas@2535: handleEvent: function () { nickjillings@1375: document.getElementById("popup-option-holder").removeChild(this.parent.rootDOM); nicholas@2535: var index = this.parent.parent.option.options.findIndex(function (element, index, array) { nickjillings@1375: if (element == this.parent.specification) nickjillings@1375: return true; nickjillings@1375: else nickjillings@1375: return false; nicholas@2535: }, this); nickjillings@1375: var optionList = this.parent.parent.option.options; nicholas@2535: if (index == optionList.length - 1) { nicholas@2535: optionList = optionList.slice(0, index); nickjillings@1375: } else { nicholas@2535: optionList = optionList.slice(0, index).concat(optionList.slice(index + 1)); nickjillings@1375: } nickjillings@1375: this.parent.parent.option.options = optionList; nickjillings@1375: } nickjillings@1375: }; nickjillings@1375: this.deleteEntry.root.textContent = "Delete Option"; nicholas@2535: this.deleteEntry.root.addEventListener("click", this.deleteEntry, false); nickjillings@1375: this.rootDOM.appendChild(this.deleteEntry.root); nickjillings@1375: } nickjillings@2158: this.addEntry = { nickjillings@2158: parent: this, nickjillings@2158: root: document.createElement("button"), nicholas@2535: handleEvent: function () { nicholas@2535: var node = { nicholas@2535: name: "name", nicholas@2535: text: "text" nicholas@2535: }; nickjillings@2158: var optionsList = this.parent.option.options; nickjillings@2158: optionsList.push(node); nicholas@2535: var obj = new optionObject(this.parent, optionsList[optionsList.length - 1]); nickjillings@2158: this.parent.optionLists.push(obj); nickjillings@2158: document.getElementById("popup-option-holder").appendChild(obj.rootDOM); nickjillings@2158: } nickjillings@2158: } nickjillings@2158: this.addEntry.root.textContent = "Add Option"; nicholas@2535: this.addEntry.root.addEventListener("click", this.addEntry); nickjillings@2158: this.dynamic.appendChild(this.addEntry.root); nicholas@2535: for (var i = 0; i < this.option.options.length; i++) { nicholas@2535: var obj = new optionObject(this, this.option.options[i]); nickjillings@1375: this.optionLists.push(obj); nickjillings@1375: optionHolder.appendChild(obj.rootDOM); nickjillings@1375: } nickjillings@1375: this.dynamic.appendChild(optionHolder); nickjillings@1370: } nickjillings@1370: } nicholas@2536: this.handleEvent = function (event) { nickjillings@1370: var name = event.currentTarget.getAttribute("name"); nickjillings@2159: var nodeName = event.currentTarget.nodeName; nickjillings@2159: if (name == "type" && nodeName == "SELECT") { nickjillings@2159: // If type has changed, we may need to rebuild the entire state node nicholas@2535: if (event.currentTarget.value != this.option.name) { nickjillings@2159: this.option.type = event.currentTarget.value; nicholas@2535: this.generate(this.option, this.parent); nickjillings@2159: } nickjillings@2159: return; nickjillings@2159: } nicholas@2535: switch (event.currentTarget.getAttribute("type")) { nickjillings@2159: case "checkbox": nicholas@2535: eval("this.option." + name + " = event.currentTarget.checked"); nickjillings@1370: break; nickjillings@2159: default: nicholas@2535: eval("this.option." + name + " = event.currentTarget.value"); nickjillings@1370: break; nickjillings@1370: } nickjillings@1370: } nicholas@2535: this.continue = function () { nicholas@2535: if (this.parent.type == "surveyNode") { nicholas@2535: var newNode = new this.parent.surveyEntryNode(this.parent, this.option); nickjillings@1375: this.parent.children.push(newNode); nickjillings@1375: this.parent.childrenDOM.appendChild(newNode.rootDOM); nickjillings@1375: } else if (this.parent.type == "surveyEntryNode") { nickjillings@1375: this.parent.build(); nickjillings@1375: } nickjillings@1370: popupObject.hide(); nickjillings@1370: } nickjillings@1370: } nicholas@2535: this.state[6] = new function () { nickjillings@1385: this.title = "Edit Scale Markers"; nickjillings@1385: this.content = document.createElement("div"); nickjillings@1385: this.content.id = "state-6"; nickjillings@1385: var spnH = document.createElement('div'); nickjillings@1385: var span = document.createElement("span"); nickjillings@1385: span.textContent = "You can edit your scale markers here for the selected interface."; nickjillings@1385: spnH.appendChild(span); nickjillings@1385: this.scaleRoot; nickjillings@1385: this.parent; nicholas@2535: this.markerNodes = []; nickjillings@1385: this.preset = { nickjillings@1385: input: document.createElement("select"), nickjillings@1385: parent: this, nicholas@2535: handleEvent: function (event) { nickjillings@1385: this.parent.scaleRoot.scales = []; nickjillings@1385: var protoScale = interfaceSpecs.getAllElementsByTagName('scaledefinitions')[0].getAllElementsByName(event.currentTarget.value)[0]; nicholas@2610: var protoMarkers = protoScale.getElementsByTagName("scalelabel"); nicholas@2535: for (var i = 0; i < protoMarkers.length; i++) { nickjillings@1385: var marker = { nickjillings@1385: position: protoMarkers[i].getAttribute("position"), nickjillings@1385: text: protoMarkers[i].textContent nickjillings@1385: } nickjillings@1385: this.parent.scaleRoot.scales.push(marker); nickjillings@1385: } nickjillings@1385: this.parent.buildMarkerList(); nickjillings@1385: } nickjillings@1385: } nicholas@2535: this.preset.input.addEventListener("change", this.preset); nickjillings@1385: this.content.appendChild(this.preset.input); nickjillings@1385: var optionHolder = document.createElement("div"); nickjillings@1385: optionHolder.className = 'node'; nickjillings@1385: optionHolder.id = 'popup-option-holder'; nickjillings@1385: this.content.appendChild(optionHolder); n@2609: this.addMarker = { n@2609: root: document.createElement("button"), n@2609: parent: this, n@2609: handleEvent: function () { n@2609: var marker = { n@2609: position: 0, n@2609: text: "text" n@2609: }; n@2609: this.parent.scaleRoot.scales.push(marker); n@2609: var markerNode = new this.parent.buildMarkerNode(this.parent, marker); n@2609: document.getElementById("popup-option-holder").appendChild(markerNode.root); n@2609: this.parent.markerNodes.push(markerNode); n@2609: } n@2609: }; n@2609: this.addMarker.root.textContent = "Add Marker"; n@2609: this.addMarker.root.addEventListener("click", this.addMarker); nicholas@2535: this.generate = function (scaleRoot, parent) { nickjillings@1385: this.scaleRoot = scaleRoot; nickjillings@1385: this.parent = parent; nicholas@2535: nickjillings@1385: // Generate Pre-Set dropdown nicholas@2390: var protoScales = interfaceSpecs.getAllElementsByTagName('scaledefinitions')[0].getElementsByTagName("scale"); nickjillings@1385: this.preset.input.innerHTML = ""; nicholas@2535: nicholas@2535: for (var i = 0; i < protoScales.length; i++) { nickjillings@1385: var selectOption = document.createElement("option"); nickjillings@1385: var scaleName = protoScales[i].getAttribute("name"); nicholas@2535: selectOption.setAttribute("name", scaleName); nickjillings@1385: selectOption.textContent = scaleName; nickjillings@1385: this.preset.input.appendChild(selectOption); nickjillings@1385: } nickjillings@2115: this.content.appendChild(this.addMarker.root); nicholas@2535: nickjillings@1385: // Create Marker List nickjillings@1385: this.buildMarkerList(); nickjillings@1385: } nicholas@2535: this.buildMarkerList = function () { nickjillings@1385: var markerInject = document.getElementById("popup-option-holder"); nickjillings@1385: markerInject.innerHTML = ""; nickjillings@1385: this.markerNodes = []; nicholas@2535: for (var i = 0; i < this.scaleRoot.scales.length; i++) { nicholas@2535: var markerNode = new this.buildMarkerNode(this, this.scaleRoot.scales[i]); nickjillings@1385: markerInject.appendChild(markerNode.root); nickjillings@1385: this.markerNodes.push(markerNode); nicholas@2535: nickjillings@1385: } nickjillings@1385: } nicholas@2535: nicholas@2535: this.buildMarkerNode = function (parent, specification) { nickjillings@2115: this.root = document.createElement("div"); nickjillings@2115: this.root.className = "popup-option-entry"; nickjillings@2115: this.positionInput = document.createElement("input"); nickjillings@2115: this.positionInput.min = 0; nickjillings@2115: this.positionInput.max = 100; nickjillings@2115: this.positionInput.value = specification.position; nicholas@2535: this.positionInput.setAttribute("name", "position"); nickjillings@2115: this.textInput = document.createElement("input"); nicholas@2535: this.textInput.setAttribute("name", "text"); nickjillings@2180: this.textInput.style.width = "300px"; nickjillings@2115: this.textInput.value = specification.text; nickjillings@2115: this.specification = specification; nickjillings@2115: this.parent = parent; nicholas@2535: this.handleEvent = function (event) { nicholas@2535: switch (event.currentTarget.getAttribute("name")) { nickjillings@2115: case "position": nickjillings@2115: this.specification.position = Number(event.currentTarget.value); nickjillings@2115: break; nickjillings@2115: case "text": nickjillings@2115: this.specification.text = event.currentTarget.value; nickjillings@2115: break; nickjillings@2115: } nickjillings@2115: } nicholas@2535: this.positionInput.addEventListener("change", this, false); nicholas@2535: this.textInput.addEventListener("change", this, false); nickjillings@2115: nickjillings@2115: var posText = document.createElement("span"); nickjillings@2115: posText.textContent = "Position: "; nickjillings@2115: var textText = document.createElement("span"); nickjillings@2115: textText.textContent = "Text: "; nickjillings@2115: this.root.appendChild(posText); nickjillings@2115: this.root.appendChild(this.positionInput); nickjillings@2115: this.root.appendChild(textText); nickjillings@2115: this.root.appendChild(this.textInput); nickjillings@2115: nickjillings@2115: this.deleteMarker = { nickjillings@2115: root: document.createElement("button"), nickjillings@2115: parent: this, nicholas@2535: handleEvent: function () { nicholas@2535: var index = this.parent.parent.scaleRoot.scales.findIndex(function (element, index, array) { nicholas@2535: if (element == this) { nicholas@2535: return true; nicholas@2535: } else { nicholas@2535: return false; nicholas@2535: } nicholas@2535: }, this.parent.specification) nickjillings@2115: if (index >= 0) { nicholas@2535: this.parent.parent.scaleRoot.scales.splice(index, 1); nickjillings@2115: } nickjillings@2115: document.getElementById("popup-option-holder").removeChild(this.parent.root); nickjillings@2115: } nickjillings@2115: } nicholas@2535: this.deleteMarker.root.addEventListener("click", this.deleteMarker); nickjillings@2115: this.deleteMarker.root.textContent = "Delete Marker" nickjillings@2115: this.root.appendChild(this.deleteMarker.root); nickjillings@2115: } nickjillings@1385: } nickjillings@1370: } nickjillings@1370: } nickjillings@1370: nicholas@2535: function SpecificationToHTML() { nickjillings@1370: // This takes the specification node and converts it to an on-page HTML object nickjillings@1370: // Each Specification Node is given its own JS object which listens to the XSD for instant verification nickjillings@1370: // Once generated, it directly binds into the specification object to update with changes nickjillings@1370: // Fixed DOM entries nickjillings@1370: this.injectDOM; nickjillings@1370: this.setupDOM; nickjillings@1370: this.pages = []; nicholas@2535: nickjillings@1370: // Self-contained generators nicholas@2535: this.createGeneralNodeDOM = function (name, id, parent) { nickjillings@1375: this.type = name; nickjillings@1370: var root = document.createElement('div'); nickjillings@1370: root.id = id; nickjillings@1370: root.className = "node"; nickjillings@1370: nickjillings@1370: var titleDiv = document.createElement('div'); nickjillings@1370: titleDiv.className = "node-title"; nickjillings@1370: var title = document.createElement('span'); nickjillings@1370: title.className = "node-title"; nickjillings@1370: title.textContent = name; nickjillings@1370: titleDiv.appendChild(title); nickjillings@1370: nickjillings@1370: var attributeDiv = document.createElement('div'); nickjillings@1370: attributeDiv.className = "node-attributes"; nickjillings@1370: nickjillings@1370: var childrenDiv = document.createElement('div'); nickjillings@1370: childrenDiv.className = "node-children"; nickjillings@1370: nickjillings@1370: var buttonsDiv = document.createElement('div'); nickjillings@1370: buttonsDiv.className = "node-buttons"; nickjillings@1370: nickjillings@1370: root.appendChild(titleDiv); nickjillings@1370: root.appendChild(attributeDiv); nickjillings@1370: root.appendChild(childrenDiv); nickjillings@1370: root.appendChild(buttonsDiv); nickjillings@1370: nickjillings@1370: var obj = { nickjillings@1370: rootDOM: root, nickjillings@1370: titleDOM: title, nickjillings@1370: attributeDOM: attributeDiv, nickjillings@1370: attributes: [], nickjillings@1370: childrenDOM: childrenDiv, nickjillings@1370: children: [], nickjillings@1370: buttonDOM: buttonsDiv, nickjillings@1370: parent: parent nickjillings@1370: } nickjillings@1370: return obj; nickjillings@1370: } nicholas@2535: nicholas@2535: this.convertAttributeToDOM = function (node, schema) { nickjillings@1370: // This takes an attribute schema node and returns an object with the input node and any bindings nicholas@2535: if (schema.getAttribute('name') == undefined && schema.getAttribute('ref') != undefined) { nicholas@2535: schema = specification.schema.getAllElementsByName(schema.getAttribute('ref'))[0]; nicholas@2535: } nicholas@2535: var obj = new function () { nickjillings@1370: this.input; nickjillings@1370: this.name; nickjillings@1370: this.owner; nickjillings@1370: this.holder; nicholas@2535: nickjillings@1370: this.name = schema.getAttribute('name'); nickjillings@1370: this.default = schema.getAttribute('default'); nickjillings@1370: this.dataType = schema.getAttribute('type'); nickjillings@2158: if (this.dataType == undefined) { nickjillings@2158: if (schema.childElementCount > 0) { nicholas@2390: if (schema.firstElementChild.nodeName == "xs:simpleType") { nickjillings@2158: this.dataType = schema.getAllElementsByTagName("xs:restriction")[0].getAttribute("base"); nickjillings@2158: } nickjillings@2158: } nickjillings@2158: } nicholas@2535: if (typeof this.dataType == "string") { nicholas@2535: this.dataType = this.dataType.substr(3); nicholas@2535: } else { nicholas@2535: this.dataType = "string"; nicholas@2535: } nickjillings@1370: var minVar = undefined; nickjillings@1370: var maxVar = undefined; nicholas@2535: switch (this.dataType) { nickjillings@1370: case "negativeInteger": nickjillings@1370: maxVar = -1; nickjillings@1370: break; nickjillings@1370: case "positiveInteger": nickjillings@1370: minVar = 1; nickjillings@1370: break; nickjillings@1370: case "nonNegativeInteger": nickjillings@1370: minVar = 0; nickjillings@1370: break; nickjillings@1370: case "nonPositiveInteger": nickjillings@1370: maxVar = 0; nickjillings@1370: break; nickjillings@1370: case "byte": nickjillings@1370: minVar = 0; nickjillings@1370: maxVar = 256; nickjillings@1370: break; nickjillings@1370: case "short": nickjillings@1370: minVar = 0; nickjillings@1370: maxVar = 65536; nickjillings@1370: break; nickjillings@1370: default: nickjillings@1370: break; nickjillings@1370: } nicholas@2535: nickjillings@2174: this.enumeration = schema.getAllElementsByTagName("xs:enumeration"); nickjillings@2174: if (this.enumeration.length == 0) { nickjillings@2174: this.input = document.createElement('input'); nicholas@2535: switch (this.dataType) { nickjillings@2174: case "boolean": nickjillings@2174: this.input.type = "checkbox"; nickjillings@2174: break; nickjillings@2174: case "negativeInteger": nickjillings@2174: case "positiveInteger": nickjillings@2174: case "nonNegativeInteger": nickjillings@2174: case "nonPositiveInteger": nickjillings@2174: case "integer": nickjillings@2174: case "short": nickjillings@2174: case "byte": nickjillings@2174: this.input.step = 1; nickjillings@2174: case "decimal": nickjillings@2174: this.input.type = "number"; nickjillings@2174: this.input.min = minVar; nickjillings@2174: this.input.max = maxVar; nickjillings@2174: break; nickjillings@2174: default: nickjillings@2174: break; nickjillings@2174: } nickjillings@2174: } else { nickjillings@2174: this.input = document.createElement("select"); nicholas@2535: for (var i = 0; i < this.enumeration.length; i++) { nickjillings@2174: var option = document.createElement("option"); nickjillings@2174: var value = this.enumeration[i].getAttribute("value"); nicholas@2535: option.setAttribute("value", value); nickjillings@2174: option.textContent = value; nickjillings@2174: this.input.appendChild(option); nickjillings@2174: } nickjillings@1370: } nickjillings@1370: var value; nicholas@2535: eval("value = node." + this.name) nicholas@2535: if (this.default != undefined && value == undefined) { nickjillings@2174: value = this.default; nickjillings@2174: } nickjillings@2174: if (this.input.type == "checkbox") { nicholas@2535: if (value == "true" || value == "True") { nicholas@2535: this.input.checked = false; nicholas@2535: } else { nicholas@2535: this.input.checked = false; nicholas@2535: } nickjillings@2174: } else { nickjillings@1370: this.input.value = value; nickjillings@1370: } nicholas@2535: this.handleEvent = function (event) { nickjillings@1370: var value; nicholas@2535: if (this.input.nodeName == "INPUT") { nicholas@2535: switch (this.input.type) { nickjillings@2174: case "checkbox": nickjillings@2174: value = event.currentTarget.checked; nickjillings@2174: break; nickjillings@2174: case "number": n@2423: if (event.currentTarget.value != "") { n@2423: value = Number(event.currentTarget.value); n@2423: } else { n@2423: value = undefined; n@2423: } nickjillings@2174: break; nickjillings@2174: default: n@2423: if (event.currentTarget.value != "") { n@2423: value = event.currentTarget.value; n@2423: } else { n@2423: value = undefined; n@2423: } nicholas@2535: break; nickjillings@2174: } nickjillings@2174: } else if (this.input.nodeName == "SELECT") { nickjillings@2174: value = event.currentTarget.value; nickjillings@1370: } nicholas@2535: eval("this.owner." + this.name + " = value"); nickjillings@1370: } nickjillings@1370: this.holder = document.createElement('div'); nickjillings@1370: this.holder.className = "attribute"; nicholas@2535: this.holder.setAttribute('name', this.name); nickjillings@1370: var text = document.createElement('span'); nicholas@2535: eval("text.textContent = attributeText." + this.name + "+': '"); nickjillings@1370: this.holder.appendChild(text); nickjillings@1370: this.holder.appendChild(this.input); nickjillings@1370: this.owner = node; nicholas@2535: this.input.addEventListener("change", this, false); nickjillings@1370: } nicholas@2535: if (obj.attribute != null) { nickjillings@1370: obj.input.value = obj.attribute; nickjillings@1370: } nickjillings@1370: return obj; nickjillings@1370: } nicholas@2535: nicholas@2535: this.convert = function (root) { nickjillings@1370: //Performs the actual conversion using the given root DOM as the root nickjillings@1370: this.injectDOM = root; nicholas@2535: nickjillings@1373: // Build the export button nickjillings@1373: var exportButton = document.createElement("button"); nickjillings@1373: exportButton.textContent = "Export to XML"; nicholas@2535: exportButton.onclick = function () { nickjillings@1373: var doc = specification.encode(); nickjillings@1373: var obj = {}; nickjillings@1373: obj.title = "Export"; nickjillings@1373: obj.content = document.createElement("div"); nickjillings@1373: obj.content.id = "finish"; nickjillings@1373: var span = document.createElement("span"); n@2405: span.textContent = "Your XML document is linked below. On most browsers, simply right click on the link and select 'Save As'. Or clicking on the link may download the file directly." n@2405: obj.content.appendChild(span); n@2405: span = document.createElement("p"); n@2405: span.textContent = "NOTE FOR SAFARI! You cannot right click on the below link and save it as a file, Safari does not like that at all. Instead click on it to open the XML, the Press Cmd+S to open the save dialogue. Make sure you have 'save as Page Source' selected on the bottom of the window. Currently Safari has no plans to support the HTML 'download' attribute which causes this problem"; nickjillings@1373: obj.content.appendChild(span); nickjillings@1373: var link = document.createElement("div"); n@2412: link.appendChild(doc.firstChild); nickjillings@1373: var file = [link.innerHTML]; nicholas@2535: var bb = new Blob(file, { nicholas@2535: type: 'application/xml' nicholas@2535: }); nickjillings@1373: var dnlk = window.URL.createObjectURL(bb); nickjillings@1373: var a = document.createElement("a"); nickjillings@1373: a.hidden = ''; nickjillings@1373: a.href = dnlk; nickjillings@1373: a.download = "project-specification.xml"; nickjillings@1373: a.textContent = "Save File"; nickjillings@1373: obj.content.appendChild(a); nickjillings@1373: popupObject.show(); nickjillings@1373: popupObject.postNode(obj); nickjillings@1373: } nickjillings@1373: this.injectDOM.appendChild(exportButton); nicholas@2535: nickjillings@1370: // First perform the setupNode; nickjillings@1370: var setupSchema = specification.schema.getAllElementsByName('setup')[0]; nicholas@2535: this.setupDOM = new this.createGeneralNodeDOM('Global Configuration', 'setup', null); nickjillings@1370: this.injectDOM.appendChild(this.setupDOM.rootDOM); nickjillings@1370: var setupAttributes = setupSchema.getAllElementsByTagName('xs:attribute'); nicholas@2535: for (var i = 0; i < setupAttributes.length; i++) { nickjillings@1370: var attributeName = setupAttributes[i].getAttribute('name'); nicholas@2535: var attrObject = this.convertAttributeToDOM(specification, setupAttributes[i]); nickjillings@1370: this.setupDOM.attributeDOM.appendChild(attrObject.holder); nickjillings@1370: this.setupDOM.attributes.push(attrObject); nickjillings@1370: } nicholas@2535: nickjillings@2179: // Build the exit Text node nicholas@2535: var exitText = new this.createGeneralNodeDOM("Exit Text", "exit-test", this.setupDOM); nickjillings@2179: exitText.rootDOM.removeChild(exitText.attributeDOM); nickjillings@2179: this.setupDOM.children.push(exitText); nickjillings@2179: this.setupDOM.childrenDOM.appendChild(exitText.rootDOM); nickjillings@2179: var obj = { nickjillings@2179: rootDOM: document.createElement("div"), nickjillings@2179: labelDOM: document.createElement("label"), nickjillings@2179: inputDOM: document.createElement("textarea"), nickjillings@2179: parent: exitText, nickjillings@2179: specification: specification, nicholas@2535: handleEvent: function (event) { nickjillings@2179: this.specification.exitText = this.inputDOM.value; nickjillings@2179: } nickjillings@2179: } b@2367: var exitWarning = document.createElement("div"); b@2367: obj.rootDOM.appendChild(exitWarning); b@2367: exitWarning.textContent = "Only visible when the above 'On complete redirect URL' field is empty."; nickjillings@2179: obj.rootDOM.appendChild(obj.labelDOM); nickjillings@2179: obj.rootDOM.appendChild(obj.inputDOM); nickjillings@2179: obj.labelDOM.textContent = "Text: "; nickjillings@2179: obj.inputDOM.value = obj.specification.exitText; nicholas@2535: obj.inputDOM.addEventListener("change", obj); nickjillings@2179: exitText.children.push(obj); nickjillings@2179: exitText.childrenDOM.appendChild(obj.rootDOM); nicholas@2535: nickjillings@1370: // Now we must build the interface Node nicholas@2535: this.interfaceDOM = new this.interfaceNode(this, specification.interfaces); nicholas@2535: this.interfaceDOM.build("Interface", "setup-interface", this.setupDOM.rootDOM); nicholas@2535: nickjillings@1370: // Now build the Metrics selection node nicholas@2535: var metric = this.createGeneralNodeDOM("Session Metrics", "setup-metric", this.setupDOM); nickjillings@1370: metric.rootDOM.removeChild(metric.attributeDOM); nickjillings@1370: this.setupDOM.children.push(metric); nickjillings@1370: this.setupDOM.childrenDOM.appendChild(metric.rootDOM); nickjillings@1370: var interfaceName = popupStateNodes.state[1].select.value; nickjillings@1370: var checkText = interfaceSpecs.getElementsByTagName("global")[0].getAllElementsByTagName("metrics")[0]; nickjillings@1370: var testXML = interfaceSpecs.getElementsByTagName("tests")[0].getAllElementsByName(interfaceName)[0]; nickjillings@1370: var interfaceXML = interfaceSpecs.getAllElementsByTagName("interfaces")[0].getAllElementsByName(testXML.getAttribute("interface"))[0].getAllElementsByTagName("metrics")[0]; nickjillings@1370: testXML = testXML.getAllElementsByTagName("metrics"); nicholas@2390: var interfaceXMLChild = interfaceXML.firstElementChild; nicholas@2535: while (interfaceXMLChild) { nickjillings@1370: var obj = { nickjillings@1370: input: document.createElement('input'), nickjillings@1370: root: document.createElement('div'), nickjillings@1370: text: document.createElement('span'), nickjillings@1370: specification: specification.metrics.enabled, nicholas@2390: name: interfaceXMLChild.getAttribute("name"), nicholas@2535: handleEvent: function () { nicholas@2535: for (var i = 0; i < this.specification.length; i++) { nicholas@2535: if (this.specification[i] == this.name) { nickjillings@1370: var options = this.specification; nickjillings@1370: if (this.input.checked == false) { nicholas@2535: if (i == options.length) { nicholas@2535: options = options.slice(0, i); nicholas@2535: } else { nicholas@2535: options = options.slice(0, i).concat(options.slice(i + 1)); nickjillings@1370: } nickjillings@1370: } else { nickjillings@1370: return; nickjillings@1370: } nickjillings@1370: this.specification = options; nickjillings@1370: break; nickjillings@1370: } nickjillings@1370: } nickjillings@1370: if (this.input.checked) { nickjillings@1370: this.specification.push(this.name); nickjillings@1370: } nickjillings@1370: } nickjillings@1370: }; nickjillings@1370: obj.root.className = "attribute"; nickjillings@1370: obj.input.type = "checkbox"; nickjillings@1370: obj.root.appendChild(obj.text); nickjillings@1370: obj.root.appendChild(obj.input); nicholas@2390: obj.text.textContent = checkText.getAllElementsByName(interfaceXMLChild.getAttribute("name"))[0].textContent; nickjillings@1370: metric.children.push(obj); nickjillings@1370: metric.childrenDOM.appendChild(obj.root); nicholas@2535: for (var j = 0; j < specification.metrics.enabled.length; j++) { nicholas@2535: if (specification.metrics.enabled[j] == obj.name) { nickjillings@1370: obj.input.checked = true; nickjillings@1370: break; nickjillings@1370: } nickjillings@1370: } nicholas@2390: interfaceXMLChild = interfaceXMLChild.nextElementSibling; nickjillings@1370: } nicholas@2535: nickjillings@1370: // Now both before and after surveys nicholas@2535: if (specification.preTest == undefined) { nickjillings@2194: specification.preTest = new specification.surveyNode(specification); nickjillings@1370: specification.preTest.location = "pre"; nickjillings@1370: } nicholas@2535: if (specification.postTest == undefined) { nickjillings@2194: specification.postTest = new specification.surveyNode(specification); nickjillings@1370: specification.postTest.location = "post"; nickjillings@1370: } nicholas@2535: var surveyBefore = new this.surveyNode(this, specification.preTest, "Pre"); nicholas@2535: var surveyAfter = new this.surveyNode(this, specification.postTest, "Post"); nickjillings@1370: this.setupDOM.children.push(surveyBefore); nickjillings@1370: this.setupDOM.children.push(surveyAfter); nickjillings@1370: this.setupDOM.childrenDOM.appendChild(surveyBefore.rootDOM); nickjillings@1370: this.setupDOM.childrenDOM.appendChild(surveyAfter.rootDOM); nicholas@2535: nickjillings@1370: // Add in the page creator button nickjillings@1370: this.addPage = { nickjillings@1370: root: document.createElement("button"), nickjillings@1370: parent: this, nicholas@2535: handleEvent: function () { nickjillings@2194: var pageObj = new specification.page(specification); nickjillings@1370: specification.pages.push(pageObj); nicholas@2535: var newPage = new this.parent.pageNode(this.parent, pageObj); nicholas@2315: document.getElementById("page-holder").appendChild(newPage.rootDOM); nickjillings@1370: this.parent.pages.push(newPage); nickjillings@1370: } nickjillings@1370: } nickjillings@1370: this.addPage.root.textContent = "Add Page"; nicholas@2315: this.addPage.root.id = "new-page-button"; nicholas@2315: this.addPage.root.style.float = "left"; nicholas@2535: this.addPage.root.addEventListener("click", this.addPage, false); nicholas@2535: nicholas@2315: var pageHolder = document.createElement("div"); nicholas@2535: pageHolder.id = "page-holder"; nicholas@2315: this.injectDOM.appendChild(pageHolder); nicholas@2535: nickjillings@1374: // Build each page nicholas@2535: for (var page of specification.pages) { nicholas@2535: var newPage = new this.pageNode(this, page); nicholas@2315: pageHolder.appendChild(newPage.rootDOM); nickjillings@1374: this.pages.push(newPage); nickjillings@1374: } nicholas@2535: nicholas@2315: this.injectDOM.appendChild(this.addPage.root); nickjillings@1370: } nicholas@2535: nicholas@2535: this.interfaceNode = function (parent, rootObject) { nickjillings@1375: this.type = "interfaceNode"; nickjillings@1370: this.rootDOM; nickjillings@1370: this.titleDOM; nickjillings@1370: this.attributeDOM; nickjillings@1370: this.attributes = []; nickjillings@1370: this.childrenDOM; nickjillings@1370: this.children = []; nickjillings@1370: this.buttonDOM; nickjillings@1370: this.parent = parent; nickjillings@1370: this.HTMLPoint; nickjillings@1370: this.specification = rootObject; nickjillings@1370: this.schema = specification.schema.getAllElementsByName("interface")[1]; nicholas@2535: nicholas@2535: this.createIOasAttr = function (name, specification, parent, type) { nickjillings@1370: this.root = document.createElement('div'); nickjillings@1370: this.input = document.createElement("input"); nickjillings@1370: this.name = name; nickjillings@1370: this.type = type; nickjillings@1370: this.parent = parent; nickjillings@1370: this.specification = specification; nicholas@2535: this.handleEvent = function (event) { nicholas@2535: for (var i = 0; i < this.specification.options.length; i++) { nicholas@2535: if (this.specification.options[i].name == this.name) { nickjillings@1370: var options = this.specification.options; nickjillings@1370: if (this.input.checked == false) { nicholas@2535: if (i == options.length) { nicholas@2535: options = options.slice(0, i); nicholas@2535: } else { nicholas@2535: options = options.slice(0, i).concat(options.slice(i + 1)); nickjillings@1370: } nickjillings@1370: } else { nickjillings@1370: return; nickjillings@1370: } nickjillings@1370: this.specification.options = options; nickjillings@1370: break; nickjillings@1370: } nickjillings@1370: } nickjillings@1370: if (this.input.checked) { nickjillings@1370: var obj = { nickjillings@1370: name: this.name, nickjillings@1370: type: this.type nickjillings@1370: }; nickjillings@1370: this.specification.options.push(obj); nickjillings@1370: } nicholas@2535: if (this.parent.HTMLPoint.id == "setup") { nickjillings@1370: // We've changed a global setting, must update all child 'interfaces' and disable them nicholas@2535: for (pages of convert.pages) { nicholas@2535: for (interface of pages.interfaces) { nicholas@2535: if (this.type == "check") { nicholas@2535: for (node of interface.children[0].attributes) { nickjillings@1370: if (node.name == this.name) { nickjillings@1370: if (this.input.checked) { nickjillings@1370: node.input.disabled = true; nickjillings@1370: node.input.checked = false; nickjillings@1370: } else { nickjillings@1370: node.input.disabled = false; nickjillings@1370: } nickjillings@1370: break; nickjillings@1370: } nickjillings@1370: } nicholas@2535: } else if (this.type == "show") { nicholas@2535: for (node of interface.children[1].attributes) { nickjillings@1370: if (node.name == this.name) { nickjillings@1370: if (this.input.checked) { nickjillings@1370: node.input.disabled = true; nickjillings@1370: } else { nickjillings@1370: node.input.disabled = false; nickjillings@1370: } nickjillings@1370: break; nickjillings@1370: } nickjillings@1370: } nickjillings@1370: } nickjillings@1370: } nickjillings@1370: } nickjillings@1370: } nickjillings@1370: }; nicholas@2535: this.findIndex = function (element, index, array) { nickjillings@1370: if (element.name == this.name) nickjillings@1370: return true; nickjillings@1370: else nickjillings@1370: return false; nickjillings@1370: }; nicholas@2535: this.findNode = function (element, index, array) { nickjillings@1370: if (element.name == this.name) nickjillings@1370: return true; nickjillings@1370: else nickjillings@1370: return false; nickjillings@1370: }; nickjillings@1370: this.input.type = "checkbox"; nicholas@2535: this.input.setAttribute("name", name); nicholas@2535: this.input.addEventListener("change", this, false); nickjillings@1370: this.root.appendChild(this.input); nickjillings@1370: this.root.className = "attribute"; nickjillings@1370: return this; nickjillings@1370: } nicholas@2535: nicholas@2535: this.build = function (name, id, parent) { nicholas@2535: var obj = this.parent.createGeneralNodeDOM(name, id, parent); nicholas@2535: nickjillings@1370: this.rootDOM = obj.rootDOM; nickjillings@1370: this.titleDOM = obj.titleDOM; nickjillings@1370: this.attributeDOM = obj.attributeDOM; nickjillings@1370: this.childrenDOM = obj.childrenDOM; nickjillings@1370: this.buttonDOM = obj.buttonsDOM; nickjillings@1370: this.HTMLPoint = parent; nickjillings@1370: this.rootDOM.removeChild(this.attributeDOM); nicholas@2243: if (parent.id != "setup") { nicholas@2243: // Put in the node: nicholas@2243: this.titleNode = { nicholas@2243: root: document.createElement("div"), nicholas@2243: label: document.createElement("span"), nicholas@2243: input: document.createElement("input"), nicholas@2243: parent: this, nicholas@2535: handleEvent: function (event) { nicholas@2243: this.parent.specification.title = event.currentTarget.value; nicholas@2243: } nicholas@2243: } nicholas@2549: this.titleNode.label.textContent = "Presented Axis Title:"; nicholas@2243: this.titleNode.root.className = "node-children"; nicholas@2243: this.titleNode.root.appendChild(this.titleNode.label); nicholas@2243: this.titleNode.root.appendChild(this.titleNode.input); nicholas@2535: this.titleNode.input.addEventListener("change", this.titleNode, false); nicholas@2243: this.titleNode.input.value = this.specification.title; nicholas@2243: this.children.push(this.titleNode); nicholas@2243: this.childrenDOM.appendChild(this.titleNode.root); nicholas@2549: // Set the interface-name attribute nicholas@2549: this.axisName = { nicholas@2549: root: document.createElement("div"), nicholas@2549: label: document.createElement("span"), nicholas@2549: input: document.createElement("input"), nicholas@2549: parent: this, nicholas@2549: handleEvent: function (event) { nicholas@2549: this.parent.specification.name = event.currentTarget.value; nicholas@2549: } nicholas@2549: } nicholas@2549: this.axisName.label.textContent = "Saved Axis Name (no spaces):"; nicholas@2549: this.axisName.root.className = "node-children"; nicholas@2549: this.axisName.root.appendChild(this.axisName.label); nicholas@2549: this.axisName.root.appendChild(this.axisName.input); nicholas@2549: this.axisName.input.addEventListener("change", this.axisName, false); nicholas@2549: this.axisName.input.value = this.specification.name; nicholas@2549: this.children.push(this.axisName); nicholas@2549: this.childrenDOM.appendChild(this.axisName.root); nicholas@2243: } nicholas@2535: nickjillings@1370: // Put in the check / show options as individual children nicholas@2535: var checks = this.parent.createGeneralNodeDOM("Checks", "setup-interface-checks", this); nickjillings@1370: nickjillings@1370: var interfaceName = popupStateNodes.state[1].select.value; nickjillings@1370: var checkText = interfaceSpecs.getElementsByTagName("global")[0].getAllElementsByTagName("checks")[0]; nickjillings@1370: var testXML = interfaceSpecs.getElementsByTagName("tests")[0].getAllElementsByName(interfaceName)[0]; nickjillings@1370: var interfaceXML = interfaceSpecs.getAllElementsByTagName("interfaces")[0].getAllElementsByName(testXML.getAttribute("interface"))[0].getAllElementsByTagName("checks")[0]; nickjillings@1370: testXML = testXML.getAllElementsByTagName("checks"); nicholas@2390: var interfaceXMLChild = interfaceXML.firstElementChild; nicholas@2535: while (interfaceXMLChild) { nicholas@2535: var obj = new this.createIOasAttr(interfaceXMLChild.getAttribute("name"), this.specification, this, "check"); nicholas@2535: for (var option of this.specification.options) { nicholas@2535: if (option.name == obj.name) { nickjillings@1370: obj.input.checked = true; nickjillings@1370: break; nickjillings@1370: } nickjillings@1370: } nickjillings@1370: if (parent.id != "setup") { nicholas@2535: var node = convert.interfaceDOM.children[0].attributes.find(obj.findNode, obj); nickjillings@1381: if (node != undefined) { nickjillings@1381: if (node.input.checked) { nickjillings@1381: obj.input.checked = false; nickjillings@1381: obj.input.disabled = true; nickjillings@1381: } nickjillings@1370: } nickjillings@1370: } nickjillings@1370: var text = document.createElement('span'); nicholas@2390: text.textContent = checkText.getAllElementsByName(interfaceXMLChild.getAttribute("name"))[0].textContent; nickjillings@1370: obj.root.appendChild(text); nickjillings@1370: checks.attributeDOM.appendChild(obj.root); nickjillings@1370: checks.attributes.push(obj); nicholas@2390: interfaceXMLChild = interfaceXMLChild.nextElementSibling; nickjillings@1370: } nickjillings@1370: this.children.push(checks); nickjillings@1370: this.childrenDOM.appendChild(checks.rootDOM); nickjillings@1370: nicholas@2535: var show = this.parent.createGeneralNodeDOM("Show", "setup-interface-show", this); nickjillings@1370: interfaceName = popupStateNodes.state[1].select.value; nickjillings@1370: checkText = interfaceSpecs.getElementsByTagName("global")[0].getAllElementsByTagName("show")[0]; nickjillings@1370: testXML = interfaceSpecs.getElementsByTagName("tests")[0].getAllElementsByName(interfaceName)[0]; nickjillings@1370: interfaceXML = interfaceSpecs.getAllElementsByTagName("interfaces")[0].getAllElementsByName(testXML.getAttribute("interface"))[0].getAllElementsByTagName("show")[0]; nickjillings@1370: testXML = testXML.getAllElementsByTagName("show"); nicholas@2390: interfaceXMLChild = interfaceXML.firstElementChild; nicholas@2535: while (interfaceXMLChild) { nicholas@2535: var obj = new this.createIOasAttr(interfaceXMLChild.getAttribute("name"), this.specification, this, "show"); nicholas@2535: for (var option of this.specification.options) { nicholas@2535: if (option.name == obj.name) { nickjillings@1370: obj.input.checked = true; nickjillings@1370: break; nickjillings@1370: } nickjillings@1370: } nickjillings@1370: if (parent.id != "setup") { nicholas@2535: var node = convert.interfaceDOM.children[0].attributes.find(obj.findNode, obj); nickjillings@1381: if (node != undefined) { nickjillings@1381: if (node.input.checked) { nickjillings@1381: obj.input.checked = false; nickjillings@1381: obj.input.disabled = true; nickjillings@1381: } nickjillings@1370: } nickjillings@1370: } nickjillings@1370: var text = document.createElement('span'); nicholas@2390: text.textContent = checkText.getAllElementsByName(interfaceXMLChild.getAttribute("name"))[0].textContent; nickjillings@1370: obj.root.appendChild(text); nickjillings@1370: show.attributeDOM.appendChild(obj.root); nickjillings@1370: show.attributes.push(obj); nicholas@2390: interfaceXMLChild = interfaceXMLChild.nextElementSibling; nickjillings@1370: } nickjillings@1370: this.children.push(show); nickjillings@1370: this.childrenDOM.appendChild(show.rootDOM); nicholas@2535: nicholas@2535: if (parent.id == "setup") {} else { nicholas@2535: var nameAttr = this.parent.convertAttributeToDOM(this, specification.schema.getAllElementsByName("name")[0]); nickjillings@1370: this.attributeDOM.appendChild(nameAttr.holder); nickjillings@1370: this.attributes.push(nameAttr); nicholas@2535: var scales = new this.scalesNode(this, this.specification); nickjillings@1385: this.children.push(scales); nickjillings@1385: this.childrenDOM.appendChild(scales.rootDOM); nickjillings@1370: } nicholas@2535: if (parent != undefined) { nickjillings@1370: parent.appendChild(this.rootDOM); nickjillings@1370: } nickjillings@1370: } nicholas@2535: nicholas@2535: this.scalesNode = function (parent, rootObject) { nickjillings@1385: this.type = "scalesNode"; nickjillings@1385: this.rootDOM = document.createElement("div"); nickjillings@1385: this.titleDOM = document.createElement("span"); nickjillings@1385: this.attributeDOM = document.createElement("div"); nickjillings@1385: this.attributes = []; nickjillings@1385: this.childrenDOM = document.createElement("div"); nickjillings@1385: this.children = []; nickjillings@1385: this.buttonDOM = document.createElement("div"); nickjillings@1385: this.parent = parent; nickjillings@1385: this.specification = rootObject; nickjillings@1385: this.schema = specification.schema.getAllElementsByName("page")[0]; nickjillings@1385: this.rootDOM.className = "node"; nickjillings@1385: nickjillings@1385: var titleDiv = document.createElement('div'); nickjillings@1385: titleDiv.className = "node-title"; nickjillings@1385: this.titleDOM.className = "node-title"; nickjillings@1385: this.titleDOM.textContent = "Interface Scales"; nickjillings@1385: titleDiv.appendChild(this.titleDOM); nickjillings@1385: nickjillings@1385: this.attributeDOM.className = "node-attributes"; nickjillings@1385: this.childrenDOM.className = "node-children"; nickjillings@1385: this.buttonDOM.className = "node-buttons"; nickjillings@1385: nickjillings@1385: this.rootDOM.appendChild(titleDiv); nickjillings@1385: this.rootDOM.appendChild(this.attributeDOM); nickjillings@1385: this.rootDOM.appendChild(this.childrenDOM); nickjillings@1385: this.rootDOM.appendChild(this.buttonDOM); nicholas@2535: nickjillings@1385: this.editButton = { nickjillings@1385: button: document.createElement("button"), nickjillings@1385: parent: this, nicholas@2535: handleEvent: function (event) { nickjillings@1385: popupObject.show(); nickjillings@1385: popupObject.postNode(popupStateNodes.state[6]); nicholas@2535: popupStateNodes.state[6].generate(this.parent.specification, this.parent); nickjillings@1385: } nickjillings@1385: }; nickjillings@1385: this.editButton.button.textContent = "Edit Scales/Markers"; nicholas@2535: this.editButton.button.addEventListener("click", this.editButton, false); nickjillings@1385: this.buttonDOM.appendChild(this.editButton.button); nickjillings@1385: } nickjillings@1370: } nicholas@2535: nicholas@2535: this.surveyNode = function (parent, rootObject, location) { nickjillings@1375: this.type = "surveyNode"; nickjillings@1370: this.rootDOM = document.createElement("div"); nickjillings@1370: this.titleDOM = document.createElement("span"); nickjillings@1370: this.attributeDOM = document.createElement("div"); nickjillings@1370: this.attributes = []; nickjillings@1370: this.childrenDOM = document.createElement("div"); nickjillings@1370: this.children = []; nickjillings@1370: this.buttonDOM = document.createElement("div"); nickjillings@1370: this.parent = parent; nickjillings@1370: this.specification = rootObject; nickjillings@1370: this.schema = specification.schema.getAllElementsByName("survey")[1]; nickjillings@1370: this.rootDOM.className = "node"; nickjillings@1370: nickjillings@1370: var titleDiv = document.createElement('div'); nickjillings@1370: titleDiv.className = "node-title"; nickjillings@1370: this.titleDOM.className = "node-title"; nickjillings@1370: this.titleDOM.textContent = "Survey"; nickjillings@1370: titleDiv.appendChild(this.titleDOM); nicholas@2535: nickjillings@1370: this.attributeDOM.className = "node-attributes"; nickjillings@1370: var locationAttr = document.createElement("span"); nickjillings@1370: this.attributeDOM.appendChild(locationAttr); nickjillings@1370: if (location == "Pre" || location == "pre") { nickjillings@1370: locationAttr.textContent = "Location: Before"; nickjillings@1370: } else { nickjillings@1370: locationAttr.textContent = "Location: After"; nickjillings@1370: } nickjillings@1370: this.childrenDOM.className = "node-children"; nickjillings@1370: this.buttonDOM.className = "node-buttons"; nickjillings@1370: nickjillings@1370: this.rootDOM.appendChild(titleDiv); nickjillings@1370: this.rootDOM.appendChild(this.attributeDOM); nickjillings@1370: this.rootDOM.appendChild(this.childrenDOM); nickjillings@1370: this.rootDOM.appendChild(this.buttonDOM); nicholas@2535: nicholas@2535: this.surveyEntryNode = function (parent, rootObject) { nickjillings@1375: this.type = "surveyEntryNode"; nickjillings@1370: this.rootDOM = document.createElement("div"); nickjillings@1370: this.titleDOM = document.createElement("span"); nickjillings@1370: this.attributeDOM = document.createElement("div"); nickjillings@1370: this.attributes = []; nickjillings@1370: this.childrenDOM = document.createElement("div"); nickjillings@1370: this.children = []; nickjillings@1370: this.buttonDOM = document.createElement("div"); nickjillings@1370: this.parent = parent; nickjillings@1370: this.specification = rootObject; nickjillings@1370: this.schema = specification.schema.getAllElementsByName("surveyentry")[1]; nickjillings@1370: nickjillings@1370: this.rootDOM.className = "node"; nickjillings@1370: this.rootDOM.style.minWidth = "50%"; nickjillings@1370: nickjillings@1370: var titleDiv = document.createElement('div'); nickjillings@1370: titleDiv.className = "node-title"; nickjillings@1370: this.titleDOM.className = "node-title"; nickjillings@1370: titleDiv.appendChild(this.titleDOM); nickjillings@1370: nickjillings@1370: this.attributeDOM.className = "node-attributes"; nickjillings@1370: this.childrenDOM.className = "node-children"; nickjillings@1370: this.buttonDOM.className = "node-buttons"; nickjillings@1370: nickjillings@1370: this.rootDOM.appendChild(titleDiv); nickjillings@1370: this.rootDOM.appendChild(this.attributeDOM); nickjillings@1370: this.rootDOM.appendChild(this.childrenDOM); nickjillings@1370: this.rootDOM.appendChild(this.buttonDOM); nicholas@2535: nicholas@2535: this.build = function () { nickjillings@1375: this.attributeDOM.innerHTML = null; nickjillings@1375: this.childrenDOM.innerHTML = null; nickjillings@1375: var statementRoot = document.createElement("div"); nickjillings@1375: var statement = document.createElement("span"); nicholas@2535: statement.textContent = "Statement / Question: " + this.specification.statement; nickjillings@1375: statementRoot.appendChild(statement); nickjillings@1375: this.children.push(statementRoot); nickjillings@1375: this.childrenDOM.appendChild(statementRoot); nicholas@2535: switch (this.specification.type) { nickjillings@1375: case "statement": nickjillings@1375: this.titleDOM.textContent = "Statement"; nickjillings@1375: break; nickjillings@1375: case "question": nickjillings@1375: this.titleDOM.textContent = "Question"; nicholas@2535: var id = convert.convertAttributeToDOM(this.specification, specification.schema.getAllElementsByName("id")[0]); nicholas@2535: var mandatory = convert.convertAttributeToDOM(this.specification, specification.schema.getAllElementsByName("mandatory")[0]); nicholas@2535: var boxsize = convert.convertAttributeToDOM(this.specification, specification.schema.getAllElementsByName("boxsize")[0]); nickjillings@1375: this.attributeDOM.appendChild(id.holder); nickjillings@1375: this.attributes.push(id); nickjillings@1375: this.attributeDOM.appendChild(mandatory.holder); nickjillings@1375: this.attributes.push(mandatory); nickjillings@1375: this.attributeDOM.appendChild(boxsize.holder); nickjillings@1375: this.attributes.push(boxsize); nickjillings@1375: break; nickjillings@1375: case "number": nickjillings@1375: this.titleDOM.textContent = "Number"; nicholas@2535: var id = convert.convertAttributeToDOM(this.specification, specification.schema.getAllElementsByName("id")[0]); nicholas@2535: var mandatory = convert.convertAttributeToDOM(this.specification, specification.schema.getAllElementsByName("mandatory")[0]); nicholas@2535: var min = convert.convertAttributeToDOM(this.specification, specification.schema.getAllElementsByName("min")[0]); nicholas@2535: var max = convert.convertAttributeToDOM(this.specification, specification.schema.getAllElementsByName("max")[0]); nickjillings@1375: this.attributeDOM.appendChild(id.holder); nickjillings@1375: this.attributes.push(id); nickjillings@1375: this.attributeDOM.appendChild(min.holder); nickjillings@1375: this.attributes.push(min); nickjillings@1375: this.attributeDOM.appendChild(max.holder); nickjillings@1375: this.attributes.push(max); nickjillings@1375: break; nickjillings@1375: case "checkbox": nickjillings@1375: this.titleDOM.textContent = "Checkbox"; nicholas@2535: var id = convert.convertAttributeToDOM(this.specification, specification.schema.getAllElementsByName("id")[0]); nickjillings@1375: this.attributeDOM.appendChild(id.holder); nickjillings@1375: this.attributes.push(id); nickjillings@1375: break; nickjillings@1375: case "radio": nickjillings@1375: this.titleDOM.textContent = "Radio"; nicholas@2535: var id = convert.convertAttributeToDOM(this.specification, specification.schema.getAllElementsByName("id")[0]); nickjillings@1375: this.attributeDOM.appendChild(id.holder); nickjillings@1375: this.attributes.push(id); nickjillings@1375: break; nickjillings@1375: } nickjillings@1370: } nickjillings@1375: this.build(); nicholas@2535: nickjillings@1370: this.editNode = { nickjillings@1370: root: document.createElement("button"), nickjillings@1370: parent: this, nicholas@2535: handleEvent: function () { nickjillings@1370: popupObject.show(); nicholas@2535: popupStateNodes.state[5].generate(this.parent.specification, this.parent); nickjillings@1370: popupObject.postNode(popupStateNodes.state[5]); nickjillings@1370: } nickjillings@1370: } nickjillings@1370: this.editNode.root.textContent = "Edit Entry"; nicholas@2535: this.editNode.root.addEventListener("click", this.editNode, false); nickjillings@1370: this.buttonDOM.appendChild(this.editNode.root); nicholas@2535: nickjillings@1370: this.deleteNode = { nickjillings@1370: root: document.createElement("button"), nickjillings@1370: parent: this, nicholas@2535: handleEvent: function () { nickjillings@1370: var optionList = this.parent.parent.specification.options; nickjillings@1370: var childList = this.parent.parent.children; nicholas@2535: for (var i = 0; i < this.parent.parent.specification.options.length; i++) { nickjillings@1370: var option = this.parent.parent.specification.options[i]; nicholas@2535: if (option == this.parent.specification) { nickjillings@1370: this.parent.parent.childrenDOM.removeChild(this.parent.rootDOM); nicholas@2535: if (i == this.parent.parent.specification.options.length - 1) { nicholas@2535: optionList = optionList.slice(0, i); nicholas@2535: childList = childList.slice(0, i); nicholas@2535: } else { nicholas@2535: optionList = optionList.slice(0, i).concat(optionList.slice(i + 1)); nicholas@2535: childList = childList.slice(0, i).concat(childList.slice(i + 1)); nickjillings@1370: } nickjillings@1370: this.parent.parent.specification.options = optionList; nickjillings@1370: this.parent.parent.children = childList; nickjillings@1370: } nickjillings@1370: } nickjillings@1370: } nickjillings@1370: } nickjillings@1370: this.deleteNode.root.textContent = "Delete Entry"; nicholas@2535: this.deleteNode.root.addEventListener("click", this.deleteNode, false); nickjillings@1370: this.buttonDOM.appendChild(this.deleteNode.root); nicholas@2535: nicholas@2535: this.moveToPosition = function (new_index) { nicholas@2535: new_index = Math.min(new_index, this.parent.children.length); nicholas@2535: var curr_index = this.parent.children.findIndex(function (elem) { nicholas@2535: if (elem == this) { nicholas@2535: return true; nicholas@2535: } else { nicholas@2535: return false; nicholas@2535: } nicholas@2535: }, this); n@2416: // Split at the current location to remove the node and shift all the children up nicholas@2535: var tail = this.parent.children.splice(curr_index + 1); n@2416: this.parent.children.pop(); n@2416: this.parent.children = this.parent.children.concat(tail); nicholas@2535: n@2416: //Split at the new location and insert the node n@2416: tail = this.parent.children.splice(new_index); n@2416: this.parent.children.push(this); n@2416: this.parent.children = this.parent.children.concat(tail); nicholas@2535: n@2416: // Re-build the specification n@2416: this.parent.specification.options = []; n@2416: this.parent.childrenDOM.innerHTML = ""; n@2416: for (var obj of this.parent.children) { n@2416: this.parent.specification.options.push(obj.specification); n@2416: this.parent.childrenDOM.appendChild(obj.rootDOM); n@2416: } nicholas@2535: this.parent.children.forEach(function (obj, index) { n@2420: obj.moveButtons.disable(index); n@2420: }); n@2414: } nicholas@2535: n@2420: this.moveButtons = { n@2420: root_up: document.createElement("button"), n@2420: root_down: document.createElement("button"), n@2420: parent: this, nicholas@2535: handleEvent: function (event) { n@2420: var index = this.parent.parent.children.indexOf(this.parent); n@2420: if (event.currentTarget.getAttribute("direction") == "up") { nicholas@2535: index = Math.max(index - 1, 0); n@2420: } else if (event.currentTarget.getAttribute("direction") == "down") { nicholas@2535: index = Math.min(index + 1, this.parent.parent.children.length - 1); n@2420: } n@2420: this.parent.moveToPosition(index); n@2420: this.disable(index); n@2420: }, nicholas@2535: disable: function (index) { n@2420: if (index == 0) { n@2420: this.root_up.disabled = true; n@2420: } else { n@2420: this.root_up.disabled = false; n@2420: } nicholas@2535: if (index == this.parent.parent.children.length - 1) { n@2420: this.root_down.disabled = true; n@2420: } else { n@2420: this.root_down.disabled = false; n@2420: } n@2420: } n@2420: } nicholas@2535: this.moveButtons.root_up.setAttribute("direction", "up"); nicholas@2535: this.moveButtons.root_down.setAttribute("direction", "down"); nicholas@2535: this.moveButtons.root_up.addEventListener("click", this.moveButtons, false); nicholas@2535: this.moveButtons.root_down.addEventListener("click", this.moveButtons, false); n@2420: this.moveButtons.root_up.textContent = "Move Up"; n@2420: this.moveButtons.root_down.textContent = "Move Down"; n@2420: this.buttonDOM.appendChild(this.moveButtons.root_up); n@2420: this.buttonDOM.appendChild(this.moveButtons.root_down); nickjillings@1370: } nickjillings@1370: this.addNode = { nickjillings@1370: root: document.createElement("button"), nickjillings@1370: parent: this, nicholas@2535: handleEvent: function () { nickjillings@2194: var newNode = new this.parent.specification.OptionNode(this.parent.specification); nickjillings@1370: this.parent.specification.options.push(newNode); nickjillings@1370: popupObject.show(); nicholas@2535: popupStateNodes.state[5].generate(newNode, this.parent); nickjillings@1370: popupObject.postNode(popupStateNodes.state[5]); nickjillings@1370: } nickjillings@1370: } nickjillings@1370: this.addNode.root.textContent = "Add Survey Entry"; nicholas@2535: this.addNode.root.addEventListener("click", this.addNode, false); nickjillings@1370: this.buttonDOM.appendChild(this.addNode.root); nicholas@2535: nicholas@2535: for (var option of this.specification.options) { nicholas@2535: var newNode = new this.surveyEntryNode(this, option); nickjillings@1370: this.children.push(newNode); nickjillings@1370: this.childrenDOM.appendChild(newNode.rootDOM); nickjillings@1370: } nicholas@2535: nicholas@2535: this.children.forEach(function (obj, index) { n@2420: obj.moveButtons.disable(index); n@2420: }); nickjillings@1370: } nicholas@2535: nicholas@2535: this.pageNode = function (parent, rootObject) { nickjillings@1375: this.type = "pageNode"; nickjillings@1370: this.rootDOM = document.createElement("div"); nickjillings@1370: this.titleDOM = document.createElement("span"); nickjillings@1370: this.attributeDOM = document.createElement("div"); nickjillings@1370: this.attributes = []; nickjillings@1370: this.childrenDOM = document.createElement("div"); nickjillings@1370: this.children = []; nickjillings@1370: this.buttonDOM = document.createElement("div"); nickjillings@1370: this.parent = parent; nickjillings@1370: this.specification = rootObject; nickjillings@1370: this.schema = specification.schema.getAllElementsByName("page")[0]; nickjillings@1370: this.rootDOM.className = "node"; nickjillings@1370: nickjillings@1370: var titleDiv = document.createElement('div'); nickjillings@1370: titleDiv.className = "node-title"; nickjillings@1370: this.titleDOM.className = "node-title"; nickjillings@1370: this.titleDOM.textContent = "Test Page"; nickjillings@1370: titleDiv.appendChild(this.titleDOM); nicholas@2535: nickjillings@1370: this.attributeDOM.className = "node-attributes"; nickjillings@1370: this.childrenDOM.className = "node-children"; nickjillings@1370: this.buttonDOM.className = "node-buttons"; nickjillings@1370: nickjillings@1370: this.rootDOM.appendChild(titleDiv); nickjillings@1370: this.rootDOM.appendChild(this.attributeDOM); nickjillings@1370: this.rootDOM.appendChild(this.childrenDOM); nickjillings@1370: this.rootDOM.appendChild(this.buttonDOM); nicholas@2535: nickjillings@1370: // Do the comment prefix node nicholas@2535: var cpn = this.parent.createGeneralNodeDOM("Comment Prefix", "" + this.specification.id + "-commentprefix", this.parent); nickjillings@1370: cpn.rootDOM.removeChild(cpn.attributeDOM); nickjillings@1370: var obj = { nickjillings@1370: root: document.createElement("div"), nickjillings@1370: input: document.createElement("input"), nickjillings@1370: parent: this, nicholas@2535: handleEvent: function () { nickjillings@1370: this.parent.specification.commentBoxPrefix = event.currentTarget.value; nickjillings@1370: } nickjillings@1370: } nickjillings@1370: cpn.children.push(obj); nickjillings@1370: cpn.childrenDOM.appendChild(obj.root); nickjillings@1370: obj.root.appendChild(obj.input); nicholas@2535: obj.input.addEventListener("change", obj, false); nickjillings@1370: obj.input.value = this.specification.commentBoxPrefix; nickjillings@1370: this.childrenDOM.appendChild(cpn.rootDOM); nickjillings@1370: this.children.push(cpn); nicholas@2535: nickjillings@1370: // Now both before and after surveys nicholas@2535: if (this.specification.preTest == undefined) { nickjillings@2194: this.specification.preTest = new specification.surveyNode(specification); nickjillings@1370: this.specification.preTest.location = "pre"; nickjillings@1370: } nicholas@2535: if (this.specification.postTest == undefined) { nickjillings@2194: this.specification.postTest = new specification.surveyNode(specification); nickjillings@1370: this.specification.postTest.location = "post"; nickjillings@1370: } nicholas@2535: var surveyBefore = new this.parent.surveyNode(this, this.specification.preTest, "Pre"); nicholas@2535: var surveyAfter = new this.parent.surveyNode(this, this.specification.postTest, "Post"); nickjillings@1370: this.children.push(surveyBefore); nickjillings@1370: this.children.push(surveyAfter); nickjillings@1370: this.childrenDOM.appendChild(surveyBefore.rootDOM); nickjillings@1370: this.childrenDOM.appendChild(surveyAfter.rootDOM); nicholas@2535: nickjillings@1370: // Build the attributes nickjillings@1370: var attributeList = this.schema.getAllElementsByTagName("xs:attribute"); nicholas@2535: for (var i = 0; i < attributeList.length; i++) { nickjillings@1370: var attributeName = attributeList[i].getAttribute('name'); nicholas@2535: var attrObject = this.parent.convertAttributeToDOM(rootObject, attributeList[i]); nickjillings@1370: this.attributeDOM.appendChild(attrObject.holder); nickjillings@1370: this.attributes.push(attrObject); nickjillings@1370: } nicholas@2535: nickjillings@1370: this.interfaces = []; nicholas@2535: nicholas@2535: this.getAudioElements = function () { n@2421: var array = []; nicholas@2535: for (var i = 0; i < this.children.length; i++) { n@2421: if (this.children[i].type == "audioElementNode") { n@2421: array[array.length] = this.children[i]; n@2421: } n@2421: } n@2421: return array; n@2421: } nicholas@2535: nicholas@2535: this.redrawChildren = function () { n@2421: this.childrenDOM.innerHTML = ""; nicholas@2535: for (var child of this.children) { n@2421: this.childrenDOM.appendChild(child.rootDOM); n@2421: } n@2421: } nicholas@2535: nicholas@2535: this.audioElementNode = function (parent, rootObject) { nickjillings@1375: this.type = "audioElementNode"; nickjillings@1370: this.rootDOM = document.createElement("div"); nickjillings@1370: this.titleDOM = document.createElement("span"); nickjillings@1370: this.attributeDOM = document.createElement("div"); nickjillings@1370: this.attributes = []; nickjillings@1370: this.childrenDOM = document.createElement("div"); nickjillings@1370: this.children = []; nickjillings@1370: this.buttonDOM = document.createElement("div"); nickjillings@1370: this.parent = parent; nickjillings@1370: this.specification = rootObject; nickjillings@1370: this.schema = specification.schema.getAllElementsByName("audioelement")[0]; nickjillings@1370: this.rootDOM.className = "node"; nickjillings@1370: nickjillings@1370: var titleDiv = document.createElement('div'); nickjillings@1370: titleDiv.className = "node-title"; nickjillings@1370: this.titleDOM.className = "node-title"; nickjillings@1370: this.titleDOM.textContent = "Audio Element"; nickjillings@1370: titleDiv.appendChild(this.titleDOM); nickjillings@1370: nickjillings@1370: this.attributeDOM.className = "node-attributes"; nickjillings@1370: this.childrenDOM.className = "node-children"; nickjillings@1370: this.buttonDOM.className = "node-buttons"; nickjillings@1370: nickjillings@1370: this.rootDOM.appendChild(titleDiv); nickjillings@1370: this.rootDOM.appendChild(this.attributeDOM); nickjillings@1370: this.rootDOM.appendChild(this.childrenDOM); nickjillings@1370: this.rootDOM.appendChild(this.buttonDOM); nicholas@2535: nickjillings@1370: // Build the attributes nickjillings@1370: var attributeList = this.schema.getAllElementsByTagName("xs:attribute"); nicholas@2535: for (var i = 0; i < attributeList.length; i++) { nickjillings@1370: var attributeName = attributeList[i].getAttribute('name'); nicholas@2535: var attrObject = this.parent.parent.convertAttributeToDOM(rootObject, attributeList[i]); nickjillings@1370: this.attributeDOM.appendChild(attrObject.holder); nickjillings@1370: this.attributes.push(attrObject); nickjillings@1370: } nicholas@2535: nickjillings@1370: this.deleteNode = { nickjillings@1370: root: document.createElement("button"), nickjillings@1370: parent: this, nicholas@2535: handleEvent: function () { nicholas@2535: var i = this.parent.parent.specification.audioElements.findIndex(this.findNode, this); nickjillings@1370: if (i >= 0) { nickjillings@1370: var aeList = this.parent.parent.specification.audioElements; nicholas@2535: if (i < aeList.length - 1) { nicholas@2535: aeList = aeList.slice(0, i).concat(aeList.slice(i + 1)); nickjillings@1370: } else { nicholas@2535: aeList = aeList.slice(0, i); nickjillings@1370: } nickjillings@1370: } nicholas@2535: i = this.parent.parent.children.findIndex(function (element, index, array) { nickjillings@1370: if (element == this.parent) nickjillings@1370: return true; nickjillings@1370: else nickjillings@1370: return false; nicholas@2535: }, this); nickjillings@1370: if (i >= 0) { nickjillings@1370: var childList = this.parent.children; nicholas@2535: if (i < aeList.length - 1) { nicholas@2535: childList = childList.slice(0, i).concat(childList.slice(i + 1)); nickjillings@1370: } else { nicholas@2535: childList = childList.slice(0, i); nickjillings@1370: } nickjillings@1370: this.parent.parent.childrenDOM.removeChild(this.parent.rootDOM); nickjillings@1370: } nickjillings@1370: }, nicholas@2535: findNode: function (element, index, array) { nickjillings@1370: if (element == this.parent.specification) nickjillings@1370: return true; nickjillings@1370: else nickjillings@1370: return false; nickjillings@1370: } nickjillings@1370: } nickjillings@1370: this.deleteNode.root.textContent = "Delete Entry"; nicholas@2535: this.deleteNode.root.addEventListener("click", this.deleteNode, false); nickjillings@1370: this.buttonDOM.appendChild(this.deleteNode.root); nicholas@2535: n@2421: this.moveButtons = { n@2421: root_up: document.createElement("button"), n@2421: root_down: document.createElement("button"), n@2421: parent: this, nicholas@2535: handleEvent: function (event) { n@2421: var index = this.parent.parent.getAudioElements().indexOf(this.parent); n@2421: if (event.currentTarget.getAttribute("direction") == "up") { nicholas@2535: index = Math.max(index - 1, 0); n@2421: } else if (event.currentTarget.getAttribute("direction") == "down") { nicholas@2535: index = Math.min(index + 1, this.parent.parent.getAudioElements().length - 1); n@2421: } n@2421: this.parent.moveToPosition(index); n@2421: this.disable(index); n@2421: }, nicholas@2535: disable: function (index) { n@2421: if (index == 0) { n@2421: this.root_up.disabled = true; n@2421: } else { n@2421: this.root_up.disabled = false; n@2421: } nicholas@2535: if (index == this.parent.parent.getAudioElements().length - 1) { n@2421: this.root_down.disabled = true; n@2421: } else { n@2421: this.root_down.disabled = false; n@2421: } n@2421: } n@2421: } nicholas@2535: this.moveButtons.root_up.setAttribute("direction", "up"); nicholas@2535: this.moveButtons.root_down.setAttribute("direction", "down"); nicholas@2535: this.moveButtons.root_up.addEventListener("click", this.moveButtons, false); nicholas@2535: this.moveButtons.root_down.addEventListener("click", this.moveButtons, false); n@2421: this.moveButtons.root_up.textContent = "Move Up"; n@2421: this.moveButtons.root_down.textContent = "Move Down"; n@2421: this.buttonDOM.appendChild(this.moveButtons.root_up); n@2421: this.buttonDOM.appendChild(this.moveButtons.root_down); nicholas@2535: nicholas@2535: this.moveToPosition = function (new_index) { nicholas@2535: n@2421: // Get the zero-th Object n@2421: var zero_object = this.parent.getAudioElements()[0]; n@2421: var parent_children_root_index = this.parent.children.indexOf(zero_object); n@2421: // splice out the array for processing n@2421: var process_array = this.parent.children.splice(parent_children_root_index); nicholas@2535: nicholas@2535: n@2421: new_index = Math.min(new_index, process_array.length); nicholas@2535: var curr_index = process_array.findIndex(function (elem) { nicholas@2535: if (elem == this) { nicholas@2535: return true; nicholas@2535: } else { nicholas@2535: return false; nicholas@2535: } nicholas@2535: }, this); nicholas@2535: n@2421: // Split at the current location to remove the node and shift all the children up nicholas@2535: var tail = process_array.splice(curr_index + 1); n@2421: process_array.pop(); n@2421: process_array = process_array.concat(tail); nicholas@2535: n@2421: //Split at the new location and insert the node n@2421: tail = process_array.splice(new_index); n@2421: process_array.push(this); n@2421: process_array = process_array.concat(tail); nicholas@2535: n@2421: // Re-attach to the parent.children n@2421: this.parent.children = this.parent.children.concat(process_array); nicholas@2535: n@2421: // Re-build the specification n@2421: this.parent.specification.audioElements = []; n@2421: for (var obj of process_array) { n@2421: this.parent.specification.audioElements.push(obj.specification); n@2421: } n@2421: this.parent.redrawChildren(); nicholas@2535: nicholas@2535: process_array.forEach(function (obj, index) { n@2421: obj.moveButtons.disable(index); n@2421: }); nicholas@2535: n@2421: } nickjillings@1370: } nicholas@2535: nicholas@2535: this.commentQuestionNode = function (parent, rootObject) { nickjillings@1375: this.type = "commentQuestionNode"; nickjillings@1370: this.rootDOM = document.createElement("div"); nickjillings@1370: this.titleDOM = document.createElement("span"); nickjillings@1370: this.attributeDOM = document.createElement("div"); nickjillings@1370: this.attributes = []; nickjillings@1370: this.childrenDOM = document.createElement("div"); nickjillings@1370: this.children = []; nickjillings@1370: this.buttonDOM = document.createElement("div"); nickjillings@1370: this.parent = parent; nickjillings@1370: this.specification = rootObject; nickjillings@1370: this.schema = specification.schema.getAllElementsByName("page")[0]; n@2421: this.rootDOM.className = "node audio-element"; nickjillings@1370: nickjillings@1370: var titleDiv = document.createElement('div'); nickjillings@1370: titleDiv.className = "node-title"; nickjillings@1370: this.titleDOM.className = "node-title"; nickjillings@1370: this.titleDOM.textContent = "Test Page"; nickjillings@1370: titleDiv.appendChild(this.titleDOM); nickjillings@1370: nickjillings@1370: this.attributeDOM.className = "node-attributes"; nickjillings@1370: this.childrenDOM.className = "node-children"; nickjillings@1370: this.buttonDOM.className = "node-buttons"; nickjillings@1370: nickjillings@1370: this.rootDOM.appendChild(titleDiv); nickjillings@1370: this.rootDOM.appendChild(this.attributeDOM); nickjillings@1370: this.rootDOM.appendChild(this.childrenDOM); nickjillings@1370: this.rootDOM.appendChild(this.buttonDOM); nicholas@2535: nickjillings@1370: } nicholas@2535: nickjillings@1374: // Build the components nickjillings@1310: if (this.specification.interfaces.length == 0) { nickjillings@2194: this.specification.interfaces.push(new specification.interfaceNode(specification)); nickjillings@1310: } nicholas@2535: for (var interfaceObj of this.specification.interfaces) { nicholas@2535: var newInterface = new this.parent.interfaceNode(this.parent, interfaceObj); nicholas@2535: newInterface.build("Interface", "" + this.specification.id + "-interface", this.childrenDOM); nickjillings@1381: this.children.push(newInterface); nickjillings@1381: this.interfaces.push(newInterface); nickjillings@1381: } nicholas@2535: nicholas@2535: for (var elements of this.specification.audioElements) { nicholas@2535: var audioElementDOM = new this.audioElementNode(this, elements); nickjillings@1374: this.children.push(audioElementDOM); nickjillings@1374: this.childrenDOM.appendChild(audioElementDOM.rootDOM); nickjillings@1374: } nicholas@2535: nicholas@2535: this.getAudioElements().forEach(function (elem) { n@2421: elem.moveButtons.disable(); n@2421: }); nicholas@2535: nickjillings@1370: this.addInterface = { nickjillings@1370: root: document.createElement("button"), nickjillings@1370: parent: this, nicholas@2535: handleEvent: function () { nickjillings@2194: var InterfaceObj = new specification.interfaceNode(specification); nicholas@2535: var newInterface = new this.parent.parent.interfaceNode(this.parent.parent, InterfaceObj); nicholas@2535: newInterface.build("Interface", "" + this.parent.specification.id + "-interface", this.parent.childrenDOM); nickjillings@1370: this.parent.children.push(newInterface); nickjillings@1370: this.parent.specification.interfaces.push(InterfaceObj); nickjillings@1370: this.parent.interfaces.push(newInterface); nickjillings@1370: } nickjillings@1370: } nickjillings@1370: this.addInterface.root.textContent = "Add Interface"; nicholas@2535: this.addInterface.root.addEventListener("click", this.addInterface, false); nickjillings@1370: this.buttonDOM.appendChild(this.addInterface.root); nicholas@2535: nickjillings@1370: this.addAudioElement = { nickjillings@1370: root: document.createElement("button"), nickjillings@1370: parent: this, nicholas@2535: handleEvent: function () { nickjillings@2194: var audioElementObject = new this.parent.specification.audioElementNode(specification); nicholas@2535: var audioElementDOM = new this.parent.audioElementNode(this.parent, audioElementObject); nickjillings@1370: this.parent.specification.audioElements.push(audioElementObject); nickjillings@1370: this.parent.children.push(audioElementDOM); nickjillings@1370: this.parent.childrenDOM.appendChild(audioElementDOM.rootDOM); nickjillings@1370: } nickjillings@1370: } nickjillings@1370: this.addAudioElement.root.textContent = "Add Audio Element"; nicholas@2535: this.addAudioElement.root.addEventListener("click", this.addAudioElement, false); nickjillings@1370: this.buttonDOM.appendChild(this.addAudioElement.root); nickjillings@1370: } nicholas@2535: }