@pie-element/multiple-choice 9.12.7 → 9.12.8-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -209,11 +209,7 @@ var MultipleChoice = /*#__PURE__*/function (_HTMLElement) {
209
209
  value: function connectedCallback() {
210
210
  var _this2 = this;
211
211
 
212
- this._rerender();
213
-
214
- if (this._model && !this._model.autoplayAudioEnabled) {
215
- return;
216
- } // Observation: audio in Chrome will have the autoplay attribute,
212
+ this._rerender(); // Observation: audio in Chrome will have the autoplay attribute,
217
213
  // while other browsers will not have the autoplay attribute and will need a user interaction to play the audio
218
214
  // This workaround fixes the issue of audio being cached and played on any user interaction in Safari and Firefox
219
215
 
@@ -224,6 +220,8 @@ var MultipleChoice = /*#__PURE__*/function (_HTMLElement) {
224
220
  var audio = _this2.querySelector('audio');
225
221
 
226
222
  var isInsidePrompt = audio && audio.closest('#preview-prompt');
223
+ if (!_this2._model) return;
224
+ if (!_this2._model.autoplayAudioEnabled) return;
227
225
  if (audio && !isInsidePrompt) return;
228
226
  if (!audio) return;
229
227
 
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.js"],"names":["log","isComplete","session","model","audioComplete","autoplayAudioEnabled","completeAudioEnabled","value","choiceMode","minSelections","maxSelections","selections","length","MultipleChoice","_model","_session","_boundHandleKeyDown","handleKeyDown","bind","_keyboardEventsEnabled","_rerender","element","React","createElement","Main","onChoiceChanged","_onChange","onShowCorrectToggle","setAttribute","setLangAttribute","ReactDOM","render","keyboardEventsEnabled","enableKeyboardEvents","leading","trailing","_dispatchResponseChanged","dispatchEvent","SessionChangedEvent","tagName","toLowerCase","_dispatchModelSet","ModelSetEvent","undefined","language","lang","slice","s","data","info","document","id","Object","assign","style","position","top","width","height","display","justifyContent","alignItems","background","zIndex","img","src","alt","appendChild","observer","MutationObserver","mutationsList","forEach","mutation","type","audio","querySelector","isInsidePrompt","closest","_createAudioInfoToast","container","enableAudio","play","removeChild","removeEventListener","setTimeout","paused","addEventListener","handlePlaying","audioStartTime","Date","getTime","handleEnded","audioEndTime","disconnect","observe","childList","subtree","window","event","keyToIndex","key","numOffset","letterOffset","test","charCodeAt","choiceIndex","choices","currentValue","choiceId","newValue","selected","includes","selector","HTMLElement"],"mappings":"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","sourcesContent":["import Main from './main';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport debounce from 'lodash/debounce';\nimport debug from 'debug';\nimport { ModelSetEvent, SessionChangedEvent } from '@pie-framework/pie-player-events';\nimport { renderMath } from '@pie-lib/pie-toolbox/math-rendering';\nimport { updateSessionValue, updateSessionMetadata } from './session-updater';\n\nconst log = debug('pie-ui:multiple-choice');\n\nexport const isComplete = (session, model, audioComplete) => {\n const { autoplayAudioEnabled, completeAudioEnabled } = model || {};\n\n if (autoplayAudioEnabled && completeAudioEnabled && !audioComplete) {\n return false;\n }\n\n if (!session || !session.value) {\n return false;\n }\n\n const { choiceMode, minSelections = 1, maxSelections } = model || {};\n const selections = session.value.length || 0;\n\n if (choiceMode === 'radio') {\n return !!selections;\n }\n\n if (selections < minSelections || selections > maxSelections) {\n return false;\n }\n\n return true;\n};\n\nexport default class MultipleChoice extends HTMLElement {\n constructor() {\n super();\n this._model = null;\n this._session = null;\n this.audioComplete = false;\n this._boundHandleKeyDown = this.handleKeyDown.bind(this);\n this._keyboardEventsEnabled = false;\n\n this._rerender = debounce(\n () => {\n if (this._model && this._session) {\n var element = React.createElement(Main, {\n model: this._model,\n session: this._session,\n onChoiceChanged: this._onChange.bind(this),\n onShowCorrectToggle: this.onShowCorrectToggle.bind(this),\n });\n\n //TODO: aria-label is set in the _rerender because we need to change it when the model.choiceMode is updated. Consider revisiting the placement of the aria-label setting in the _rerender\n this.setAttribute(\n 'aria-label',\n this._model.choiceMode === 'radio' ? 'Multiple Choice Question' : 'Multiple Correct Answer Question',\n );\n this.setAttribute('role', 'region');\n this.setLangAttribute();\n\n ReactDOM.render(element, this, () => {\n log('render complete - render math');\n renderMath(this);\n });\n\n if (this._model.keyboardEventsEnabled === true && !this._keyboardEventsEnabled) {\n this.enableKeyboardEvents();\n }\n } else {\n log('skip');\n }\n },\n 50,\n { leading: false, trailing: true },\n );\n\n this._dispatchResponseChanged = debounce(() => {\n this.dispatchEvent(\n new SessionChangedEvent(this.tagName.toLowerCase(), isComplete(this._session, this._model, this.audioComplete)),\n );\n });\n\n this._dispatchModelSet = debounce(\n () => {\n this.dispatchEvent(\n new ModelSetEvent(\n this.tagName.toLowerCase(),\n isComplete(this._session, this._model),\n this._model !== undefined,\n ),\n );\n },\n 50,\n { leading: false, trailing: true },\n );\n }\n\n onShowCorrectToggle() {\n renderMath(this);\n }\n\n setLangAttribute() {\n const language = this._model && typeof this._model.language ? this._model.language : '';\n const lang = language ? language.slice(0, 2) : 'en';\n this.setAttribute('lang', lang);\n }\n\n set model(s) {\n this._model = s;\n this._rerender();\n this._dispatchModelSet();\n }\n\n get session() {\n return this._session;\n }\n\n set session(s) {\n this._session = s;\n this._rerender();\n //TODO: remove this session-changed should only be emit on user change\n this._dispatchResponseChanged();\n }\n\n _onChange(data) {\n updateSessionValue(this._session, this._model.choiceMode, data);\n this._dispatchResponseChanged();\n this._rerender();\n }\n\n _createAudioInfoToast() {\n const info = document.createElement('div');\n info.id = 'play-audio-info';\n\n Object.assign(info.style, {\n position: 'absolute',\n top: 0,\n width:'100%',\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n background: 'white',\n zIndex: '1000'\n });\n\n const img = document.createElement('img');\n img.src = 'https://student.assessment.renaissance.com/ce/quizenginecap/assets/img/playAppsSel.gif';\n img.alt = 'Click anywhere to enable audio autoplay';\n img.width = 500;\n img.height = 300;\n\n info.appendChild(img);\n return info;\n }\n\n connectedCallback() {\n this._rerender();\n\n if (this._model && !this._model.autoplayAudioEnabled) {\n return;\n }\n\n // Observation: audio in Chrome will have the autoplay attribute,\n // while other browsers will not have the autoplay attribute and will need a user interaction to play the audio\n // This workaround fixes the issue of audio being cached and played on any user interaction in Safari and Firefox\n const observer = new MutationObserver((mutationsList, observer) => {\n mutationsList.forEach((mutation) => {\n if (mutation.type === 'childList') {\n const audio = this.querySelector('audio');\n const isInsidePrompt = audio && audio.closest('#preview-prompt');\n\n if (audio && !isInsidePrompt) return;\n if (!audio) return;\n\n const info = this._createAudioInfoToast();\n const container = this.querySelector('#main-container');\n const enableAudio = () => {\n if (this.querySelector('#play-audio-info')) {\n audio.play();\n container.removeChild(info);\n }\n\n document.removeEventListener('click', enableAudio);\n };\n\n // if the audio is paused, it means the user has not interacted with the page yet and the audio will not play\n // FIX FOR SAFARI: play with a slight delay to check if autoplay was blocked\n setTimeout(() => {\n if (audio.paused && !this.querySelector('#play-audio-info')) {\n // add info message as a toast to enable audio playback\n container.appendChild(info);\n document.addEventListener('click', enableAudio);\n } else {\n document.removeEventListener('click', enableAudio);\n }\n }, 500);\n\n // we need to listen for the playing event to remove the toast in case the audio plays because of re-rendering\n const handlePlaying = () => {\n updateSessionMetadata(this._session, { audioStartTime: new Date().getTime() });\n \n const info = this.querySelector('#play-audio-info');\n if (info) {\n container.removeChild(info);\n }\n\n audio.removeEventListener('playing', handlePlaying);\n };\n\n audio.addEventListener('playing', handlePlaying);\n\n // we need to listen for the ended event to update the isComplete state\n const handleEnded = () => {\n updateSessionMetadata(this._session, { audioEndTime: new Date().getTime() });\n this.audioComplete = true;\n this._dispatchResponseChanged();\n audio.removeEventListener('ended', handleEnded);\n };\n\n audio.addEventListener('ended', handleEnded);\n\n observer.disconnect();\n }\n });\n });\n\n observer.observe(this, { childList: true, subtree: true });\n }\n\n enableKeyboardEvents() {\n if (!this._keyboardEventsEnabled) {\n window.addEventListener('keydown', this._boundHandleKeyDown);\n this._keyboardEventsEnabled = true;\n }\n }\n\n disconnectedCallback() {\n if (this._keyboardEventsEnabled) {\n window.removeEventListener('keydown', this._boundHandleKeyDown);\n this._keyboardEventsEnabled = false;\n }\n }\n\n /**\n * Handles global keyboard events for selecting or toggling multiple-choice answers.\n * Maps keys (1-9, 0, a-j, A-J) to choices and updates the session state accordingly.\n * Ensures valid key presses toggle or select the appropriate choice based on the model.\n */\n handleKeyDown(event) {\n if (!this._model || !this._session) {\n return;\n }\n\n const keyToIndex = (key) => {\n const numOffset = key >= '1' && key <= '9' ? key - '1' : key === '0' ? 9 : -1;\n const letterOffset = /^[a-jA-J]$/.test(key) ? key.toLowerCase().charCodeAt(0) - 'a'.charCodeAt(0) : -1;\n return numOffset >= 0 ? numOffset : letterOffset;\n };\n\n const choiceIndex = keyToIndex(event.key);\n\n if (choiceIndex === undefined || choiceIndex >= this._model.choices.length) {\n return;\n }\n\n const currentValue = this._session.value || [];\n const choiceId = this._model.choices[choiceIndex].value;\n\n const newValue = {\n value: choiceId,\n selected: !currentValue.includes(choiceId),\n selector: 'Keyboard',\n };\n\n this._onChange(newValue);\n }\n}\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../src/index.js"],"names":["log","isComplete","session","model","audioComplete","autoplayAudioEnabled","completeAudioEnabled","value","choiceMode","minSelections","maxSelections","selections","length","MultipleChoice","_model","_session","_boundHandleKeyDown","handleKeyDown","bind","_keyboardEventsEnabled","_rerender","element","React","createElement","Main","onChoiceChanged","_onChange","onShowCorrectToggle","setAttribute","setLangAttribute","ReactDOM","render","keyboardEventsEnabled","enableKeyboardEvents","leading","trailing","_dispatchResponseChanged","dispatchEvent","SessionChangedEvent","tagName","toLowerCase","_dispatchModelSet","ModelSetEvent","undefined","language","lang","slice","s","data","info","document","id","Object","assign","style","position","top","width","height","display","justifyContent","alignItems","background","zIndex","img","src","alt","appendChild","observer","MutationObserver","mutationsList","forEach","mutation","type","audio","querySelector","isInsidePrompt","closest","_createAudioInfoToast","container","enableAudio","play","removeChild","removeEventListener","setTimeout","paused","addEventListener","handlePlaying","audioStartTime","Date","getTime","handleEnded","audioEndTime","disconnect","observe","childList","subtree","window","event","keyToIndex","key","numOffset","letterOffset","test","charCodeAt","choiceIndex","choices","currentValue","choiceId","newValue","selected","includes","selector","HTMLElement"],"mappings":"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","sourcesContent":["import Main from './main';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport debounce from 'lodash/debounce';\nimport debug from 'debug';\nimport { ModelSetEvent, SessionChangedEvent } from '@pie-framework/pie-player-events';\nimport { renderMath } from '@pie-lib/pie-toolbox/math-rendering';\nimport { updateSessionValue, updateSessionMetadata } from './session-updater';\n\nconst log = debug('pie-ui:multiple-choice');\n\nexport const isComplete = (session, model, audioComplete) => {\n const { autoplayAudioEnabled, completeAudioEnabled } = model || {};\n\n if (autoplayAudioEnabled && completeAudioEnabled && !audioComplete) {\n return false;\n }\n\n if (!session || !session.value) {\n return false;\n }\n\n const { choiceMode, minSelections = 1, maxSelections } = model || {};\n const selections = session.value.length || 0;\n\n if (choiceMode === 'radio') {\n return !!selections;\n }\n\n if (selections < minSelections || selections > maxSelections) {\n return false;\n }\n\n return true;\n};\n\nexport default class MultipleChoice extends HTMLElement {\n constructor() {\n super();\n this._model = null;\n this._session = null;\n this.audioComplete = false;\n this._boundHandleKeyDown = this.handleKeyDown.bind(this);\n this._keyboardEventsEnabled = false;\n\n this._rerender = debounce(\n () => {\n if (this._model && this._session) {\n var element = React.createElement(Main, {\n model: this._model,\n session: this._session,\n onChoiceChanged: this._onChange.bind(this),\n onShowCorrectToggle: this.onShowCorrectToggle.bind(this),\n });\n\n //TODO: aria-label is set in the _rerender because we need to change it when the model.choiceMode is updated. Consider revisiting the placement of the aria-label setting in the _rerender\n this.setAttribute(\n 'aria-label',\n this._model.choiceMode === 'radio' ? 'Multiple Choice Question' : 'Multiple Correct Answer Question',\n );\n this.setAttribute('role', 'region');\n this.setLangAttribute();\n\n ReactDOM.render(element, this, () => {\n log('render complete - render math');\n renderMath(this);\n });\n\n if (this._model.keyboardEventsEnabled === true && !this._keyboardEventsEnabled) {\n this.enableKeyboardEvents();\n }\n } else {\n log('skip');\n }\n },\n 50,\n { leading: false, trailing: true },\n );\n\n this._dispatchResponseChanged = debounce(() => {\n this.dispatchEvent(\n new SessionChangedEvent(this.tagName.toLowerCase(), isComplete(this._session, this._model, this.audioComplete)),\n );\n });\n\n this._dispatchModelSet = debounce(\n () => {\n this.dispatchEvent(\n new ModelSetEvent(\n this.tagName.toLowerCase(),\n isComplete(this._session, this._model),\n this._model !== undefined,\n ),\n );\n },\n 50,\n { leading: false, trailing: true },\n );\n }\n\n onShowCorrectToggle() {\n renderMath(this);\n }\n\n setLangAttribute() {\n const language = this._model && typeof this._model.language ? this._model.language : '';\n const lang = language ? language.slice(0, 2) : 'en';\n this.setAttribute('lang', lang);\n }\n\n set model(s) {\n this._model = s;\n this._rerender();\n this._dispatchModelSet();\n }\n\n get session() {\n return this._session;\n }\n\n set session(s) {\n this._session = s;\n this._rerender();\n //TODO: remove this session-changed should only be emit on user change\n this._dispatchResponseChanged();\n }\n\n _onChange(data) {\n updateSessionValue(this._session, this._model.choiceMode, data);\n this._dispatchResponseChanged();\n this._rerender();\n }\n\n _createAudioInfoToast() {\n const info = document.createElement('div');\n info.id = 'play-audio-info';\n\n Object.assign(info.style, {\n position: 'absolute',\n top: 0,\n width:'100%',\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n background: 'white',\n zIndex: '1000'\n });\n\n const img = document.createElement('img');\n img.src = 'https://student.assessment.renaissance.com/ce/quizenginecap/assets/img/playAppsSel.gif';\n img.alt = 'Click anywhere to enable audio autoplay';\n img.width = 500;\n img.height = 300;\n\n info.appendChild(img);\n return info;\n }\n\n connectedCallback() {\n this._rerender();\n\n // Observation: audio in Chrome will have the autoplay attribute,\n // while other browsers will not have the autoplay attribute and will need a user interaction to play the audio\n // This workaround fixes the issue of audio being cached and played on any user interaction in Safari and Firefox\n const observer = new MutationObserver((mutationsList, observer) => {\n mutationsList.forEach((mutation) => {\n if (mutation.type === 'childList') {\n const audio = this.querySelector('audio');\n const isInsidePrompt = audio && audio.closest('#preview-prompt');\n\n if (!this._model) return;\n if (!this._model.autoplayAudioEnabled) return;\n if (audio && !isInsidePrompt) return;\n if (!audio) return;\n\n const info = this._createAudioInfoToast();\n const container = this.querySelector('#main-container');\n const enableAudio = () => {\n if (this.querySelector('#play-audio-info')) {\n audio.play();\n container.removeChild(info);\n }\n\n document.removeEventListener('click', enableAudio);\n };\n\n // if the audio is paused, it means the user has not interacted with the page yet and the audio will not play\n // FIX FOR SAFARI: play with a slight delay to check if autoplay was blocked\n setTimeout(() => {\n if (audio.paused && !this.querySelector('#play-audio-info')) {\n // add info message as a toast to enable audio playback\n container.appendChild(info);\n document.addEventListener('click', enableAudio);\n } else {\n document.removeEventListener('click', enableAudio);\n }\n }, 500);\n\n // we need to listen for the playing event to remove the toast in case the audio plays because of re-rendering\n const handlePlaying = () => {\n updateSessionMetadata(this._session, { audioStartTime: new Date().getTime() });\n \n const info = this.querySelector('#play-audio-info');\n if (info) {\n container.removeChild(info);\n }\n\n audio.removeEventListener('playing', handlePlaying);\n };\n\n audio.addEventListener('playing', handlePlaying);\n\n // we need to listen for the ended event to update the isComplete state\n const handleEnded = () => {\n updateSessionMetadata(this._session, { audioEndTime: new Date().getTime() });\n this.audioComplete = true;\n this._dispatchResponseChanged();\n audio.removeEventListener('ended', handleEnded);\n };\n\n audio.addEventListener('ended', handleEnded);\n\n observer.disconnect();\n }\n });\n });\n\n observer.observe(this, { childList: true, subtree: true });\n }\n\n enableKeyboardEvents() {\n if (!this._keyboardEventsEnabled) {\n window.addEventListener('keydown', this._boundHandleKeyDown);\n this._keyboardEventsEnabled = true;\n }\n }\n\n disconnectedCallback() {\n if (this._keyboardEventsEnabled) {\n window.removeEventListener('keydown', this._boundHandleKeyDown);\n this._keyboardEventsEnabled = false;\n }\n }\n\n /**\n * Handles global keyboard events for selecting or toggling multiple-choice answers.\n * Maps keys (1-9, 0, a-j, A-J) to choices and updates the session state accordingly.\n * Ensures valid key presses toggle or select the appropriate choice based on the model.\n */\n handleKeyDown(event) {\n if (!this._model || !this._session) {\n return;\n }\n\n const keyToIndex = (key) => {\n const numOffset = key >= '1' && key <= '9' ? key - '1' : key === '0' ? 9 : -1;\n const letterOffset = /^[a-jA-J]$/.test(key) ? key.toLowerCase().charCodeAt(0) - 'a'.charCodeAt(0) : -1;\n return numOffset >= 0 ? numOffset : letterOffset;\n };\n\n const choiceIndex = keyToIndex(event.key);\n\n if (choiceIndex === undefined || choiceIndex >= this._model.choices.length) {\n return;\n }\n\n const currentValue = this._session.value || [];\n const choiceId = this._model.choices[choiceIndex].value;\n\n const newValue = {\n value: choiceId,\n selected: !currentValue.includes(choiceId),\n selector: 'Keyboard',\n };\n\n this._onChange(newValue);\n }\n}\n"],"file":"index.js"}
package/module/element.js CHANGED
@@ -13209,14 +13209,13 @@ class MultipleChoice extends HTMLElement {
13209
13209
  }
13210
13210
  connectedCallback() {
13211
13211
  this._rerender();
13212
- if (this._model && !this._model.autoplayAudioEnabled) {
13213
- return;
13214
- }
13215
13212
  const observer = new MutationObserver((mutationsList, observer) => {
13216
13213
  mutationsList.forEach(mutation => {
13217
13214
  if (mutation.type === 'childList') {
13218
13215
  const audio = this.querySelector('audio');
13219
13216
  const isInsidePrompt = audio && audio.closest('#preview-prompt');
13217
+ if (!this._model) return;
13218
+ if (!this._model.autoplayAudioEnabled) return;
13220
13219
  if (audio && !isInsidePrompt) return;
13221
13220
  if (!audio) return;
13222
13221
  const info = this._createAudioInfoToast();
package/module/index.html CHANGED
@@ -2,7 +2,7 @@
2
2
  <!doctype html>
3
3
  <html>
4
4
  <head>
5
- <title>@pie-element/multiple-choice@9.12.6</title>
5
+ <title>@pie-element/multiple-choice@9.12.7</title>
6
6
  <script
7
7
  type="module"
8
8
  src="https://cdn.jsdelivr.net/npm/@pslb/demo-el@^1.0.0/dist/demo-el/demo-el.esm.js"></script>
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pie-element/multiple-choice",
3
- "version": "9.12.6",
3
+ "version": "9.12.7",
4
4
  "modules": [
5
5
  {
6
6
  "name": "@pie-lib/pie-toolbox-math-rendering-module",
package/module/print.html CHANGED
@@ -2,7 +2,7 @@
2
2
  <!doctype html>
3
3
  <html>
4
4
  <head>
5
- <title>@pie-element/multiple-choice@9.12.6</title>
5
+ <title>@pie-element/multiple-choice@9.12.7</title>
6
6
  <link
7
7
  href="https://fonts.googleapis.com/css?family=Roboto&display=swap"
8
8
  rel="stylesheet"
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pie-element/multiple-choice",
3
3
  "repository": "pie-framework/pie-elements",
4
- "version": "9.12.7",
4
+ "version": "9.12.8-next.2+959a39e31",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -19,7 +19,7 @@
19
19
  "react-test-renderer": "^16.3.2",
20
20
  "react-transition-group": "^2.3.1"
21
21
  },
22
- "gitHead": "a765ec82fb15f75b58c3f626c7728470813c89bc",
22
+ "gitHead": "959a39e31af790462a237b9e533f66cee138c1ba",
23
23
  "scripts": {
24
24
  "postpublish": "../../scripts/postpublish"
25
25
  },