annotate test_create/test_core.js @ 2986:f99b888f57e9

Possible fix for #272
author Nicholas Jillings <nicholas.jillings@mail.bcu.ac.uk>
date Tue, 10 Apr 2018 10:18:25 +0100
parents 1593792ae742
children 1ae8c03dd6a6
rev   line source
nicholas@2885 1 /* globals document, angular, window, Promise, XMLHttpRequest, Specification, XMLSerializer, Blob, DOMParser, FileReader, $*/
nicholas@2851 2 function get(url) {
nicholas@2851 3 // Return a new promise.
nicholas@2851 4 return new Promise(function (resolve, reject) {
nicholas@2851 5 // Do the usual XHR stuff
nicholas@2851 6 var req = new XMLHttpRequest();
nicholas@2851 7 req.open('GET', url);
nickjillings@1370 8
nicholas@2851 9 req.onload = function () {
nicholas@2851 10 // This is called even on 404 etc
nicholas@2851 11 // so check the status
nicholas@2851 12 if (req.status == 200) {
nicholas@2851 13 // Resolve the promise with the response text
nicholas@2851 14 resolve(req.response);
nicholas@2851 15 } else {
nicholas@2851 16 // Otherwise reject with the status text
nicholas@2851 17 // which will hopefully be a meaningful error
nicholas@2851 18 reject(Error(req.statusText));
nicholas@2851 19 }
nicholas@2851 20 };
nicholas@2851 21
nicholas@2851 22 // Handle network errors
nicholas@2851 23 req.onerror = function () {
nicholas@2851 24 reject(Error("Network Error"));
nicholas@2851 25 };
nicholas@2851 26
nicholas@2851 27 // Make the request
nicholas@2851 28 req.send();
nicholas@2851 29 });
nickjillings@1370 30 }
nickjillings@1370 31
nicholas@2851 32 var AngularInterface = angular.module("creator", []);
nickjillings@1370 33
nicholas@2851 34 var specification = new Specification();
nickjillings@1370 35
nicholas@2535 36 window.onload = function () {
nicholas@2851 37 // Get the test interface specifications
n@2911 38 toggleDropdowns();
n@2911 39 };
n@2911 40
n@2911 41 function toggleDropdowns() {
nicholas@2884 42 $(function () {
nicholas@2884 43 $('[data-toggle="popover"]').popover();
nicholas@2884 44 });
n@2911 45 }
nicholas@2535 46
nicholas@2861 47 function handleFiles(event) {
nicholas@2861 48 var s = angular.element(event.currentTarget).scope();
nicholas@2861 49 s.handleFiles(event);
nicholas@2861 50 s.$apply();
nicholas@2861 51 }
nicholas@2861 52
nicholas@2851 53 AngularInterface.controller("view", ['$scope', '$element', '$window', function ($s, $e, $w) {
nicholas@2851 54 $s.popupVisible = true;
nicholas@2864 55 $s.testSpecifications = {};
nicholas@2864 56
nicholas@2864 57 (function () {
nicholas@2864 58 new Promise(function (resolve, reject) {
nicholas@2864 59 var xml = new XMLHttpRequest();
nicholas@2864 60 xml.open("GET", "test_create/interfaces/specifications.json");
nicholas@2864 61 xml.onload = function () {
nicholas@2864 62 if (xml.status === 200) {
nicholas@2864 63 resolve(xml.responseText);
nicholas@2864 64 return;
nicholas@2864 65 }
nicholas@2864 66 reject(xml.status);
nicholas@2864 67 };
nicholas@2864 68 xml.onerror = function () {
nicholas@2864 69 reject(new Error("Network Error"));
nicholas@2864 70 };
nicholas@2864 71 xml.send();
nicholas@2864 72 }).then(JSON.parse).then(function (data) {
nicholas@2864 73 $s.testSpecifications = data;
nicholas@2864 74 $s.$apply();
nicholas@2865 75 });
nicholas@2864 76 })();
nickjillings@1370 77
nicholas@2851 78 $s.showPopup = function () {
nicholas@2851 79 $s.popupVisible = true;
nicholas@2851 80 };
nicholas@2851 81 $s.hidePopup = function () {
nicholas@2851 82 $s.popupVisible = false;
nicholas@2851 83 };
nicholas@2851 84 $s.globalSchema = undefined;
nicholas@2851 85 get("xml/test-schema.xsd").then(function (text) {
nicholas@2851 86 specification.processSchema(text);
nicholas@2851 87 $s.globalSchema = specification.getSchema();
nicholas@2986 88 $s.$apply();
nicholas@2851 89 });
n@2912 90 $s.availableInterfaceModules = [];
n@2912 91 get("interfaces/interfaces.json").then(JSON.parse).then(function (d) {
n@2912 92 $s.availableInterfaceModules = d.interfaces;
n@2912 93 $s.$apply();
n@2912 94 });
nicholas@2851 95 $s.specification = specification;
nicholas@2886 96 $s.selectedTestPrototype = undefined;
nicholas@2886 97 $s.setTestPrototype = function (obj) {
nicholas@2886 98 $s.selectedTestPrototype = obj;
nicholas@2886 99 $w.specification.interface = obj.interface;
nicholas@2886 100 }
nicholas@2857 101
nicholas@2857 102 $s.addPage = function () {
nicholas@2857 103 $s.specification.createNewPage();
nicholas@2859 104 };
nicholas@2860 105
nicholas@2862 106 $s.removePage = function (page) {
nicholas@2862 107 var index = $s.specification.pages.findIndex(function (a) {
nicholas@2862 108 return a == page;
nicholas@2862 109 });
nicholas@2862 110 if (index === -1) {
nicholas@2862 111 throw ("Invalid Page");
nicholas@2862 112 }
nicholas@2862 113 $s.specification.pages.splice(index, 1);
nicholas@2862 114 };
nicholas@2862 115
nicholas@2860 116 $s.exportXML = function () {
nicholas@2860 117 var s = new XMLSerializer();
schlien@2961 118 var doc = specification.encode();
nicholas@2891 119 var xmlstr = s.serializeToString(doc);
schlien@2961 120 var bb = new Blob(["<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" + s.serializeToString(doc)], {
nicholas@2860 121 type: 'application/xml'
nicholas@2860 122 });
nicholas@2860 123 var dnlk = window.URL.createObjectURL(bb);
nicholas@2891 124 var a = document.createElement("a");
n@2913 125 document.body.appendChild(a)
nicholas@2891 126 a.href = dnlk;
nicholas@2891 127 a.download = "test.xml";
nicholas@2891 128 a.click();
nicholas@2891 129 window.URL.revokeObjectURL(dnlk);
n@2913 130 document.body.removeChild(a);
nicholas@2861 131 };
nicholas@2887 132 $s.validated = false;
nicholas@2887 133 $s.showValidationMessages = false;
nicholas@2887 134 $s.validate = function () {
nicholas@2887 135 var s = new XMLSerializer();
nicholas@2887 136 var Module = {
nicholas@2959 137 xml: "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" + s.serializeToString(specification.encode()),
nicholas@2887 138 schema: specification.getSchemaString(),
nicholas@2887 139 arguments: ["--noout", "--schema", 'test-schema.xsd', 'document.xml']
nicholas@2887 140 };
nicholas@2887 141 var xmllint = validateXML(Module);
nicholas@2887 142 console.log(xmllint);
nicholas@2887 143 if (xmllint != 'document.xml validates\n') {
nicholas@2887 144 $s.validated = false;
nicholas@2887 145 var list = $e[0].querySelector("#validation-error-list");
nicholas@2887 146 while (list.firstChild) {
nicholas@2887 147 list.removeChild(list.firstChild);
nicholas@2887 148 }
nicholas@2887 149 var errors = xmllint.split('\n');
nicholas@2887 150 errors = errors.slice(0, errors.length - 2);
nicholas@2887 151 errors.forEach(function (str) {
nicholas@2887 152 var li = document.createElement("li");
nicholas@2887 153 li.textContent = str;
nicholas@2887 154 list.appendChild(li);
nicholas@2887 155 });
nicholas@2887 156 } else {
nicholas@2887 157 $s.validated = true;
nicholas@2887 158 }
nicholas@2887 159 $s.showValidationMessages = true;
nicholas@2887 160 }
nicholas@2887 161 $s.hideValidationMessages = function () {
nicholas@2887 162 $s.showValidationMessages = false;
nicholas@2887 163 }
n@2911 164 $s.$watch(function () {
n@2911 165 return document.querySelectorAll("div.pageNode").length;
n@2911 166 }, $w.toggleDropdowns);
n@2911 167 $s.$watch(function () {
n@2911 168 return document.querySelectorAll("div.surveyentry").length;
n@2911 169 }, $w.toggleDropdowns);
n@2911 170 $s.$watch(function () {
n@2911 171 return document.querySelectorAll("div.interface").length;
n@2911 172 }, $w.toggleDropdowns);
n@2911 173 $s.$watch(function () {
n@2911 174 return document.querySelectorAll("div.audioelement").length;
n@2911 175 }, $w.toggleDropdowns);
nicholas@2851 176 }]);
nickjillings@1370 177
nicholas@2851 178 AngularInterface.controller("introduction", ['$scope', '$element', '$window', function ($s, $e, $w) {
nicholas@2851 179 $s.state = 0;
n@2908 180 $s.selected = undefined;
nicholas@2851 181 $s.next = function () {
nicholas@2851 182 $s.state++;
nicholas@2986 183 if ($s.state > 2 || $s.file) {
nicholas@2851 184 $s.hidePopup();
n@2908 185 $s.initialise($s.selected);
nicholas@2851 186 }
nicholas@2851 187 };
nicholas@2851 188 $s.back = function () {
nicholas@2851 189 $s.state--;
nicholas@2851 190 };
nicholas@2986 191
nicholas@2986 192 $s.$watch(function () {
nicholas@2986 193 return ($s.globalSchema !== undefined)
nicholas@2986 194 }, function () {
nicholas@2986 195 if ($s.globalSchema !== undefined && $s.state === 0) {
nicholas@2986 196 $s.state = 1;
nicholas@2986 197 }
nicholas@2986 198 })
nicholas@2986 199
nicholas@2851 200 $s.mouseover = function (name) {
nicholas@2864 201 var obj = $s.testSpecifications.interfaces.find(function (i) {
nicholas@2851 202 return i.name == name;
nicholas@2851 203 });
nicholas@2851 204 if (obj) {
nicholas@2851 205 $s.description = obj.description.en;
nicholas@2851 206 }
nicholas@2851 207 };
nicholas@2851 208 $s.initialise = function (name) {
nicholas@2885 209 var obj = $s.testSpecifications.interfaces.find(function (i) {
nicholas@2851 210 return i.name == name;
nicholas@2851 211 });
nicholas@2886 212 if (obj === undefined) {
nicholas@2886 213 throw ("Cannot find specification");
nicholas@2886 214 }
n@2908 215 if (typeof obj.template === "string") {
n@2908 216 get(obj.template).then(function (data) {
n@2908 217 $s.parseFile(data);
n@2908 218 }, function (err) {})
n@2908 219 } else {
n@2908 220 $s.setTestPrototype(obj);
n@2908 221 }
nicholas@2851 222 };
n@2908 223 $s.select = function (name) {
nicholas@2986 224 $s.selected = name;
nicholas@2986 225 }
nicholas@2986 226 // Get the test interface specifications
nicholas@2861 227 $s.file = undefined;
nicholas@2851 228 $s.description = "";
nicholas@2861 229
n@2908 230 $s.parseFile = function (f) {
n@2908 231 var p = new DOMParser();
n@2908 232 specification.decode(p.parseFromString(f, "text/xml"));
n@2908 233 $s.$apply();
n@2908 234 }
n@2908 235
nicholas@2861 236 $s.handleFiles = function ($event) {
nicholas@2861 237 $s.file = $event.currentTarget.files[0];
nicholas@2861 238 var r = new FileReader();
nicholas@2861 239 r.onload = function () {
n@2908 240 $s.parseFile(r.result);
nicholas@2862 241 };
nicholas@2861 242 r.readAsText($s.file);
nicholas@2861 243 };
nicholas@2851 244 }]);
nickjillings@1370 245
nicholas@2851 246 AngularInterface.controller("setup", ['$scope', '$element', '$window', function ($s, $e, $w) {
nicholas@2851 247 function initialise() {
nicholas@2851 248 if ($s.globalSchema) {
nicholas@2851 249 $s.schema = $s.globalSchema.querySelector("[name=setup]");
nickjillings@1385 250 }
nickjillings@1370 251 }
nicholas@2851 252 $s.schema = undefined;
nicholas@2851 253 $s.attributes = [];
nickjillings@1370 254
nicholas@2851 255 $s.$watch("globalSchema", initialise);
nicholas@2853 256 $s.$watch("specification.metrics.enabled.length", function () {
nicholas@2853 257 var metricsNode = document.getElementById("metricsNode");
nicholas@2853 258 if (!$s.specification.metrics) {
nicholas@2853 259 return;
nicholas@2853 260 }
nicholas@2853 261 metricsNode.querySelectorAll("input").forEach(function (DOM) {
nicholas@2853 262 DOM.checked = false;
nicholas@2853 263 });
nicholas@2853 264 $s.specification.metrics.enabled.forEach(function (metric) {
nicholas@2853 265 var DOM = metricsNode.querySelector("[value=" + metric + "]");
nicholas@2853 266 if (DOM) {
nicholas@2853 267 DOM.checked = true;
nicholas@2853 268 }
nicholas@2853 269 });
nicholas@2855 270 });
nicholas@2853 271
nicholas@2853 272 $s.enableMetric = function ($event) {
nicholas@2853 273 var metric = $event.currentTarget.value;
nicholas@2853 274 var index = specification.metrics.enabled.findIndex(function (a) {
nicholas@2853 275 return a == metric;
nicholas@2853 276 });
nicholas@2853 277 if ($event.currentTarget.checked) {
nicholas@2853 278 if (index == -1) {
nicholas@2853 279 specification.metrics.enabled.push(metric);
nicholas@2853 280 }
nicholas@2853 281 } else {
nicholas@2853 282 if (index >= 0) {
nicholas@2853 283 specification.metrics.enabled.splice(index, 1);
nicholas@2853 284 }
nicholas@2853 285 }
nicholas@2855 286 };
nicholas@2886 287
nicholas@2886 288 $s.configure = function () {}
nicholas@2886 289
nicholas@2886 290 $s.$watch("selectedTestPrototype", $s.configure);
n@2907 291
n@2907 292 $s.placeholder = function (name) {
n@2908 293 if ($s.schema) {
n@2908 294 var spec = $s.schema.querySelector("attribute[name=\"" + name + "\"]") || $w.specification.schema.querySelector("attribute[name=\"" + name + "\"]");
n@2908 295 var attr = spec.getAttribute("default");
n@2912 296 if (attr === null) {
n@2912 297 return "Not set";
n@2908 298 }
n@2908 299 return attr;
n@2907 300 }
n@2907 301 }
nicholas@2851 302 }]);
nicholas@2853 303
nicholas@2858 304 AngularInterface.controller("survey", ['$scope', '$element', '$window', function ($s, $e, $w) {
nicholas@2858 305 $s.addSurveyEntry = function () {
nicholas@2858 306 $s.survey.addOption();
nicholas@2858 307 };
nicholas@2858 308 $s.removeSurveyEntry = function (entry) {
nicholas@2858 309 var index = $s.survey.options.findIndex(function (a) {
nicholas@2858 310 return a == entry;
nicholas@2858 311 });
nicholas@2858 312 if (index === -1) {
nicholas@2858 313 throw ("Invalid Entry");
nicholas@2858 314 }
nicholas@2858 315 $s.survey.options.splice(index, 1);
nicholas@2858 316 };
nicholas@2858 317 }]);
nicholas@2858 318
nicholas@2853 319 AngularInterface.controller("surveyOption", ['$scope', '$element', '$window', function ($s, $e, $w) {
nicholas@2853 320
nicholas@2853 321 $s.removeOption = function (option) {
nicholas@2853 322 var index = $s.opt.options.findIndex(function (a) {
nicholas@2853 323 return a == option;
nicholas@2853 324 });
nicholas@2853 325 if (index === -1) {
nicholas@2853 326 throw ("Invalid option");
nicholas@2853 327 }
nicholas@2853 328 $s.opt.options.splice(index, 1);
nicholas@2853 329 };
nicholas@2853 330 $s.addOption = function () {
nicholas@2853 331 $s.opt.options.push({
nicholas@2853 332 name: "",
nicholas@2853 333 text: ""
nicholas@2853 334 });
nicholas@2855 335 };
nicholas@2857 336
nicholas@2857 337 $s.addCondition = function () {
nicholas@2857 338 $s.opt.conditions.push({
nicholas@2857 339 check: "equals",
nicholas@2857 340 value: "",
nicholas@2857 341 jumpToOnPass: undefined,
nicholas@2857 342 jumpToOnFail: undefined
nicholas@2857 343 });
nicholas@2857 344 };
nicholas@2857 345
nicholas@2857 346 $s.removeCondition = function (condition) {
nicholas@2857 347 var index = $s.opt.conditions.findIndex(function (c) {
nicholas@2857 348 return c == condition;
nicholas@2857 349 });
nicholas@2857 350 if (index === -1) {
nicholas@2857 351 throw ("Invalid Condition");
nicholas@2857 352 }
nicholas@2857 353 $s.opt.conditions.splice(index, 1);
nicholas@2857 354 };
nicholas@2855 355 }]);
nicholas@2855 356
nicholas@2855 357 AngularInterface.controller("interfaceNode", ['$scope', '$element', '$window', function ($s, $e, $w) {
nicholas@2855 358 $s.$watch("interface.options.length", function () {
nicholas@2855 359 if (!$s.interface || !$s.interface.options) {
nicholas@2855 360 return;
nicholas@2855 361 }
nicholas@2855 362 var options = $e[0].querySelector(".interfaceOptions").querySelectorAll(".attribute");
nicholas@2855 363 options.forEach(function (option) {
nicholas@2855 364 var name = option.getAttribute("name");
nicholas@2855 365 var index = $s.interface.options.findIndex(function (io) {
nicholas@2855 366 return io.name == name;
nicholas@2855 367 });
nicholas@2855 368 option.querySelector("input").checked = (index >= 0);
nicholas@2855 369 if (name == "scalerange" && index >= 0) {
nicholas@2855 370 option.querySelector("[name=min]").value = $s.interface.options[index].min;
nicholas@2855 371 option.querySelector("[name=max]").value = $s.interface.options[index].max;
nicholas@2855 372 }
nicholas@2855 373 });
nicholas@2855 374 });
nicholas@2855 375 $s.enableInterfaceOption = function ($event) {
nicholas@2855 376 var name = $event.currentTarget.parentElement.getAttribute("name");
nicholas@2855 377 var type = $event.currentTarget.parentElement.getAttribute("type");
nicholas@2855 378 var index = $s.interface.options.findIndex(function (io) {
nicholas@2855 379 return io.name == name;
nicholas@2855 380 });
nicholas@2855 381 if (index == -1 && $event.currentTarget.checked) {
nicholas@2855 382 var obj = $s.interface.options.push({
nicholas@2855 383 name: name,
nicholas@2855 384 type: type
nicholas@2855 385 });
nicholas@2855 386 if (name == "scalerange") {
nicholas@2855 387 obj.min = $event.currentTarget.parentElement.querySelector("[name=min]").value;
nicholas@2855 388 obj.max = $event.currentTarget.parentElement.querySelector("[name=max]").value;
nicholas@2855 389 }
nicholas@2855 390 } else if (index >= 0 && !$event.currentTarget.checked) {
nicholas@2855 391 $s.interface.options.splice(index, 1);
nicholas@2855 392 }
nicholas@2857 393 };
nicholas@2886 394 $s.scales = [];
nicholas@2857 395 $s.removeScale = function (scale) {
nicholas@2857 396 var index = $s.interface.scales.findIndex(function (s) {
nicholas@2857 397 return s == scale;
nicholas@2857 398 });
nicholas@2857 399 if (index >= 0) {
nicholas@2857 400 $s.interface.scales.splice(index, 1);
nicholas@2857 401 }
nicholas@2857 402 };
nicholas@2857 403 $s.addScale = function () {
nicholas@2857 404 $s.interface.scales.push({
nicholas@2857 405 position: undefined,
nicholas@2857 406 text: undefined
nicholas@2857 407 });
nicholas@2857 408 };
nicholas@2864 409 $s.clearScales = function () {
nicholas@2864 410 $s.interface.scales = [];
nicholas@2864 411 };
nicholas@2876 412 $s.useScales = function (scale) {
nicholas@2864 413 $s.clearScales();
nicholas@2876 414 scale.scales.forEach(function (s) {
nicholas@2864 415 $s.interface.scales.push(s);
nicholas@2864 416 });
nicholas@2886 417 $s.selectedScale = scale.name;
nicholas@2864 418 };
nicholas@2886 419 $s.selectedScale = undefined;
nicholas@2886 420
nicholas@2886 421 $s.configure = function () {
nicholas@2886 422 if ($s.selectedTestPrototype === undefined) {
nicholas@2886 423 return;
nicholas@2886 424 }
nicholas@2886 425 if ($s.selectedTestPrototype.checks && $s.selectedTestPrototype.checks.length >= 1) {
nicholas@2886 426 $s.selectedTestPrototype.checks.forEach(function (entry) {
nicholas@2886 427 var dom = $e[0].querySelector("[name=\"" + entry.name + "\"] input");
nicholas@2886 428 if (entry.support == "none") {
nicholas@2886 429 dom.checked = false;
nicholas@2886 430 dom.disabled = true;
nicholas@2886 431 }
nicholas@2886 432 });
nicholas@2886 433 }
nicholas@2886 434 if ($s.selectedTestPrototype.show && $s.selectedTestPrototype.show.length >= 1) {
nicholas@2886 435 $s.selectedTestPrototype.show.forEach(function (entry) {
nicholas@2886 436 var dom = $e[0].querySelector("[name=\"" + entry.name + "\"] input");
nicholas@2886 437 if (entry.support == "none") {
nicholas@2886 438 dom.checked = false;
nicholas@2886 439 dom.disabled = true;
nicholas@2886 440 }
nicholas@2886 441 });
nicholas@2886 442 }
nicholas@2886 443 if ($s.interface !== specification.interfaces) {
nicholas@2886 444 // Page specific interface nodes
nicholas@2886 445 if ($s.selectedTestPrototype.hasScales !== undefined && ($s.selectedTestPrototype.hasScales == "false" || $s.selectedTestPrototype.hasScales == false)) {
nicholas@2886 446 var elem = $e[0].querySelector("[name=\"scale-selection\"]")
nicholas@2886 447 elem.style.visibility = "hidden";
nicholas@2886 448 elem.style.height = "0px";
nicholas@2886 449 }
nicholas@2886 450 if ($s.selectedTestPrototype.scales && $s.selectedTestPrototype.show.length >= 1) {
nicholas@2886 451 $s.scales = [];
nicholas@2886 452 $s.selectedTestPrototype.scales.forEach(function (scalename) {
nicholas@2886 453 var obj = $s.testSpecifications.scales.find(function (a) {
nicholas@2886 454 return a.name == scalename;
nicholas@2886 455 });
nicholas@2886 456 $s.scales.push(obj);
nicholas@2886 457 });
nicholas@2886 458 if ($s.selectedTestPrototype.scales.includes($s.selectedScale) == false) {
nicholas@2886 459 $s.clearScales();
nicholas@2886 460 }
nicholas@2886 461 if ($s.scales.length == 1) {
nicholas@2886 462 $s.clearScales();
nicholas@2886 463 $s.useScales($s.scales[0]);
nicholas@2886 464 }
nicholas@2886 465 } else {
nicholas@2886 466 $s.scales = $s.testSpecifications.scales;
nicholas@2886 467 }
nicholas@2886 468 }
nicholas@2886 469 };
nicholas@2886 470
nicholas@2886 471 $s.$watch("selectedTestPrototype", $s.configure);
nicholas@2886 472 $s.configure();
nicholas@2853 473 }]);
nicholas@2859 474 AngularInterface.controller("page", ['$scope', '$element', '$window', function ($s, $e, $w) {
n@2907 475 $s.schema = $w.specification.schema.querySelector("element[name=\"page\"]");
n@2909 476 $s.page.label = $s.page.label || "default";
nicholas@2859 477 $s.addInterface = function () {
nicholas@2859 478 $s.page.addInterface();
nicholas@2859 479 };
nicholas@2859 480 $s.removeInterface = function (node) {
nicholas@2859 481 var index = $s.page.interfaces.findIndex(function (a) {
nicholas@2859 482 return a == node;
nicholas@2859 483 });
nicholas@2859 484 if (index === -1) {
nicholas@2859 485 throw ("Invalid node");
nicholas@2859 486 }
nicholas@2859 487 $s.page.interfaces.splice(index, 1);
nicholas@2859 488 };
nicholas@2859 489
nicholas@2859 490 $s.addCommentQuestion = function () {
nicholas@2859 491 $s.page.addCommentQuestion();
nicholas@2859 492 };
nicholas@2859 493 $s.removeCommentQuestion = function (node) {
nicholas@2859 494 var index = $s.page.commentQuestions.findIndex(function (a) {
nicholas@2859 495 return a == node;
nicholas@2859 496 });
nicholas@2859 497 if (index === -1) {
nicholas@2859 498 throw ("Invalid node");
nicholas@2859 499 }
nicholas@2859 500 $s.page.commentQuestions.splice(index, 1);
nicholas@2859 501 };
nicholas@2859 502 $s.addAudioElement = function () {
nicholas@2859 503 $s.page.addAudioElement();
nicholas@2859 504 };
nicholas@2859 505 $s.removeAudioElement = function (element) {
nicholas@2859 506 var index = $s.page.audioElements.findIndex(function (a) {
nicholas@2859 507 return a == element;
nicholas@2859 508 });
nicholas@2859 509 if (index === -1) {
nicholas@2859 510 throw ("Invalid node");
nicholas@2859 511 }
nicholas@2859 512 $s.page.audioElements.splice(index, 1);
nicholas@2859 513 };
n@2907 514
n@2907 515 $s.placeholder = function (name) {
n@2907 516 var spec = $s.schema.querySelector("attribute[name=\"" + name + "\"]") || $w.specification.schema.querySelector("attribute[name=\"" + name + "\"]");
n@2907 517 var attr = spec.getAttribute("default");
n@2912 518 if (attr === null) {
n@2912 519 return "Not set";
n@2907 520 }
n@2907 521 return attr;
n@2907 522 }
nicholas@2859 523 }]);