@pie-element/hotspot 7.6.8-next.13 → 7.6.8-next.3

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.
@@ -58,8 +58,7 @@ function model(question, session, env) {
58
58
  language = normalizedQuestion.language,
59
59
  fontSizeFactor = normalizedQuestion.fontSizeFactor,
60
60
  autoplayAudioEnabled = normalizedQuestion.autoplayAudioEnabled,
61
- completeAudioEnabled = normalizedQuestion.completeAudioEnabled,
62
- customAudioButton = normalizedQuestion.customAudioButton;
61
+ completeAudioEnabled = normalizedQuestion.completeAudioEnabled;
63
62
 
64
63
  var _ref = shapes || {},
65
64
  rectangles = _ref.rectangles,
@@ -83,7 +82,6 @@ function model(question, session, env) {
83
82
  fontSizeFactor: fontSizeFactor,
84
83
  autoplayAudioEnabled: autoplayAudioEnabled,
85
84
  completeAudioEnabled: completeAudioEnabled,
86
- customAudioButton: customAudioButton,
87
85
  shapes: _objectSpread(_objectSpread({}, shapes), {}, {
88
86
  // eslint-disable-next-line no-unused-vars
89
87
  rectangles: (rectangles || []).map(function (_ref2) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.js"],"names":["log","normalize","question","defaults","model","session","env","normalizedQuestion","imageUrl","dimensions","hotspotColor","hoverOutlineColor","selectedHotspotColor","multipleCorrect","outlineColor","partialScoring","prompt","shapes","language","fontSizeFactor","autoplayAudioEnabled","completeAudioEnabled","customAudioButton","rectangles","polygons","circles","shouldIncludeCorrectResponse","mode","role","Promise","resolve","out","disabled","map","index","correct","rectProps","polyProps","circleProps","responseCorrect","undefined","extraCSSRules","rationale","rationaleEnabled","teacherInstructions","teacherInstructionsEnabled","promptEnabled","strokeWidth","createDefaultModel","getScore","config","answers","partialScoringEnabled","enabled","correctAnswers","selectedChoices","choices","correctChoices","filter","choice","forEach","shape","selected","answer","id","correctlySelected","extraAnswers","length","total","str","toFixed","parseFloat","outcome","score","empty","returnShapesCorrect","i","push","createCorrectResponseSession","rectangleCorrect","polygonsCorrect","circlesCorrect","getInnerText","html","replaceAll","getContent","replace","validate","minShapes","maxShapes","maxSelections","errors","field","required","allShapes","Object","values","reduce","acc","nbOfSelections","nbOfShapes","selections"],"mappings":"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","sourcesContent":["import debug from 'debug';\nimport isEmpty from 'lodash/isEmpty';\nimport { partialScoring } from '@pie-lib/pie-toolbox/controller-utils';\n\nimport { isResponseCorrect } from './utils';\n\nimport defaults from './defaults';\n\nconst log = debug('pie-elements:hotspot:controller');\n\nexport const normalize = (question) => ({\n ...defaults,\n ...question,\n});\n\nexport function model(question, session, env) {\n const normalizedQuestion = normalize(question);\n const {\n imageUrl,\n dimensions,\n hotspotColor,\n hoverOutlineColor,\n selectedHotspotColor,\n multipleCorrect,\n outlineColor,\n partialScoring,\n prompt,\n shapes,\n language,\n fontSizeFactor,\n autoplayAudioEnabled,\n completeAudioEnabled,\n customAudioButton\n } = normalizedQuestion;\n const { rectangles, polygons, circles } = shapes || {};\n\n const shouldIncludeCorrectResponse = env.mode === 'evaluate' || (env.role === 'instructor' && env.mode === 'view');\n\n return new Promise((resolve) => {\n const out = {\n disabled: env.mode !== 'gather',\n mode: env.mode,\n dimensions,\n imageUrl,\n outlineColor,\n hotspotColor,\n hoverOutlineColor,\n selectedHotspotColor,\n multipleCorrect,\n partialScoring,\n language,\n fontSizeFactor,\n autoplayAudioEnabled,\n completeAudioEnabled,\n customAudioButton,\n shapes: {\n ...shapes,\n // eslint-disable-next-line no-unused-vars\n rectangles: (rectangles || []).map(({ index, correct, ...rectProps }) =>\n shouldIncludeCorrectResponse ? { correct, ...rectProps } : { ...rectProps }\n ),\n // eslint-disable-next-line no-unused-vars\n polygons: (polygons || []).map(({ index, correct, ...polyProps }) =>\n shouldIncludeCorrectResponse ? { correct, ...polyProps } : {...polyProps }\n ),\n // eslint-disable-next-line no-unused-vars\n circles: (circles || []).map(({ index, correct, ...circleProps }) =>\n\n shouldIncludeCorrectResponse ? { correct, ...circleProps } : { ...circleProps }\n ),\n\n },\n responseCorrect: env.mode === 'evaluate' ? isResponseCorrect(normalizedQuestion, session) : undefined,\n extraCSSRules: normalizedQuestion.extraCSSRules,\n };\n\n if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {\n out.rationale = normalizedQuestion.rationaleEnabled ? normalizedQuestion.rationale : null;\n out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled\n ? normalizedQuestion.teacherInstructions\n : null;\n } else {\n out.rationale = null;\n out.teacherInstructions = null;\n }\n\n out.prompt = normalizedQuestion.promptEnabled ? prompt : null;\n out.strokeWidth = normalizedQuestion.strokeWidth;\n\n resolve(out);\n });\n}\n\nexport const createDefaultModel = (model = {}) =>\n new Promise((resolve) => {\n resolve({\n ...defaults,\n ...model,\n });\n });\n\nconst getScore = (config, session, env = {}) => {\n const { answers } = session || {};\n\n if (!config.shapes || (!config.shapes.rectangles && !config.shapes.polygons && !config.shapes.circles)) {\n return 0;\n }\n\n const { shapes: { rectangles = [], polygons = [], circles = [] } = {} } = config;\n const partialScoringEnabled = partialScoring.enabled(config, env);\n\n if (!partialScoringEnabled) {\n return isResponseCorrect(config, session) ? 1 : 0;\n }\n\n let correctAnswers = 0;\n let selectedChoices = 0;\n\n const choices = [...rectangles, ...polygons, ...circles];\n\n const correctChoices = choices.filter((choice) => choice.correct);\n\n choices.forEach((shape) => {\n const selected = answers && answers.filter((answer) => answer.id === shape.id)[0];\n const correctlySelected = shape.correct && selected;\n\n if (selected) {\n selectedChoices += 1;\n }\n\n if (correctlySelected) {\n correctAnswers += 1;\n }\n });\n\n const extraAnswers = selectedChoices > correctChoices.length ? selectedChoices - correctChoices.length : 0;\n\n const total = correctChoices.length === 0 ? 1 : correctChoices.length;\n const str = ((correctAnswers - extraAnswers) / total).toFixed(2);\n\n return str < 0 ? 0 : parseFloat(str);\n};\n\nexport function outcome(config, session, env = {}) {\n return new Promise((resolve) => {\n log('outcome...');\n\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true });\n }\n\n if (session.answers) {\n const score = getScore(config, session, env);\n resolve({ score });\n } else {\n resolve({ score: 0, empty: true });\n }\n });\n}\n\nconst returnShapesCorrect = (shapes) => {\n let answers = [];\n\n shapes.forEach((i) => {\n const { correct, id } = i;\n if (correct) {\n answers.push({ id });\n }\n });\n return answers;\n};\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const { shapes: { rectangles = [], circles = [], polygons = {} } = {} } = question;\n\n const rectangleCorrect = returnShapesCorrect(rectangles);\n const polygonsCorrect = returnShapesCorrect(polygons);\n const circlesCorrect = returnShapesCorrect(circles);\n\n resolve({\n answers: [...rectangleCorrect, ...polygonsCorrect, ...circlesCorrect],\n id: '1',\n });\n } else {\n resolve(null);\n }\n });\n};\n\n// remove all html tags\nconst getInnerText = (html) => (html || '').replaceAll(/<[^>]*>/g, '');\n\n// remove all html tags except img and iframe\nconst getContent = (html) => (html || '').replace(/(<(?!img|iframe)([^>]+)>)/gi, '');\n\nexport const validate = (model = {}, config = {}) => {\n const { shapes } = model;\n const { minShapes = 2, maxShapes, maxSelections } = config;\n const errors = {};\n\n ['teacherInstructions', 'prompt', 'rationale'].forEach((field) => {\n if (config[field]?.required && !getContent(model[field])) {\n errors[field] = 'This field is required.';\n }\n });\n\n const allShapes = Object.values(shapes || {}).reduce((acc, shape) => [...acc, ...shape], []);\n\n const nbOfSelections = (allShapes || []).reduce((acc, shape) => (shape.correct ? acc + 1 : acc), 0);\n\n const nbOfShapes = (allShapes || []).length;\n\n if (nbOfShapes < minShapes) {\n errors.shapes = `There should be at least ${minShapes} shapes defined.`;\n } else if (nbOfShapes > maxShapes) {\n errors.shapes = `No more than ${maxShapes} shapes should be defined.`;\n }\n\n if (nbOfSelections < 1) {\n errors.selections = 'There should be at least 1 shape selected.';\n } else if (nbOfSelections > maxSelections) {\n errors.selections = `No more than ${maxSelections} shapes should be selected.`;\n }\n\n return errors;\n};\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../src/index.js"],"names":["log","normalize","question","defaults","model","session","env","normalizedQuestion","imageUrl","dimensions","hotspotColor","hoverOutlineColor","selectedHotspotColor","multipleCorrect","outlineColor","partialScoring","prompt","shapes","language","fontSizeFactor","autoplayAudioEnabled","completeAudioEnabled","rectangles","polygons","circles","shouldIncludeCorrectResponse","mode","role","Promise","resolve","out","disabled","map","index","correct","rectProps","polyProps","circleProps","responseCorrect","undefined","extraCSSRules","rationale","rationaleEnabled","teacherInstructions","teacherInstructionsEnabled","promptEnabled","strokeWidth","createDefaultModel","getScore","config","answers","partialScoringEnabled","enabled","correctAnswers","selectedChoices","choices","correctChoices","filter","choice","forEach","shape","selected","answer","id","correctlySelected","extraAnswers","length","total","str","toFixed","parseFloat","outcome","score","empty","returnShapesCorrect","i","push","createCorrectResponseSession","rectangleCorrect","polygonsCorrect","circlesCorrect","getInnerText","html","replaceAll","getContent","replace","validate","minShapes","maxShapes","maxSelections","errors","field","required","allShapes","Object","values","reduce","acc","nbOfSelections","nbOfShapes","selections"],"mappings":"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","sourcesContent":["import debug from 'debug';\nimport isEmpty from 'lodash/isEmpty';\nimport { partialScoring } from '@pie-lib/pie-toolbox/controller-utils';\n\nimport { isResponseCorrect } from './utils';\n\nimport defaults from './defaults';\n\nconst log = debug('pie-elements:hotspot:controller');\n\nexport const normalize = (question) => ({\n ...defaults,\n ...question,\n});\n\nexport function model(question, session, env) {\n const normalizedQuestion = normalize(question);\n const {\n imageUrl,\n dimensions,\n hotspotColor,\n hoverOutlineColor,\n selectedHotspotColor,\n multipleCorrect,\n outlineColor,\n partialScoring,\n prompt,\n shapes,\n language,\n fontSizeFactor,\n autoplayAudioEnabled,\n completeAudioEnabled\n } = normalizedQuestion;\n const { rectangles, polygons, circles } = shapes || {};\n\n const shouldIncludeCorrectResponse = env.mode === 'evaluate' || (env.role === 'instructor' && env.mode === 'view');\n\n return new Promise((resolve) => {\n const out = {\n disabled: env.mode !== 'gather',\n mode: env.mode,\n dimensions,\n imageUrl,\n outlineColor,\n hotspotColor,\n hoverOutlineColor,\n selectedHotspotColor,\n multipleCorrect,\n partialScoring,\n language,\n fontSizeFactor,\n autoplayAudioEnabled,\n completeAudioEnabled,\n shapes: {\n ...shapes,\n // eslint-disable-next-line no-unused-vars\n rectangles: (rectangles || []).map(({ index, correct, ...rectProps }) =>\n shouldIncludeCorrectResponse ? { correct, ...rectProps } : { ...rectProps }\n ),\n // eslint-disable-next-line no-unused-vars\n polygons: (polygons || []).map(({ index, correct, ...polyProps }) =>\n shouldIncludeCorrectResponse ? { correct, ...polyProps } : {...polyProps }\n ),\n // eslint-disable-next-line no-unused-vars\n circles: (circles || []).map(({ index, correct, ...circleProps }) => \n \n shouldIncludeCorrectResponse ? { correct, ...circleProps } : { ...circleProps }\n ),\n \n },\n responseCorrect: env.mode === 'evaluate' ? isResponseCorrect(normalizedQuestion, session) : undefined,\n extraCSSRules: normalizedQuestion.extraCSSRules,\n };\n\n if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {\n out.rationale = normalizedQuestion.rationaleEnabled ? normalizedQuestion.rationale : null;\n out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled\n ? normalizedQuestion.teacherInstructions\n : null;\n } else {\n out.rationale = null;\n out.teacherInstructions = null;\n }\n\n out.prompt = normalizedQuestion.promptEnabled ? prompt : null;\n out.strokeWidth = normalizedQuestion.strokeWidth;\n\n resolve(out);\n });\n}\n\nexport const createDefaultModel = (model = {}) =>\n new Promise((resolve) => {\n resolve({\n ...defaults,\n ...model,\n });\n });\n\nconst getScore = (config, session, env = {}) => {\n const { answers } = session || {};\n\n if (!config.shapes || (!config.shapes.rectangles && !config.shapes.polygons && !config.shapes.circles)) {\n return 0;\n }\n\n const { shapes: { rectangles = [], polygons = [], circles = [] } = {} } = config;\n const partialScoringEnabled = partialScoring.enabled(config, env);\n\n if (!partialScoringEnabled) {\n return isResponseCorrect(config, session) ? 1 : 0;\n }\n\n let correctAnswers = 0;\n let selectedChoices = 0;\n\n const choices = [...rectangles, ...polygons, ...circles];\n\n const correctChoices = choices.filter((choice) => choice.correct);\n\n choices.forEach((shape) => {\n const selected = answers && answers.filter((answer) => answer.id === shape.id)[0];\n const correctlySelected = shape.correct && selected;\n\n if (selected) {\n selectedChoices += 1;\n }\n\n if (correctlySelected) {\n correctAnswers += 1;\n }\n });\n\n const extraAnswers = selectedChoices > correctChoices.length ? selectedChoices - correctChoices.length : 0;\n\n const total = correctChoices.length === 0 ? 1 : correctChoices.length;\n const str = ((correctAnswers - extraAnswers) / total).toFixed(2);\n\n return str < 0 ? 0 : parseFloat(str);\n};\n\nexport function outcome(config, session, env = {}) {\n return new Promise((resolve) => {\n log('outcome...');\n\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true });\n }\n\n if (session.answers) {\n const score = getScore(config, session, env);\n resolve({ score });\n } else {\n resolve({ score: 0, empty: true });\n }\n });\n}\n\nconst returnShapesCorrect = (shapes) => {\n let answers = [];\n\n shapes.forEach((i) => {\n const { correct, id } = i;\n if (correct) {\n answers.push({ id });\n }\n });\n return answers;\n};\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const { shapes: { rectangles = [], circles = [], polygons = {} } = {} } = question;\n\n const rectangleCorrect = returnShapesCorrect(rectangles);\n const polygonsCorrect = returnShapesCorrect(polygons);\n const circlesCorrect = returnShapesCorrect(circles);\n\n resolve({\n answers: [...rectangleCorrect, ...polygonsCorrect, ...circlesCorrect],\n id: '1',\n });\n } else {\n resolve(null);\n }\n });\n};\n\n// remove all html tags\nconst getInnerText = (html) => (html || '').replaceAll(/<[^>]*>/g, '');\n\n// remove all html tags except img and iframe\nconst getContent = (html) => (html || '').replace(/(<(?!img|iframe)([^>]+)>)/gi, '');\n\nexport const validate = (model = {}, config = {}) => {\n const { shapes } = model;\n const { minShapes = 2, maxShapes, maxSelections } = config;\n const errors = {};\n\n ['teacherInstructions', 'prompt', 'rationale'].forEach((field) => {\n if (config[field]?.required && !getContent(model[field])) {\n errors[field] = 'This field is required.';\n }\n });\n\n const allShapes = Object.values(shapes || {}).reduce((acc, shape) => [...acc, ...shape], []);\n\n const nbOfSelections = (allShapes || []).reduce((acc, shape) => (shape.correct ? acc + 1 : acc), 0);\n\n const nbOfShapes = (allShapes || []).length;\n\n if (nbOfShapes < minShapes) {\n errors.shapes = `There should be at least ${minShapes} shapes defined.`;\n } else if (nbOfShapes > maxShapes) {\n errors.shapes = `No more than ${maxShapes} shapes should be defined.`;\n }\n\n if (nbOfSelections < 1) {\n errors.selections = 'There should be at least 1 shape selected.';\n } else if (nbOfSelections > maxSelections) {\n errors.selections = `No more than ${maxSelections} shapes should be selected.`;\n }\n\n return errors;\n};\n"],"file":"index.js"}
@@ -29,8 +29,7 @@ export function model(question, session, env) {
29
29
  language,
30
30
  fontSizeFactor,
31
31
  autoplayAudioEnabled,
32
- completeAudioEnabled,
33
- customAudioButton
32
+ completeAudioEnabled
34
33
  } = normalizedQuestion;
35
34
  const { rectangles, polygons, circles } = shapes || {};
36
35
 
@@ -52,7 +51,6 @@ export function model(question, session, env) {
52
51
  fontSizeFactor,
53
52
  autoplayAudioEnabled,
54
53
  completeAudioEnabled,
55
- customAudioButton,
56
54
  shapes: {
57
55
  ...shapes,
58
56
  // eslint-disable-next-line no-unused-vars
@@ -64,11 +62,11 @@ export function model(question, session, env) {
64
62
  shouldIncludeCorrectResponse ? { correct, ...polyProps } : {...polyProps }
65
63
  ),
66
64
  // eslint-disable-next-line no-unused-vars
67
- circles: (circles || []).map(({ index, correct, ...circleProps }) =>
68
-
65
+ circles: (circles || []).map(({ index, correct, ...circleProps }) =>
66
+
69
67
  shouldIncludeCorrectResponse ? { correct, ...circleProps } : { ...circleProps }
70
68
  ),
71
-
69
+
72
70
  },
73
71
  responseCorrect: env.mode === 'evaluate' ? isResponseCorrect(normalizedQuestion, session) : undefined,
74
72
  extraCSSRules: normalizedQuestion.extraCSSRules,
@@ -260,25 +260,6 @@
260
260
  "type": "boolean",
261
261
  "title": "completeAudioEnabled"
262
262
  },
263
- "customAudioButton": {
264
- "description": "Indicates if the audio should be replaced with a custom audio button\n playImage: image url for the play state\n pauseImage: image url for the pause state",
265
- "type": "object",
266
- "properties": {
267
- "playImage": {
268
- "type": "string",
269
- "title": "playImage"
270
- },
271
- "pauseImage": {
272
- "type": "string",
273
- "title": "pauseImage"
274
- }
275
- },
276
- "required": [
277
- "pauseImage",
278
- "playImage"
279
- ],
280
- "title": "customAudioButton"
281
- },
282
263
  "id": {
283
264
  "description": "Identifier to identify the Pie Element in html markup, Must be unique within a pie item config.",
284
265
  "type": "string",
@@ -190,18 +190,6 @@ Indicates if the audio for the prompt should autoplay
190
190
 
191
191
  Indicates if the audio should reach the end before the item can be marked as 'complete'
192
192
 
193
- # `customAudioButton` (object)
194
-
195
- Indicates if the audio should be replaced with a custom audio button
196
- playImage: image url for the play state
197
- pauseImage: image url for the pause state
198
-
199
- Properties of the `customAudioButton` object:
200
-
201
- ## `playImage` (string, required)
202
-
203
- ## `pauseImage` (string, required)
204
-
205
193
  # `id` (string, required)
206
194
 
207
195
  Identifier to identify the Pie Element in html markup, Must be unique within a pie item config.
@@ -131,12 +131,13 @@ var HotspotComponent = /*#__PURE__*/function (_React$Component) {
131
131
  language = _this$props$model.language,
132
132
  fontSizeFactor = _this$props$model.fontSizeFactor,
133
133
  autoplayAudioEnabled = _this$props$model.autoplayAudioEnabled,
134
- customAudioButton = _this$props$model.customAudioButton,
135
134
  onSelectChoice = _this$props.onSelectChoice,
136
135
  classes = _this$props.classes;
137
136
  var showCorrect = this.state.showCorrect;
138
137
  var isEvaluateMode = mode === 'evaluate';
139
- var showCorrectAnswerToggle = isEvaluateMode && !responseCorrect;
138
+ var showCorrectAnswerToggle = isEvaluateMode && !responseCorrect; // Safari, Firefox, and Edge do not support autoplay audio smoothly in our use case
139
+
140
+ var addAutoplayAudio = autoplayAudioEnabled && !(/Safari|Firefox|Edg/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent));
140
141
  return /*#__PURE__*/_react["default"].createElement(_renderUi.UiLayout, {
141
142
  extraCSSRules: extraCSSRules,
142
143
  id: 'main-container',
@@ -154,8 +155,7 @@ var HotspotComponent = /*#__PURE__*/function (_React$Component) {
154
155
  })), prompt && /*#__PURE__*/_react["default"].createElement(_renderUi.PreviewPrompt, {
155
156
  className: "prompt",
156
157
  prompt: prompt,
157
- autoplayAudioEnabled: autoplayAudioEnabled,
158
- customAudioButton: customAudioButton
158
+ autoplayAudioEnabled: addAutoplayAudio
159
159
  }), showCorrectAnswerToggle && /*#__PURE__*/_react["default"].createElement(_correctAnswerToggle.CorrectAnswerToggle, {
160
160
  show: showCorrectAnswerToggle,
161
161
  toggled: showCorrect,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hotspot/index.jsx"],"names":["HotspotComponent","props","showCorrect","state","setState","observer","scale","MutationObserver","mutations","forEach","target","document","getElementById","style","cssText","zoom","substring","indexOf","lastIndexOf","zoomParsed","replace","newScale","parseFloat","observe","attributes","attributeFilter","disconnect","session","model","disabled","extraCSSRules","imageUrl","prompt","mode","multipleCorrect","shapes","outlineColor","hotspotColor","hoverOutlineColor","selectedHotspotColor","dimensions","rationale","teacherInstructions","strokeWidth","responseCorrect","language","fontSizeFactor","autoplayAudioEnabled","customAudioButton","onSelectChoice","classes","isEvaluateMode","showCorrectAnswerToggle","main","hidden","visible","collapsible","onToggle","bind","React","Component","propTypes","PropTypes","object","isRequired","func","defaultProps","styles","theme","color","text","backgroundColor","background","position","marginBottom","spacing","unit","fontSize"],"mappings":"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","sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport { CorrectAnswerToggle } from '@pie-lib/pie-toolbox/correct-answer-toggle';\nimport { color, Collapsible, hasText, PreviewPrompt, UiLayout } from '@pie-lib/pie-toolbox/render-ui';\nimport { withStyles } from '@material-ui/core/styles';\n\nimport Container from './container';\n\nclass HotspotComponent extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n showCorrect: false,\n observer: null,\n scale: 1,\n };\n }\n\n componentDidMount() {\n this.observer = new MutationObserver((mutations) => {\n mutations.forEach(() => {\n const target = document.getElementById('question-container')?.style?.cssText;\n const zoom = target?.substring(target.indexOf('--pie-zoom') + 11, target.lastIndexOf('%'));\n const zoomParsed = zoom?.replace(/\\s/g, '');\n\n if (zoomParsed) {\n const newScale = parseFloat(zoomParsed) / 100;\n\n if (newScale !== this.state.scale) {\n this.setState({\n scale: parseFloat(zoomParsed) / 100,\n });\n }\n } else if (!zoomParsed && this.state.scale !== 1) {\n this.setState({\n scale: 1,\n });\n }\n });\n });\n\n const target = document.getElementById('question-container');\n\n if (target) {\n this.observer.observe(target, { attributes: true, attributeFilter: ['style'] });\n }\n }\n\n componentWillUnmount() {\n this.observer?.disconnect();\n }\n\n onToggle = () => {\n const { showCorrect } = this.state;\n this.setState({ showCorrect: !showCorrect });\n };\n\n render() {\n const {\n session,\n model: {\n disabled,\n extraCSSRules,\n imageUrl,\n prompt,\n mode,\n multipleCorrect,\n shapes,\n outlineColor,\n hotspotColor,\n hoverOutlineColor,\n selectedHotspotColor,\n dimensions,\n rationale,\n teacherInstructions,\n strokeWidth,\n responseCorrect,\n language,\n fontSizeFactor,\n autoplayAudioEnabled,\n customAudioButton\n },\n onSelectChoice,\n classes,\n } = this.props;\n const { showCorrect } = this.state;\n const isEvaluateMode = mode === 'evaluate';\n const showCorrectAnswerToggle = isEvaluateMode && !responseCorrect;\n\n return (\n <UiLayout extraCSSRules={extraCSSRules} id={'main-container'} className={classes.main} fontSizeFactor={fontSizeFactor}>\n {teacherInstructions && hasText(teacherInstructions) && (\n <Collapsible\n labels={{ hidden: 'Show Teacher Instructions', visible: 'Hide Teacher Instructions' }}\n className={classes.collapsible}\n >\n <PreviewPrompt className=\"prompt\" prompt={teacherInstructions} />\n </Collapsible>\n )}\n\n {prompt && (\n <PreviewPrompt\n className=\"prompt\"\n prompt={prompt}\n autoplayAudioEnabled={autoplayAudioEnabled}\n customAudioButton={customAudioButton}\n />\n )}\n\n {showCorrectAnswerToggle && (\n <CorrectAnswerToggle\n show={showCorrectAnswerToggle}\n toggled={showCorrect}\n onToggle={this.onToggle.bind(this)}\n language={language}\n />\n )}\n\n {imageUrl ? (\n <Container\n isEvaluateMode={isEvaluateMode}\n session={session}\n dimensions={dimensions}\n imageUrl={imageUrl}\n hotspotColor={hotspotColor}\n hoverOutlineColor={hoverOutlineColor}\n selectedHotspotColor={selectedHotspotColor}\n multipleCorrect={multipleCorrect}\n outlineColor={outlineColor}\n onSelectChoice={onSelectChoice}\n shapes={shapes}\n disabled={disabled}\n strokeWidth={strokeWidth}\n scale={this.state.scale}\n showCorrect={showCorrect}\n />\n ) : null}\n\n {rationale && hasText(rationale) && (\n <Collapsible labels={{ hidden: 'Show Rationale', visible: 'Hide Rationale' }}>\n <PreviewPrompt className=\"prompt\" prompt={rationale} />\n </Collapsible>\n )}\n </UiLayout>\n );\n }\n}\n\nHotspotComponent.propTypes = {\n classes: PropTypes.object,\n model: PropTypes.object.isRequired,\n onSelectChoice: PropTypes.func.isRequired,\n session: PropTypes.object.isRequired,\n};\n\nHotspotComponent.defaultProps = {\n classes: {},\n};\n\nconst styles = (theme) => ({\n main: {\n color: color.text(),\n backgroundColor: color.background(),\n position: 'relative'\n },\n collapsible: {\n marginBottom: theme.spacing.unit * 2,\n },\n prompt: {\n fontSize: 'inherit',\n },\n});\n\nexport default withStyles(styles)(HotspotComponent);\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../../src/hotspot/index.jsx"],"names":["HotspotComponent","props","showCorrect","state","setState","observer","scale","MutationObserver","mutations","forEach","target","document","getElementById","style","cssText","zoom","substring","indexOf","lastIndexOf","zoomParsed","replace","newScale","parseFloat","observe","attributes","attributeFilter","disconnect","session","model","disabled","extraCSSRules","imageUrl","prompt","mode","multipleCorrect","shapes","outlineColor","hotspotColor","hoverOutlineColor","selectedHotspotColor","dimensions","rationale","teacherInstructions","strokeWidth","responseCorrect","language","fontSizeFactor","autoplayAudioEnabled","onSelectChoice","classes","isEvaluateMode","showCorrectAnswerToggle","addAutoplayAudio","test","navigator","userAgent","main","hidden","visible","collapsible","onToggle","bind","React","Component","propTypes","PropTypes","object","isRequired","func","defaultProps","styles","theme","color","text","backgroundColor","background","position","marginBottom","spacing","unit","fontSize"],"mappings":"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","sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport { CorrectAnswerToggle } from '@pie-lib/pie-toolbox/correct-answer-toggle';\nimport { color, Collapsible, hasText, PreviewPrompt, UiLayout } from '@pie-lib/pie-toolbox/render-ui';\nimport { withStyles } from '@material-ui/core/styles';\n\nimport Container from './container';\n\nclass HotspotComponent extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n showCorrect: false,\n observer: null,\n scale: 1,\n };\n }\n\n componentDidMount() {\n this.observer = new MutationObserver((mutations) => {\n mutations.forEach(() => {\n const target = document.getElementById('question-container')?.style?.cssText;\n const zoom = target?.substring(target.indexOf('--pie-zoom') + 11, target.lastIndexOf('%'));\n const zoomParsed = zoom?.replace(/\\s/g, '');\n\n if (zoomParsed) {\n const newScale = parseFloat(zoomParsed) / 100;\n\n if (newScale !== this.state.scale) {\n this.setState({\n scale: parseFloat(zoomParsed) / 100,\n });\n }\n } else if (!zoomParsed && this.state.scale !== 1) {\n this.setState({\n scale: 1,\n });\n }\n });\n });\n\n const target = document.getElementById('question-container');\n\n if (target) {\n this.observer.observe(target, { attributes: true, attributeFilter: ['style'] });\n }\n }\n\n componentWillUnmount() {\n this.observer?.disconnect();\n }\n\n onToggle = () => {\n const { showCorrect } = this.state;\n this.setState({ showCorrect: !showCorrect });\n };\n\n render() {\n const {\n session,\n model: {\n disabled,\n extraCSSRules,\n imageUrl,\n prompt,\n mode,\n multipleCorrect,\n shapes,\n outlineColor,\n hotspotColor,\n hoverOutlineColor,\n selectedHotspotColor,\n dimensions,\n rationale,\n teacherInstructions,\n strokeWidth,\n responseCorrect,\n language,\n fontSizeFactor,\n autoplayAudioEnabled\n },\n onSelectChoice,\n classes,\n } = this.props;\n const { showCorrect } = this.state;\n const isEvaluateMode = mode === 'evaluate';\n const showCorrectAnswerToggle = isEvaluateMode && !responseCorrect;\n // Safari, Firefox, and Edge do not support autoplay audio smoothly in our use case\n const addAutoplayAudio = autoplayAudioEnabled && !(/Safari|Firefox|Edg/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent));\n\n return (\n <UiLayout extraCSSRules={extraCSSRules} id={'main-container'} className={classes.main} fontSizeFactor={fontSizeFactor}>\n {teacherInstructions && hasText(teacherInstructions) && (\n <Collapsible\n labels={{ hidden: 'Show Teacher Instructions', visible: 'Hide Teacher Instructions' }}\n className={classes.collapsible}\n >\n <PreviewPrompt className=\"prompt\" prompt={teacherInstructions} />\n </Collapsible>\n )}\n\n {prompt && <PreviewPrompt className=\"prompt\" prompt={prompt} autoplayAudioEnabled={addAutoplayAudio} />}\n\n {showCorrectAnswerToggle && (\n <CorrectAnswerToggle\n show={showCorrectAnswerToggle}\n toggled={showCorrect}\n onToggle={this.onToggle.bind(this)}\n language={language}\n />\n )}\n\n {imageUrl ? (\n <Container\n isEvaluateMode={isEvaluateMode}\n session={session}\n dimensions={dimensions}\n imageUrl={imageUrl}\n hotspotColor={hotspotColor}\n hoverOutlineColor={hoverOutlineColor}\n selectedHotspotColor={selectedHotspotColor}\n multipleCorrect={multipleCorrect}\n outlineColor={outlineColor}\n onSelectChoice={onSelectChoice}\n shapes={shapes}\n disabled={disabled}\n strokeWidth={strokeWidth}\n scale={this.state.scale}\n showCorrect={showCorrect}\n />\n ) : null}\n\n {rationale && hasText(rationale) && (\n <Collapsible labels={{ hidden: 'Show Rationale', visible: 'Hide Rationale' }}>\n <PreviewPrompt className=\"prompt\" prompt={rationale} />\n </Collapsible>\n )}\n </UiLayout>\n );\n }\n}\n\nHotspotComponent.propTypes = {\n classes: PropTypes.object,\n model: PropTypes.object.isRequired,\n onSelectChoice: PropTypes.func.isRequired,\n session: PropTypes.object.isRequired,\n};\n\nHotspotComponent.defaultProps = {\n classes: {},\n};\n\nconst styles = (theme) => ({\n main: {\n color: color.text(),\n backgroundColor: color.background(),\n position: 'relative'\n },\n collapsible: {\n marginBottom: theme.spacing.unit * 2,\n },\n prompt: {\n fontSize: 'inherit',\n },\n});\n\nexport default withStyles(styles)(HotspotComponent);\n"],"file":"index.js"}
package/lib/index.js CHANGED
@@ -211,12 +211,7 @@ var Hotspot = /*#__PURE__*/function (_HTMLElement) {
211
211
  audio.removeEventListener('ended', handleEnded);
212
212
  };
213
213
 
214
- audio.addEventListener('ended', handleEnded); // store references to remove later
215
-
216
- _this2._audio = audio;
217
- _this2._handlePlaying = handlePlaying;
218
- _this2._handleEnded = handleEnded;
219
- _this2._enableAudio = enableAudio;
214
+ audio.addEventListener('ended', handleEnded);
220
215
  observer.disconnect();
221
216
  }
222
217
  });
@@ -226,19 +221,6 @@ var Hotspot = /*#__PURE__*/function (_HTMLElement) {
226
221
  subtree: true
227
222
  });
228
223
  }
229
- }, {
230
- key: "disconnectedCallback",
231
- value: function disconnectedCallback() {
232
- document.removeEventListener('click', this._enableAudio);
233
-
234
- if (this._audio) {
235
- this._audio.removeEventListener('playing', this._handlePlaying);
236
-
237
- this._audio.removeEventListener('ended', this._handleEnded);
238
-
239
- this._audio = null;
240
- }
241
- }
242
224
  }, {
243
225
  key: "_render",
244
226
  value: function _render() {
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.js"],"names":["Hotspot","_model","_session","audioComplete","m","dispatchEvent","ModelSetEvent","tagName","toLowerCase","isComplete","_render","answers","autoplayAudioEnabled","completeAudioEnabled","Array","isArray","length","s","data","SessionChangedEvent","info","document","createElement","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","waitTime","_audio","_handlePlaying","_handleEnded","_enableAudio","disconnect","observe","childList","subtree","el","React","HotspotComponent","model","session","onSelectChoice","bind","ReactDOM","render","HTMLElement"],"mappings":"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","sourcesContent":["import React from 'react';\nimport ReactDOM from 'react-dom';\nimport { renderMath } from '@pie-lib/pie-toolbox/math-rendering';\nimport { SessionChangedEvent, ModelSetEvent } from '@pie-framework/pie-player-events';\n\nimport HotspotComponent from './hotspot';\nimport { updateSessionValue, updateSessionMetadata } from './session-updater';\n\nexport default class Hotspot extends HTMLElement {\n constructor() {\n super();\n this._model = null;\n this._session = null;\n this.audioComplete = false;\n }\n\n set model(m) {\n this._model = m;\n\n this.dispatchEvent(new ModelSetEvent(this.tagName.toLowerCase(), this.isComplete(), !!this._model));\n this._render();\n }\n\n isComplete() {\n if (!this._session || !this._session.answers) {\n return false;\n }\n\n const { autoplayAudioEnabled, completeAudioEnabled } = this._model || {};\n if (autoplayAudioEnabled && completeAudioEnabled && !this.audioComplete) {\n return false;\n }\n\n if (!Array.isArray(this._session.answers)) {\n return false;\n }\n\n return this._session.answers.length > 0;\n }\n\n set session(s) {\n if (s && !s.answers) {\n s.answers = [];\n }\n\n this._session = s;\n this._render();\n }\n\n get session() {\n return this._session;\n }\n\n onSelectChoice(data) {\n updateSessionValue(this._session, this._model, data);\n\n this.dispatchEvent(new SessionChangedEvent(this.tagName.toLowerCase(), this.isComplete()));\n\n this._render();\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._render();\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 //timestamp when auto-played audio started playing\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 //timestamp when auto-played audio completed playing\n updateSessionMetadata(this._session, { audioEndTime: new Date().getTime() });\n\n let { audioStartTime, audioEndTime, waitTime } = this._session;\n if(!waitTime && audioStartTime && audioEndTime) {\n // waitTime is elapsed time the user waited for auto-played audio to finish\n this._session.waitTime = (audioEndTime - audioStartTime);\n }\n\n this.audioComplete = true;\n this.dispatchEvent(new SessionChangedEvent(this.tagName.toLowerCase(), this.isComplete()));\n\n audio.removeEventListener('ended', handleEnded);\n };\n\n audio.addEventListener('ended', handleEnded);\n\n // store references to remove later\n this._audio = audio;\n this._handlePlaying = handlePlaying;\n this._handleEnded = handleEnded;\n this._enableAudio = enableAudio;\n\n observer.disconnect();\n }\n });\n });\n\n observer.observe(this, { childList: true, subtree: true });\n }\n\n disconnectedCallback() {\n document.removeEventListener('click', this._enableAudio);\n\n if (this._audio) {\n this._audio.removeEventListener('playing', this._handlePlaying);\n this._audio.removeEventListener('ended', this._handleEnded);\n this._audio = null;\n }\n }\n\n _render() {\n if (this._model && this._session) {\n const el = React.createElement(HotspotComponent, {\n model: this._model,\n session: this._session,\n onSelectChoice: this.onSelectChoice.bind(this),\n });\n\n ReactDOM.render(el, this, () => {\n renderMath(this);\n });\n }\n }\n}\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../src/index.js"],"names":["Hotspot","_model","_session","audioComplete","m","dispatchEvent","ModelSetEvent","tagName","toLowerCase","isComplete","_render","answers","autoplayAudioEnabled","completeAudioEnabled","Array","isArray","length","s","data","SessionChangedEvent","info","document","createElement","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","waitTime","disconnect","observe","childList","subtree","el","React","HotspotComponent","model","session","onSelectChoice","bind","ReactDOM","render","HTMLElement"],"mappings":"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","sourcesContent":["import React from 'react';\nimport ReactDOM from 'react-dom';\nimport { renderMath } from '@pie-lib/pie-toolbox/math-rendering';\nimport { SessionChangedEvent, ModelSetEvent } from '@pie-framework/pie-player-events';\n\nimport HotspotComponent from './hotspot';\nimport { updateSessionValue, updateSessionMetadata } from './session-updater';\n\nexport default class Hotspot extends HTMLElement {\n constructor() {\n super();\n this._model = null;\n this._session = null;\n this.audioComplete = false;\n }\n\n set model(m) {\n this._model = m;\n\n this.dispatchEvent(new ModelSetEvent(this.tagName.toLowerCase(), this.isComplete(), !!this._model));\n this._render();\n }\n\n isComplete() {\n if (!this._session || !this._session.answers) {\n return false;\n }\n\n const { autoplayAudioEnabled, completeAudioEnabled } = this._model || {};\n if (autoplayAudioEnabled && completeAudioEnabled && !this.audioComplete) {\n return false;\n }\n\n if (!Array.isArray(this._session.answers)) {\n return false;\n }\n\n return this._session.answers.length > 0;\n }\n\n set session(s) {\n if (s && !s.answers) {\n s.answers = [];\n }\n\n this._session = s;\n this._render();\n }\n\n get session() {\n return this._session;\n }\n\n onSelectChoice(data) {\n updateSessionValue(this._session, this._model, data);\n\n this.dispatchEvent(new SessionChangedEvent(this.tagName.toLowerCase(), this.isComplete()));\n\n this._render();\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._render();\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 //timestamp when auto-played audio started playing\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 //timestamp when auto-played audio completed playing\n updateSessionMetadata(this._session, { audioEndTime: new Date().getTime() });\n \n let { audioStartTime, audioEndTime, waitTime } = this._session;\n if(!waitTime && audioStartTime && audioEndTime) {\n // waitTime is elapsed time the user waited for auto-played audio to finish\n this._session.waitTime = (audioEndTime - audioStartTime);\n }\n \n this.audioComplete = true;\n this.dispatchEvent(new SessionChangedEvent(this.tagName.toLowerCase(), this.isComplete()));\n\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 _render() {\n if (this._model && this._session) {\n const el = React.createElement(HotspotComponent, {\n model: this._model,\n session: this._session,\n onSelectChoice: this.onSelectChoice.bind(this),\n });\n\n ReactDOM.render(el, this, () => {\n renderMath(this);\n });\n }\n }\n}\n"],"file":"index.js"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pie-element/hotspot",
3
- "version": "7.6.8-next.13+cd8256760",
3
+ "version": "7.6.8-next.3+254dccd42",
4
4
  "description": "",
5
5
  "repository": "pie-framework/pie-elements",
6
6
  "publishConfig": {
@@ -18,7 +18,7 @@
18
18
  },
19
19
  "author": "pie framework developers",
20
20
  "license": "ISC",
21
- "gitHead": "cd82567606d176cf23621538c2bc0005531d8ace",
21
+ "gitHead": "254dccd42bd4fe4e1da573a389b12b8fc7bc1b49",
22
22
  "scripts": {
23
23
  "postpublish": "../../scripts/postpublish"
24
24
  },
@@ -77,8 +77,7 @@ class HotspotComponent extends React.Component {
77
77
  responseCorrect,
78
78
  language,
79
79
  fontSizeFactor,
80
- autoplayAudioEnabled,
81
- customAudioButton
80
+ autoplayAudioEnabled
82
81
  },
83
82
  onSelectChoice,
84
83
  classes,
@@ -86,6 +85,8 @@ class HotspotComponent extends React.Component {
86
85
  const { showCorrect } = this.state;
87
86
  const isEvaluateMode = mode === 'evaluate';
88
87
  const showCorrectAnswerToggle = isEvaluateMode && !responseCorrect;
88
+ // Safari, Firefox, and Edge do not support autoplay audio smoothly in our use case
89
+ const addAutoplayAudio = autoplayAudioEnabled && !(/Safari|Firefox|Edg/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent));
89
90
 
90
91
  return (
91
92
  <UiLayout extraCSSRules={extraCSSRules} id={'main-container'} className={classes.main} fontSizeFactor={fontSizeFactor}>
@@ -98,14 +99,7 @@ class HotspotComponent extends React.Component {
98
99
  </Collapsible>
99
100
  )}
100
101
 
101
- {prompt && (
102
- <PreviewPrompt
103
- className="prompt"
104
- prompt={prompt}
105
- autoplayAudioEnabled={autoplayAudioEnabled}
106
- customAudioButton={customAudioButton}
107
- />
108
- )}
102
+ {prompt && <PreviewPrompt className="prompt" prompt={prompt} autoplayAudioEnabled={addAutoplayAudio} />}
109
103
 
110
104
  {showCorrectAnswerToggle && (
111
105
  <CorrectAnswerToggle
package/src/index.js CHANGED
@@ -129,7 +129,7 @@ export default class Hotspot extends HTMLElement {
129
129
  const handlePlaying = () => {
130
130
  //timestamp when auto-played audio started playing
131
131
  updateSessionMetadata(this._session, { audioStartTime: new Date().getTime() });
132
-
132
+
133
133
  const info = this.querySelector('#play-audio-info');
134
134
  if (info) {
135
135
  container.removeChild(info);
@@ -144,13 +144,13 @@ export default class Hotspot extends HTMLElement {
144
144
  const handleEnded = () => {
145
145
  //timestamp when auto-played audio completed playing
146
146
  updateSessionMetadata(this._session, { audioEndTime: new Date().getTime() });
147
-
147
+
148
148
  let { audioStartTime, audioEndTime, waitTime } = this._session;
149
149
  if(!waitTime && audioStartTime && audioEndTime) {
150
150
  // waitTime is elapsed time the user waited for auto-played audio to finish
151
151
  this._session.waitTime = (audioEndTime - audioStartTime);
152
152
  }
153
-
153
+
154
154
  this.audioComplete = true;
155
155
  this.dispatchEvent(new SessionChangedEvent(this.tagName.toLowerCase(), this.isComplete()));
156
156
 
@@ -159,12 +159,6 @@ export default class Hotspot extends HTMLElement {
159
159
 
160
160
  audio.addEventListener('ended', handleEnded);
161
161
 
162
- // store references to remove later
163
- this._audio = audio;
164
- this._handlePlaying = handlePlaying;
165
- this._handleEnded = handleEnded;
166
- this._enableAudio = enableAudio;
167
-
168
162
  observer.disconnect();
169
163
  }
170
164
  });
@@ -173,16 +167,6 @@ export default class Hotspot extends HTMLElement {
173
167
  observer.observe(this, { childList: true, subtree: true });
174
168
  }
175
169
 
176
- disconnectedCallback() {
177
- document.removeEventListener('click', this._enableAudio);
178
-
179
- if (this._audio) {
180
- this._audio.removeEventListener('playing', this._handlePlaying);
181
- this._audio.removeEventListener('ended', this._handleEnded);
182
- this._audio = null;
183
- }
184
- }
185
-
186
170
  _render() {
187
171
  if (this._model && this._session) {
188
172
  const el = React.createElement(HotspotComponent, {