|
64 | 64 | * @param {String} id the identifier of the element we want. |
65 | 65 | */ |
66 | 66 | function vle_get_element(id) { |
67 | | - /* In the case of Moodle we are happy as long as the element is inside |
68 | | - something with the `formulation`-class. */ |
69 | 67 | let candidate = document.getElementById(id); |
70 | 68 | let iter = candidate; |
71 | | - while (iter && !iter.classList.contains('formulation')) { |
| 69 | + while (iter && !iter.classList.contains('formulation') && |
| 70 | + !iter.classList.contains('outcome')) { |
72 | 71 | iter = iter.parentElement; |
73 | 72 | } |
74 | | - if (iter && iter.classList.contains('formulation')) { |
| 73 | + if (iter && (iter.classList.contains('formulation') || |
| 74 | + iter.classList.contains('outcome'))) { |
75 | 75 | return candidate; |
76 | 76 | } |
77 | 77 |
|
|
99 | 99 | something with the `formulation`-class. */ |
100 | 100 | let initialcandidate = document.getElementById(srciframe); |
101 | 101 | let iter = initialcandidate; |
102 | | - while (iter && !iter.classList.contains('formulation')) { |
| 102 | + while (iter && !iter.classList.contains('formulation') && |
| 103 | + !iter.classList.contains('outcome')) { |
103 | 104 | iter = iter.parentElement; |
104 | 105 | } |
105 | | - if (iter && iter.classList.contains('formulation')) { |
| 106 | + if (iter && (iter.classList.contains('formulation') || |
| 107 | + iter.classList.contains('outcome'))) { |
106 | 108 | // iter now represents the borders of the question containing |
107 | 109 | // this IFRAME. |
108 | 110 | let possible = iter.querySelector('input[id$="_' + name + '"]'); |
|
313 | 315 | } |
314 | 316 | } |
315 | 317 |
|
| 318 | + // Transfer all data attributes of the input. Note that while most come from |
| 319 | + // STACK some might come from the VLE. For truly portable stuff only use ones |
| 320 | + // startting with "stack". Basically, the "initialValue" one comes from Moodle. |
| 321 | + response['input-dataset'] = {}; |
| 322 | + for (var k in input.dataset) { |
| 323 | + response['input-dataset'][k] = input.dataset[k]; |
| 324 | + } |
| 325 | + |
316 | 326 | // 3. Add listener for changes of this input. |
317 | 327 | if (input.id in INPUTS) { |
318 | 328 | if (msg.src in INPUTS[input.id]) { |
|
468 | 478 | } |
469 | 479 | } |
470 | 480 |
|
| 481 | + break; |
| 482 | + case 'register-button-listener': |
| 483 | + // 1. Find the element. |
| 484 | + element = vle_get_element(msg.target); |
| 485 | + |
| 486 | + if (element === null) { |
| 487 | + // Requested something that is not available. |
| 488 | + const ret = { |
| 489 | + version: 'STACK-JS:1.2.0', |
| 490 | + type: 'error', |
| 491 | + msg: 'Failed to find element: "' + msg.target + '"', |
| 492 | + tgt: msg.src |
| 493 | + }; |
| 494 | + IFRAMES[msg.src].contentWindow.postMessage(JSON.stringify(ret), '*'); |
| 495 | + return; |
| 496 | + } |
| 497 | + |
| 498 | + // 2. Add a listener, no need to do anything more |
| 499 | + // complicated than this. |
| 500 | + element.addEventListener('click', (event) => { |
| 501 | + let resp = { |
| 502 | + version: 'STACK-JS:1.2.0', |
| 503 | + type: 'button-click', |
| 504 | + name: msg.target, |
| 505 | + tgt: msg.src |
| 506 | + }; |
| 507 | + IFRAMES[msg.src].contentWindow.postMessage(JSON.stringify(resp), '*'); |
| 508 | + // These listeners will stop the submissions of buttons which might be a problem. |
| 509 | + event.preventDefault(); |
| 510 | + }); |
| 511 | + |
471 | 512 | break; |
472 | 513 | case 'toggle-visibility': |
473 | 514 | // 1. Find the element. |
|
0 commit comments