nicholas@2885: /* globals document, angular, window, Promise, XMLHttpRequest, Specification, XMLSerializer, Blob, DOMParser, FileReader, $*/ nicholas@2851: function get(url) { nicholas@2851: // Return a new promise. nicholas@2851: return new Promise(function (resolve, reject) { nicholas@2851: // Do the usual XHR stuff nicholas@2851: var req = new XMLHttpRequest(); nicholas@2851: req.open('GET', url); nickjillings@1370: nicholas@2851: req.onload = function () { nicholas@2851: // This is called even on 404 etc nicholas@2851: // so check the status nicholas@2851: if (req.status == 200) { nicholas@2851: // Resolve the promise with the response text nicholas@2851: resolve(req.response); nicholas@2851: } else { nicholas@2851: // Otherwise reject with the status text nicholas@2851: // which will hopefully be a meaningful error nicholas@2851: reject(Error(req.statusText)); nicholas@2851: } nicholas@2851: }; nicholas@2851: nicholas@2851: // Handle network errors nicholas@2851: req.onerror = function () { nicholas@2851: reject(Error("Network Error")); nicholas@2851: }; nicholas@2851: nicholas@2851: // Make the request nicholas@2851: req.send(); nicholas@2851: }); nickjillings@1370: } nickjillings@1370: nicholas@2851: var AngularInterface = angular.module("creator", []); nickjillings@1370: nicholas@3097: AngularInterface.directive("dropzone", function () { nicholas@3097: return { nicholas@3097: restrict: "A", nicholas@3097: link: function (scope, elem) { nicholas@3097: elem.bind('dragover', function (evt) { nicholas@3097: evt.stopPropagation(); nicholas@3097: evt.preventDefault(); nicholas@3097: }); nicholas@3097: elem.bind('dragend', function (evt) { nicholas@3097: console.log(evt); nicholas@3097: evt.stopPropagation(); nicholas@3097: evt.preventDefault(); nicholas@3097: }); nicholas@3097: elem.bind('drop', function (event) { nicholas@3097: var evt = event.originalEvent; nicholas@3097: console.log(evt); nicholas@3097: evt.stopPropagation(); nicholas@3097: evt.preventDefault(); nicholas@3097: nicholas@3097: var files = evt.dataTransfer.files; nicholas@3097: for (var i = 0, f; f = files[i]; i++) { nicholas@3097: var reader = new FileReader(); nicholas@3097: reader.readAsArrayBuffer(f); nicholas@3097: nicholas@3097: reader.onload = (function (theFile) { nicholas@3097: return function (e) { nicholas@3099: scope.ondrop(theFile.name); nicholas@3097: scope.$apply(); nicholas@3097: }; nicholas@3097: })(f); nicholas@3097: } nicholas@3097: }); nicholas@3097: } nicholas@3097: } nicholas@3097: }); nicholas@3097: nicholas@2851: var specification = new Specification(); nickjillings@1370: nicholas@2535: window.onload = function () { nicholas@2851: // Get the test interface specifications n@2911: toggleDropdowns(); nicholas@3098: $("#popupHolder").modal("show"); n@2911: }; n@2911: n@2911: function toggleDropdowns() { nicholas@2884: $(function () { nicholas@2884: $('[data-toggle="popover"]').popover(); nicholas@2884: }); n@2911: } nicholas@2535: nicholas@2861: function handleFiles(event) { nicholas@2861: var s = angular.element(event.currentTarget).scope(); nicholas@2861: s.handleFiles(event); nicholas@2861: s.$apply(); nicholas@2861: } nicholas@2861: nicholas@2851: AngularInterface.controller("view", ['$scope', '$element', '$window', function ($s, $e, $w) { nicholas@2864: $s.testSpecifications = {}; nicholas@2864: nicholas@2864: (function () { nicholas@2864: new Promise(function (resolve, reject) { nicholas@2864: var xml = new XMLHttpRequest(); nicholas@2864: xml.open("GET", "test_create/interfaces/specifications.json"); nicholas@2864: xml.onload = function () { nicholas@2864: if (xml.status === 200) { nicholas@2864: resolve(xml.responseText); nicholas@2864: return; nicholas@2864: } nicholas@2864: reject(xml.status); nicholas@2864: }; nicholas@2864: xml.onerror = function () { nicholas@2864: reject(new Error("Network Error")); nicholas@2864: }; nicholas@2864: xml.send(); nicholas@2864: }).then(JSON.parse).then(function (data) { nicholas@2864: $s.testSpecifications = data; nicholas@2864: $s.$apply(); nicholas@2865: }); nicholas@2864: })(); nickjillings@1370: nicholas@2851: $s.globalSchema = undefined; nicholas@2851: get("xml/test-schema.xsd").then(function (text) { nicholas@2851: specification.processSchema(text); nicholas@2851: $s.globalSchema = specification.getSchema(); nicholas@2986: $s.$apply(); nicholas@2851: }); n@2912: $s.availableInterfaceModules = []; n@2912: get("interfaces/interfaces.json").then(JSON.parse).then(function (d) { n@2912: $s.availableInterfaceModules = d.interfaces; n@2912: $s.$apply(); n@2912: }); nicholas@2851: $s.specification = specification; nicholas@2886: $s.selectedTestPrototype = undefined; nicholas@2886: $s.setTestPrototype = function (obj) { nicholas@2886: $s.selectedTestPrototype = obj; nicholas@2886: $w.specification.interface = obj.interface; nicholas@2886: } nicholas@2857: nicholas@2857: $s.addPage = function () { nicholas@2857: $s.specification.createNewPage(); nicholas@2859: }; nicholas@2860: nicholas@2862: $s.removePage = function (page) { nicholas@2862: var index = $s.specification.pages.findIndex(function (a) { nicholas@2862: return a == page; nicholas@2862: }); nicholas@2862: if (index === -1) { nicholas@2862: throw ("Invalid Page"); nicholas@2862: } nicholas@2862: $s.specification.pages.splice(index, 1); nicholas@2862: }; nicholas@2862: nicholas@2860: $s.exportXML = function () { nicholas@2860: var s = new XMLSerializer(); schlien@2961: var doc = specification.encode(); nicholas@2891: var xmlstr = s.serializeToString(doc); schlien@2961: var bb = new Blob(["" + s.serializeToString(doc)], { nicholas@2860: type: 'application/xml' nicholas@2860: }); nicholas@2860: var dnlk = window.URL.createObjectURL(bb); nicholas@2891: var a = document.createElement("a"); n@2913: document.body.appendChild(a) nicholas@2891: a.href = dnlk; nicholas@2891: a.download = "test.xml"; nicholas@2891: a.click(); nicholas@2891: window.URL.revokeObjectURL(dnlk); n@2913: document.body.removeChild(a); nicholas@2861: }; nicholas@2887: $s.validated = false; nicholas@2887: $s.showValidationMessages = false; nicholas@2887: $s.validate = function () { nicholas@2887: var s = new XMLSerializer(); nicholas@2887: var Module = { nicholas@2959: xml: "" + s.serializeToString(specification.encode()), nicholas@2887: schema: specification.getSchemaString(), nicholas@2887: arguments: ["--noout", "--schema", 'test-schema.xsd', 'document.xml'] nicholas@2887: }; nicholas@2887: var xmllint = validateXML(Module); nicholas@2887: console.log(xmllint); nicholas@2887: if (xmllint != 'document.xml validates\n') { nicholas@2887: $s.validated = false; nicholas@2887: var list = $e[0].querySelector("#validation-error-list"); nicholas@2887: while (list.firstChild) { nicholas@2887: list.removeChild(list.firstChild); nicholas@2887: } nicholas@2887: var errors = xmllint.split('\n'); nicholas@2887: errors = errors.slice(0, errors.length - 2); nicholas@2887: errors.forEach(function (str) { nicholas@2887: var li = document.createElement("li"); nicholas@2887: li.textContent = str; nicholas@2887: list.appendChild(li); nicholas@2887: }); nicholas@2887: } else { nicholas@2887: $s.validated = true; nicholas@2887: } nicholas@2887: $s.showValidationMessages = true; nicholas@2887: } nicholas@2887: $s.hideValidationMessages = function () { nicholas@2887: $s.showValidationMessages = false; nicholas@2887: } n@2911: $s.$watch(function () { n@2911: return document.querySelectorAll("div.pageNode").length; n@2911: }, $w.toggleDropdowns); n@2911: $s.$watch(function () { n@2911: return document.querySelectorAll("div.surveyentry").length; n@2911: }, $w.toggleDropdowns); n@2911: $s.$watch(function () { n@2911: return document.querySelectorAll("div.interface").length; n@2911: }, $w.toggleDropdowns); n@2911: $s.$watch(function () { n@2911: return document.querySelectorAll("div.audioelement").length; n@2911: }, $w.toggleDropdowns); nicholas@2851: }]); nickjillings@1370: nicholas@2851: AngularInterface.controller("introduction", ['$scope', '$element', '$window', function ($s, $e, $w) { nicholas@2851: $s.state = 0; n@2908: $s.selected = undefined; nicholas@3099: $s.close = function () { nicholas@3099: $($e[0]).modal('hide'); nicholas@3099: } nicholas@2851: $s.next = function () { nicholas@3108: if (($s.state === 1 && $s.file) || $s.state === 2) { nicholas@3099: $s.initialise($s.selected); nicholas@3099: if ($s.selected != "AB" && $s.selected != "ABX") { nicholas@3099: $s.close(); nicholas@3099: } nicholas@3108: } else if ($s.state === 3 && $s.audioFragments.length > 0) { nicholas@3099: // Populate the audio pages by creating a pairwise set of pairs nicholas@3099: $s.populatePages((function (a) { nicholas@3099: var b = []; nicholas@3099: a.forEach(function (e1, i1, a) { nicholas@3099: a.forEach(function (e2, i2) { nicholas@3099: var entry = [e1, e2]; nicholas@3099: if (i1 > i2) { nicholas@3099: b.push(entry); nicholas@3099: } nicholas@3099: }); nicholas@3099: }); nicholas@3099: return b; nicholas@3099: })($s.audioFragments)); nicholas@3099: $s.close(); nicholas@3108: } else if ($s.state > 3) { nicholas@3099: $s.close(); nicholas@3099: } nicholas@2851: $s.state++; nicholas@3099: console.log("Modal state " + $s.state); nicholas@2851: }; nicholas@3099: $s.skip = function () { nicholas@3099: $s.close(); nicholas@3099: } nicholas@2851: $s.back = function () { nicholas@2851: $s.state--; nicholas@2851: }; nicholas@2986: nicholas@2986: $s.$watch(function () { nicholas@2986: return ($s.globalSchema !== undefined) nicholas@2986: }, function () { nicholas@2986: if ($s.globalSchema !== undefined && $s.state === 0) { nicholas@2986: $s.state = 1; nicholas@2986: } nicholas@2986: }) nicholas@2986: nicholas@2851: $s.mouseover = function (name) { nicholas@2864: var obj = $s.testSpecifications.interfaces.find(function (i) { nicholas@2851: return i.name == name; nicholas@2851: }); nicholas@2851: if (obj) { nicholas@2851: $s.description = obj.description.en; nicholas@2851: } nicholas@2851: }; nicholas@2851: $s.initialise = function (name) { nicholas@2885: var obj = $s.testSpecifications.interfaces.find(function (i) { nicholas@2851: return i.name == name; nicholas@2851: }); nicholas@2886: if (obj === undefined) { nicholas@2886: throw ("Cannot find specification"); nicholas@2886: } n@2908: if (typeof obj.template === "string") { n@2908: get(obj.template).then(function (data) { n@2908: $s.parseFile(data); n@2908: }, function (err) {}) n@2908: } else { n@2908: $s.setTestPrototype(obj); n@2908: } nicholas@2851: }; n@2908: $s.select = function (name) { nicholas@3099: $s.selected = name; nicholas@3099: }; nicholas@3099: // Get the test interface specifications nicholas@2861: $s.file = undefined; nicholas@2851: $s.description = ""; nicholas@2861: n@2908: $s.parseFile = function (f) { n@2908: var p = new DOMParser(); n@2908: specification.decode(p.parseFromString(f, "text/xml")); n@2908: $s.$apply(); n@2908: } n@2908: nicholas@2861: $s.handleFiles = function ($event) { nicholas@2861: $s.file = $event.currentTarget.files[0]; nicholas@2861: var r = new FileReader(); nicholas@2861: r.onload = function () { n@2908: $s.parseFile(r.result); nicholas@2862: }; nicholas@2861: r.readAsText($s.file); nicholas@2861: }; nicholas@3099: nicholas@3099: $s.audioFragments = []; nicholas@3099: $s.ondrop = function (filename) { nicholas@3099: $s.audioFragments.push({ nicholas@3099: fname: filename, nicholas@3099: name: "fragment-" + String($s.audioFragments.length) nicholas@3099: }); nicholas@3099: }; nicholas@3099: nicholas@3099: $s.populatePages = function (structures) { nicholas@3099: structures.forEach(function (p, i) { nicholas@3099: var page = $w.specification.createNewPage(); nicholas@3099: page.id = "page-" + String(i); nicholas@3099: p.forEach(function (a) { nicholas@3099: var fragment = page.addAudioElement(); nicholas@3099: fragment.name = a.name; nicholas@3099: fragment.id = a.name + "-p" + String(i); nicholas@3099: fragment.url = a.fname; nicholas@3099: }); nicholas@3099: page.addInterface(); nicholas@3099: }); nicholas@3099: } nicholas@2851: }]); nickjillings@1370: nicholas@2851: AngularInterface.controller("setup", ['$scope', '$element', '$window', function ($s, $e, $w) { nicholas@2851: function initialise() { nicholas@2851: if ($s.globalSchema) { nicholas@2851: $s.schema = $s.globalSchema.querySelector("[name=setup]"); nickjillings@1385: } nickjillings@1370: } nicholas@2851: $s.schema = undefined; nicholas@2851: $s.attributes = []; nickjillings@1370: nicholas@2851: $s.$watch("globalSchema", initialise); nicholas@2853: $s.$watch("specification.metrics.enabled.length", function () { nicholas@2853: var metricsNode = document.getElementById("metricsNode"); nicholas@2853: if (!$s.specification.metrics) { nicholas@2853: return; nicholas@2853: } nicholas@2853: metricsNode.querySelectorAll("input").forEach(function (DOM) { nicholas@2853: DOM.checked = false; nicholas@2853: }); nicholas@2853: $s.specification.metrics.enabled.forEach(function (metric) { nicholas@2853: var DOM = metricsNode.querySelector("[value=" + metric + "]"); nicholas@2853: if (DOM) { nicholas@2853: DOM.checked = true; nicholas@2853: } nicholas@2853: }); nicholas@2855: }); nicholas@2853: nicholas@2853: $s.enableMetric = function ($event) { nicholas@2853: var metric = $event.currentTarget.value; nicholas@2853: var index = specification.metrics.enabled.findIndex(function (a) { nicholas@2853: return a == metric; nicholas@2853: }); nicholas@2853: if ($event.currentTarget.checked) { nicholas@2853: if (index == -1) { nicholas@2853: specification.metrics.enabled.push(metric); nicholas@2853: } nicholas@2853: } else { nicholas@2853: if (index >= 0) { nicholas@2853: specification.metrics.enabled.splice(index, 1); nicholas@2853: } nicholas@2853: } nicholas@2855: }; nicholas@2886: nicholas@2886: $s.configure = function () {} nicholas@2886: nicholas@2886: $s.$watch("selectedTestPrototype", $s.configure); n@2907: n@2907: $s.placeholder = function (name) { n@2908: if ($s.schema) { n@2908: var spec = $s.schema.querySelector("attribute[name=\"" + name + "\"]") || $w.specification.schema.querySelector("attribute[name=\"" + name + "\"]"); n@2908: var attr = spec.getAttribute("default"); n@2912: if (attr === null) { n@2912: return "Not set"; n@2908: } n@2908: return attr; n@2907: } n@2907: } nicholas@2851: }]); nicholas@2853: nicholas@2858: AngularInterface.controller("survey", ['$scope', '$element', '$window', function ($s, $e, $w) { nicholas@2858: $s.addSurveyEntry = function () { nicholas@2858: $s.survey.addOption(); nicholas@2858: }; nicholas@2858: $s.removeSurveyEntry = function (entry) { nicholas@2858: var index = $s.survey.options.findIndex(function (a) { nicholas@2858: return a == entry; nicholas@2858: }); nicholas@2858: if (index === -1) { nicholas@2858: throw ("Invalid Entry"); nicholas@2858: } nicholas@2858: $s.survey.options.splice(index, 1); nicholas@2858: }; nicholas@2858: }]); nicholas@2858: nicholas@2853: AngularInterface.controller("surveyOption", ['$scope', '$element', '$window', function ($s, $e, $w) { nicholas@2853: nicholas@2853: $s.removeOption = function (option) { nicholas@2853: var index = $s.opt.options.findIndex(function (a) { nicholas@2853: return a == option; nicholas@2853: }); nicholas@2853: if (index === -1) { nicholas@2853: throw ("Invalid option"); nicholas@2853: } nicholas@2853: $s.opt.options.splice(index, 1); nicholas@2853: }; nicholas@2853: $s.addOption = function () { nicholas@2853: $s.opt.options.push({ nicholas@2853: name: "", nicholas@2853: text: "" nicholas@2853: }); nicholas@2855: }; nicholas@2857: nicholas@2857: $s.addCondition = function () { nicholas@2857: $s.opt.conditions.push({ nicholas@2857: check: "equals", nicholas@2857: value: "", nicholas@2857: jumpToOnPass: undefined, nicholas@2857: jumpToOnFail: undefined nicholas@2857: }); nicholas@2857: }; nicholas@2857: nicholas@2857: $s.removeCondition = function (condition) { nicholas@2857: var index = $s.opt.conditions.findIndex(function (c) { nicholas@2857: return c == condition; nicholas@2857: }); nicholas@2857: if (index === -1) { nicholas@2857: throw ("Invalid Condition"); nicholas@2857: } nicholas@2857: $s.opt.conditions.splice(index, 1); nicholas@2857: }; nicholas@2855: }]); nicholas@2855: nicholas@2855: AngularInterface.controller("interfaceNode", ['$scope', '$element', '$window', function ($s, $e, $w) { nicholas@2855: $s.$watch("interface.options.length", function () { nicholas@2855: if (!$s.interface || !$s.interface.options) { nicholas@2855: return; nicholas@2855: } nicholas@2855: var options = $e[0].querySelector(".interfaceOptions").querySelectorAll(".attribute"); nicholas@2855: options.forEach(function (option) { nicholas@2855: var name = option.getAttribute("name"); nicholas@2855: var index = $s.interface.options.findIndex(function (io) { nicholas@2855: return io.name == name; nicholas@2855: }); nicholas@3136: if (name == "scalerange") { nicholas@3136: $e[0].querySelector("[name=min]").value = option.getAttribute("min"); nicholas@3136: $e[0].querySelector("[name=max]").value = option.getAttribute("max"); nicholas@3136: } nicholas@2855: option.querySelector("input").checked = (index >= 0); nicholas@2855: }); nicholas@2855: }); nicholas@3136: $s.updateScaleRange = function() { nicholas@3136: var obj = $s.interface.options.find(function(i) { nicholas@3136: return i.name == "scalerange"; nicholas@3136: }); nicholas@3136: if (obj === undefined) { nicholas@3136: return; nicholas@3136: } nicholas@3136: var min = $e[0].querySelector("[name=min]").value; nicholas@3136: var max = $e[0].querySelector("[name=max]").value; nicholas@3136: obj.min = min; nicholas@3136: obj.max = max; nicholas@3136: }; nicholas@2855: $s.enableInterfaceOption = function ($event) { nicholas@2855: var name = $event.currentTarget.parentElement.getAttribute("name"); nicholas@2855: var type = $event.currentTarget.parentElement.getAttribute("type"); nicholas@2855: var index = $s.interface.options.findIndex(function (io) { nicholas@2855: return io.name == name; nicholas@2855: }); nicholas@2855: if (index == -1 && $event.currentTarget.checked) { nicholas@3136: var obj = { nicholas@2855: name: name, nicholas@2855: type: type nicholas@3136: }; nicholas@2855: if (name == "scalerange") { nicholas@3136: $s.updateScaleRange(); nicholas@2855: } nicholas@3136: $s.interface.options.push(obj); nicholas@2855: } else if (index >= 0 && !$event.currentTarget.checked) { nicholas@2855: $s.interface.options.splice(index, 1); nicholas@2855: } nicholas@2857: }; nicholas@2886: $s.scales = []; nicholas@2857: $s.removeScale = function (scale) { nicholas@2857: var index = $s.interface.scales.findIndex(function (s) { nicholas@2857: return s == scale; nicholas@2857: }); nicholas@2857: if (index >= 0) { nicholas@2857: $s.interface.scales.splice(index, 1); nicholas@2857: } nicholas@2857: }; nicholas@2857: $s.addScale = function () { nicholas@2857: $s.interface.scales.push({ nicholas@2857: position: undefined, nicholas@2857: text: undefined nicholas@2857: }); nicholas@2857: }; nicholas@2864: $s.clearScales = function () { nicholas@2864: $s.interface.scales = []; nicholas@2864: }; nicholas@2876: $s.useScales = function (scale) { nicholas@2864: $s.clearScales(); nicholas@2876: scale.scales.forEach(function (s) { nicholas@2864: $s.interface.scales.push(s); nicholas@2864: }); nicholas@2886: $s.selectedScale = scale.name; nicholas@2864: }; nicholas@2886: $s.selectedScale = undefined; nicholas@2886: nicholas@2886: $s.configure = function () { nicholas@2886: if ($s.selectedTestPrototype === undefined) { nicholas@2886: return; nicholas@2886: } nicholas@2886: if ($s.selectedTestPrototype.checks && $s.selectedTestPrototype.checks.length >= 1) { nicholas@2886: $s.selectedTestPrototype.checks.forEach(function (entry) { nicholas@2886: var dom = $e[0].querySelector("[name=\"" + entry.name + "\"] input"); nicholas@2886: if (entry.support == "none") { nicholas@2886: dom.checked = false; nicholas@2886: dom.disabled = true; nicholas@2886: } nicholas@2886: }); nicholas@2886: } nicholas@2886: if ($s.selectedTestPrototype.show && $s.selectedTestPrototype.show.length >= 1) { nicholas@2886: $s.selectedTestPrototype.show.forEach(function (entry) { nicholas@2886: var dom = $e[0].querySelector("[name=\"" + entry.name + "\"] input"); nicholas@2886: if (entry.support == "none") { nicholas@2886: dom.checked = false; nicholas@2886: dom.disabled = true; nicholas@2886: } nicholas@2886: }); nicholas@2886: } nicholas@2886: if ($s.interface !== specification.interfaces) { nicholas@2886: // Page specific interface nodes nicholas@2886: if ($s.selectedTestPrototype.hasScales !== undefined && ($s.selectedTestPrototype.hasScales == "false" || $s.selectedTestPrototype.hasScales == false)) { nicholas@2886: var elem = $e[0].querySelector("[name=\"scale-selection\"]") nicholas@2886: elem.style.visibility = "hidden"; nicholas@2886: elem.style.height = "0px"; nicholas@2886: } nicholas@2886: if ($s.selectedTestPrototype.scales && $s.selectedTestPrototype.show.length >= 1) { nicholas@2886: $s.scales = []; nicholas@2886: $s.selectedTestPrototype.scales.forEach(function (scalename) { nicholas@2886: var obj = $s.testSpecifications.scales.find(function (a) { nicholas@2886: return a.name == scalename; nicholas@2886: }); nicholas@2886: $s.scales.push(obj); nicholas@2886: }); nicholas@2886: if ($s.selectedTestPrototype.scales.includes($s.selectedScale) == false) { nicholas@2886: $s.clearScales(); nicholas@2886: } nicholas@2886: if ($s.scales.length == 1) { nicholas@2886: $s.clearScales(); nicholas@2886: $s.useScales($s.scales[0]); nicholas@2886: } nicholas@2886: } else { nicholas@2886: $s.scales = $s.testSpecifications.scales; nicholas@2886: } nicholas@2886: } nicholas@2886: }; nicholas@2886: nicholas@2886: $s.$watch("selectedTestPrototype", $s.configure); nicholas@2886: $s.configure(); nicholas@2853: }]); nicholas@2859: AngularInterface.controller("page", ['$scope', '$element', '$window', function ($s, $e, $w) { n@2907: $s.schema = $w.specification.schema.querySelector("element[name=\"page\"]"); n@2909: $s.page.label = $s.page.label || "default"; nicholas@2859: $s.addInterface = function () { nicholas@2859: $s.page.addInterface(); nicholas@2859: }; nicholas@2859: $s.removeInterface = function (node) { nicholas@2859: var index = $s.page.interfaces.findIndex(function (a) { nicholas@2859: return a == node; nicholas@2859: }); nicholas@2859: if (index === -1) { nicholas@2859: throw ("Invalid node"); nicholas@2859: } nicholas@2859: $s.page.interfaces.splice(index, 1); nicholas@2859: }; nicholas@2859: nicholas@2859: $s.addCommentQuestion = function () { nicholas@2859: $s.page.addCommentQuestion(); nicholas@2859: }; nicholas@2859: $s.removeCommentQuestion = function (node) { nicholas@2859: var index = $s.page.commentQuestions.findIndex(function (a) { nicholas@2859: return a == node; nicholas@2859: }); nicholas@2859: if (index === -1) { nicholas@2859: throw ("Invalid node"); nicholas@2859: } nicholas@2859: $s.page.commentQuestions.splice(index, 1); nicholas@2859: }; nicholas@2859: $s.addAudioElement = function () { nicholas@2859: $s.page.addAudioElement(); nicholas@2859: }; nicholas@3099: $s.ondrop = function (filename) { nicholas@3097: var fragment = $s.page.addAudioElement(); nicholas@3097: fragment.url = filename; nicholas@3097: }; nicholas@2859: $s.removeAudioElement = function (element) { nicholas@2859: var index = $s.page.audioElements.findIndex(function (a) { nicholas@2859: return a == element; nicholas@2859: }); nicholas@2859: if (index === -1) { nicholas@2859: throw ("Invalid node"); nicholas@2859: } nicholas@2859: $s.page.audioElements.splice(index, 1); nicholas@2859: }; n@2907: n@2907: $s.placeholder = function (name) { n@2907: var spec = $s.schema.querySelector("attribute[name=\"" + name + "\"]") || $w.specification.schema.querySelector("attribute[name=\"" + name + "\"]"); n@2907: var attr = spec.getAttribute("default"); n@2912: if (attr === null) { n@2912: return "Not set"; n@2907: } n@2907: return attr; n@2907: } nicholas@2859: }]);