@pie-element/ebsr 14.2.1-next.2 → 14.2.1-next.29

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.
Files changed (221) hide show
  1. package/CHANGELOG.json +1547 -0
  2. package/CHANGELOG.md +2281 -0
  3. package/LICENSE.md +5 -0
  4. package/README.md +62 -0
  5. package/configure/CHANGELOG.json +992 -0
  6. package/configure/CHANGELOG.md +2144 -0
  7. package/configure/lib/defaults.js +229 -0
  8. package/configure/lib/defaults.js.map +1 -0
  9. package/configure/lib/index.js +154 -0
  10. package/configure/lib/index.js.map +1 -0
  11. package/configure/lib/main.js +222 -0
  12. package/configure/lib/main.js.map +1 -0
  13. package/configure/package.json +23 -0
  14. package/configure/src/__tests__/index.test.js +492 -0
  15. package/configure/src/defaults.js +173 -0
  16. package/configure/src/index.js +174 -0
  17. package/configure/src/main.jsx +235 -0
  18. package/controller/CHANGELOG.json +552 -0
  19. package/controller/CHANGELOG.md +1282 -0
  20. package/controller/lib/defaults.js +31 -0
  21. package/controller/lib/defaults.js.map +1 -0
  22. package/controller/lib/index.js +448 -0
  23. package/controller/lib/index.js.map +1 -0
  24. package/controller/lib/utils.js +18 -0
  25. package/controller/lib/utils.js.map +1 -0
  26. package/controller/package.json +18 -0
  27. package/controller/src/__tests__/index.test.js +591 -0
  28. package/controller/src/__tests__/utils.test.js +48 -0
  29. package/controller/src/defaults.js +25 -0
  30. package/controller/src/index.js +442 -0
  31. package/controller/src/utils.js +18 -0
  32. package/docs/config-schema.json +5787 -0
  33. package/docs/config-schema.json.md +4278 -0
  34. package/docs/demo/config.js +8 -0
  35. package/docs/demo/generate.js +52 -0
  36. package/docs/demo/index.html +2 -0
  37. package/docs/demo/session.js +14 -0
  38. package/docs/pie-schema.json +2911 -0
  39. package/docs/pie-schema.json.md +2142 -0
  40. package/ebsr.png +0 -0
  41. package/lib/index.js +207 -0
  42. package/lib/index.js.map +1 -0
  43. package/lib/print.js +186 -0
  44. package/lib/print.js.map +1 -0
  45. package/module/configure.js +1 -0
  46. package/module/controller.js +5664 -0
  47. package/module/demo.js +77 -0
  48. package/module/element.js +1 -0
  49. package/module/index.html +21 -0
  50. package/module/manifest.json +14 -0
  51. package/module/print-demo.js +115 -0
  52. package/module/print.html +18 -0
  53. package/module/print.js +1 -0
  54. package/package.json +17 -56
  55. package/src/__tests__/index.test.js +129 -0
  56. package/src/index.js +222 -0
  57. package/src/print.js +207 -0
  58. package/dist/author/defaults.d.ts +0 -66
  59. package/dist/author/defaults.js +0 -161
  60. package/dist/author/index.d.ts +0 -34
  61. package/dist/author/index.js +0 -78
  62. package/dist/author/main.d.ts +0 -22
  63. package/dist/author/main.js +0 -121
  64. package/dist/controller/defaults.d.ts +0 -15
  65. package/dist/controller/defaults.js +0 -26
  66. package/dist/controller/index.d.ts +0 -42
  67. package/dist/controller/index.js +0 -186
  68. package/dist/controller/utils.d.ts +0 -10
  69. package/dist/controller/utils.js +0 -8
  70. package/dist/delivery/index.d.ts +0 -26
  71. package/dist/delivery/index.js +0 -132
  72. package/dist/index.d.ts +0 -1
  73. package/dist/index.iife.d.ts +0 -8
  74. package/dist/index.iife.js +0 -165
  75. package/dist/index.js +0 -2
  76. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_DataView.js +0 -6
  77. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_Hash.js +0 -16
  78. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_ListCache.js +0 -16
  79. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_Map.js +0 -6
  80. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_MapCache.js +0 -16
  81. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_Promise.js +0 -6
  82. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_Set.js +0 -6
  83. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_SetCache.js +0 -11
  84. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_Stack.js +0 -14
  85. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_Symbol.js +0 -5
  86. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_Uint8Array.js +0 -5
  87. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_WeakMap.js +0 -6
  88. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_apply.js +0 -12
  89. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_arrayEach.js +0 -7
  90. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_arrayFilter.js +0 -10
  91. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_arrayLikeKeys.js +0 -15
  92. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_arrayMap.js +0 -7
  93. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_arrayPush.js +0 -7
  94. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_arraySome.js +0 -7
  95. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_assignValue.js +0 -10
  96. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_assocIndexOf.js +0 -8
  97. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseAssign.js +0 -8
  98. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseAssignIn.js +0 -8
  99. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseAssignValue.js +0 -12
  100. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseClone.js +0 -57
  101. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseCreate.js +0 -14
  102. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseGet.js +0 -10
  103. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseGetAllKeys.js +0 -9
  104. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseGetTag.js +0 -10
  105. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseIsArguments.js +0 -9
  106. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseIsEqual.js +0 -8
  107. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseIsEqualDeep.js +0 -30
  108. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseIsMap.js +0 -9
  109. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseIsNative.js +0 -11
  110. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseIsSet.js +0 -9
  111. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseIsTypedArray.js +0 -11
  112. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseKeys.js +0 -12
  113. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseKeysIn.js +0 -13
  114. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseRest.js +0 -9
  115. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseSetToString.js +0 -14
  116. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseTimes.js +0 -7
  117. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseToString.js +0 -15
  118. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseUnary.js +0 -8
  119. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_cacheHas.js +0 -6
  120. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_castPath.js +0 -10
  121. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_cloneArrayBuffer.js +0 -8
  122. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_cloneBuffer.js +0 -10
  123. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_cloneDataView.js +0 -8
  124. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_cloneRegExp.js +0 -8
  125. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_cloneSymbol.js +0 -8
  126. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_cloneTypedArray.js +0 -8
  127. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_copyArray.js +0 -8
  128. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_copyObject.js +0 -14
  129. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_copySymbols.js +0 -8
  130. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_copySymbolsIn.js +0 -8
  131. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_coreJsData.js +0 -5
  132. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_defineProperty.js +0 -10
  133. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_equalArrays.js +0 -35
  134. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_equalByTag.js +0 -35
  135. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_equalObjects.js +0 -32
  136. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_freeGlobal.js +0 -4
  137. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_getAllKeys.js +0 -9
  138. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_getAllKeysIn.js +0 -9
  139. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_getMapData.js +0 -8
  140. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_getNative.js +0 -9
  141. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_getPrototype.js +0 -5
  142. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_getRawTag.js +0 -14
  143. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_getSymbols.js +0 -10
  144. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_getSymbolsIn.js +0 -11
  145. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_getTag.js +0 -23
  146. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_getValue.js +0 -6
  147. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_hashClear.js +0 -7
  148. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_hashDelete.js +0 -7
  149. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_hashGet.js +0 -13
  150. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_hashHas.js +0 -9
  151. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_hashSet.js +0 -9
  152. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_initCloneArray.js +0 -8
  153. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_initCloneByTag.js +0 -33
  154. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_initCloneObject.js +0 -9
  155. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_isIndex.js +0 -8
  156. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_isIterateeCall.js +0 -12
  157. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_isKey.js +0 -11
  158. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_isKeyable.js +0 -7
  159. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_isMasked.js +0 -11
  160. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_isPrototype.js +0 -8
  161. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_listCacheClear.js +0 -6
  162. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_listCacheDelete.js +0 -9
  163. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_listCacheGet.js +0 -8
  164. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_listCacheHas.js +0 -7
  165. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_listCacheSet.js +0 -8
  166. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_mapCacheClear.js +0 -13
  167. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_mapCacheDelete.js +0 -8
  168. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_mapCacheGet.js +0 -7
  169. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_mapCacheHas.js +0 -7
  170. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_mapCacheSet.js +0 -8
  171. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_mapToArray.js +0 -9
  172. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_memoizeCapped.js +0 -11
  173. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_nativeCreate.js +0 -5
  174. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_nativeKeys.js +0 -5
  175. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_nativeKeysIn.js +0 -8
  176. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_nodeUtil.js +0 -9
  177. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_objectToString.js +0 -7
  178. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_overArg.js +0 -8
  179. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_overRest.js +0 -13
  180. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_root.js +0 -5
  181. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_setCacheAdd.js +0 -7
  182. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_setCacheHas.js +0 -6
  183. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_setToArray.js +0 -9
  184. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_setToString.js +0 -6
  185. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_shortOut.js +0 -14
  186. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_stackClear.js +0 -7
  187. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_stackDelete.js +0 -7
  188. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_stackGet.js +0 -6
  189. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_stackHas.js +0 -6
  190. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_stackSet.js +0 -16
  191. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_stringToPath.js +0 -10
  192. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_toKey.js +0 -10
  193. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_toSource.js +0 -15
  194. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/cloneDeep.js +0 -8
  195. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/constant.js +0 -8
  196. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/defaults.js +0 -16
  197. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/eq.js +0 -6
  198. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/get.js +0 -8
  199. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/identity.js +0 -6
  200. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isArguments.js +0 -10
  201. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isArray.js +0 -4
  202. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isArrayLike.js +0 -8
  203. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isBuffer.js +0 -6
  204. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isEmpty.js +0 -21
  205. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isEqual.js +0 -7
  206. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isFunction.js +0 -11
  207. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isLength.js +0 -7
  208. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isMap.js +0 -7
  209. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isObject.js +0 -7
  210. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isObjectLike.js +0 -6
  211. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isSet.js +0 -7
  212. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isSymbol.js +0 -9
  213. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isTypedArray.js +0 -7
  214. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/keys.js +0 -9
  215. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/keysIn.js +0 -9
  216. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/memoize.js +0 -16
  217. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/stubArray.js +0 -6
  218. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/stubFalse.js +0 -6
  219. package/dist/node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/toString.js +0 -7
  220. package/dist/print/index.d.ts +0 -25
  221. package/dist/print/index.js +0 -107
@@ -0,0 +1,129 @@
1
+ import React from 'react';
2
+ import { SessionChangedEvent } from '@pie-framework/pie-player-events';
3
+ import { isSessionComplete } from '..';
4
+
5
+ jest.mock('@pie-lib/math-rendering', () => ({ renderMath: jest.fn() }));
6
+ jest.mock('@pie-element/multiple-choice', () => jest.fn());
7
+
8
+ const PART_A = 'partA';
9
+ const PART_B = 'partB';
10
+
11
+ const defaultModel = {
12
+ disabled: false,
13
+ mode: 'gather',
14
+ partA: {
15
+ choiceMode: 'radio',
16
+ choices: [
17
+ { value: 'a', label: 'label a' },
18
+ { value: 'b', label: 'label b' },
19
+ { value: 'c', label: 'label c', correct: true, feedback: 'great' },
20
+ ],
21
+ choicePrefix: 'numbers',
22
+ prompt: `prompt ${PART_A}`,
23
+ },
24
+ partB: {
25
+ choiceMode: 'radio',
26
+ choices: [
27
+ { value: 'd', label: 'label d', correct: true, feedback: 'great' },
28
+ { value: 'e', label: 'label e' },
29
+ { value: 'f', label: 'label f' },
30
+ ],
31
+ choicePrefix: 'numbers',
32
+ prompt: `prompt ${PART_B}`,
33
+ },
34
+ };
35
+
36
+ const defaultSession = { id: 1 };
37
+
38
+ describe('ebsr', () => {
39
+ let Def;
40
+ let el;
41
+ let ebsr;
42
+
43
+ beforeAll(() => {
44
+ Def = require('../index').default;
45
+
46
+ // Register the custom element if not already registered
47
+ if (!customElements.get('ebsr-element')) {
48
+ customElements.define('ebsr-element', Def);
49
+ }
50
+ });
51
+
52
+ beforeEach(() => {
53
+ el = document.createElement('ebsr-element');
54
+
55
+ // Mock createElement for part elements
56
+ ebsr = {
57
+ partA: document.createElement('div'),
58
+ partB: document.createElement('div'),
59
+ };
60
+ el.querySelector = jest.fn((s) => {
61
+ if (s === '#part-a') {
62
+ return ebsr.partA;
63
+ } else {
64
+ return ebsr.partB;
65
+ }
66
+ });
67
+
68
+ // Mock _render to avoid innerHTML issues with custom elements
69
+ el._render = jest.fn();
70
+
71
+ // Mock dispatchEvent for testing
72
+ el.dispatchEvent = jest.fn();
73
+
74
+ el.connectedCallback();
75
+ el.model = defaultModel;
76
+ el.session = defaultSession;
77
+ });
78
+
79
+ describe('model', () => {
80
+ it('should have set the model', () => {
81
+ expect(el._model).toEqual(defaultModel);
82
+ });
83
+ });
84
+
85
+ describe('session', () => {
86
+ const dispatchesSessionEvent = (key, value) => {
87
+ it(`${key} dispatches session changed event`, () => {
88
+ const session = { id: key, value };
89
+ el.dispatchSessionChanged(session, key);
90
+
91
+ expect(el.dispatchEvent).toBeCalledWith(new SessionChangedEvent('ebsr-element', false));
92
+ expect(el._session.value[key]).toEqual(session);
93
+ });
94
+ };
95
+
96
+ it('should have set the session', () => {
97
+ expect(el._session).toEqual(defaultSession);
98
+ });
99
+
100
+ describe('changeAnswers', () => {
101
+ dispatchesSessionEvent(PART_A, 'a');
102
+ dispatchesSessionEvent(PART_B, 'd');
103
+ });
104
+ });
105
+
106
+ describe('setPartSession', () => {
107
+ it('sets the session object even if missing from session.value', () => {
108
+ const part = {};
109
+ el.model = {};
110
+ el.session = {
111
+ value: {},
112
+ };
113
+ el.setPartSession(part, 'partA');
114
+ expect(part.session).toEqual({ id: 'partA' });
115
+ });
116
+ });
117
+ });
118
+
119
+ describe('isSessionComplete', () => {
120
+ const assertComplete = (s, expected) => {
121
+ it(`${JSON.stringify(s)} => ${expected}`, () => {
122
+ const result = isSessionComplete(s);
123
+ expect(result).toEqual(expected);
124
+ });
125
+ };
126
+
127
+ assertComplete({}, false);
128
+ assertComplete({ value: { partA: { value: [1] }, partB: { value: [2] } } }, true);
129
+ });
package/src/index.js ADDED
@@ -0,0 +1,222 @@
1
+ import { SessionChangedEvent } from '@pie-framework/pie-player-events';
2
+ import MultipleChoice from '@pie-element/multiple-choice';
3
+ import { get } from 'lodash-es';
4
+ import debug from 'debug';
5
+
6
+ const SESSION_CHANGED = SessionChangedEvent.TYPE;
7
+ const MC_TAG_NAME = 'ebsr-multiple-choice';
8
+ const log = debug('pie-elements:ebsr');
9
+
10
+ class EbsrMC extends MultipleChoice {}
11
+
12
+ const defineMultipleChoice = () => {
13
+ if (!customElements.get(MC_TAG_NAME)) {
14
+ customElements.define(MC_TAG_NAME, EbsrMC);
15
+ }
16
+ };
17
+
18
+ defineMultipleChoice();
19
+
20
+ const isNonEmptyArray = (a) => Array.isArray(a) && a.length > 0;
21
+
22
+ export const isSessionComplete = (session) => {
23
+ const a = get(session, 'value.partA.value');
24
+ const b = get(session, 'value.partB.value');
25
+
26
+ return isNonEmptyArray(a) && isNonEmptyArray(b);
27
+ };
28
+
29
+ function getPlayerAttributes(element) {
30
+ const player =
31
+ element.closest('pie-player') ||
32
+ element.closest('pie-item-player');
33
+
34
+ if (!player) {
35
+ return { baseHeadingLevel: undefined, includeSrHeading: true };
36
+ }
37
+
38
+ const getRaw = (camelCaseName, hyphenatedName, allLowerName) => {
39
+ let raw = player[camelCaseName];
40
+
41
+ // fallback in case someone sets via HTML attribute manually
42
+ if (raw == null) {
43
+ raw =
44
+ player.getAttribute(hyphenatedName) ??
45
+ player.getAttribute(allLowerName);
46
+ }
47
+
48
+ return raw;
49
+ };
50
+
51
+ const levelRaw = getRaw('baseHeadingLevel', 'base-heading-level', 'baseheadinglevel');
52
+ const level = parseInt(levelRaw, 10);
53
+ const baseHeadingLevel = Number.isFinite(level) && level >= 1 && level <= 6 ? level : undefined;
54
+
55
+ const srRaw = getRaw('includeSrHeading', 'include-sr-heading', 'includesrheading');
56
+ const includeSrHeading = srRaw == null ? true : srRaw !== false && srRaw !== 'false';
57
+
58
+ return { baseHeadingLevel, includeSrHeading };
59
+ }
60
+
61
+ export default class Ebsr extends HTMLElement {
62
+ constructor() {
63
+ super();
64
+ this._model = {};
65
+ this._session = {};
66
+ }
67
+
68
+ onSessionUpdated = (e) => {
69
+ if (e.target === this) {
70
+ return;
71
+ }
72
+
73
+ e.preventDefault();
74
+ e.stopImmediatePropagation();
75
+
76
+ const id = e.target.getAttribute('id');
77
+
78
+ if (id) {
79
+ const key = `part${id.toUpperCase()}`;
80
+
81
+ if (e.update) {
82
+ this._model[key] = e.update;
83
+ }
84
+ //TODO: accessing a private property here. The session event should contain the update in future to prevent this.
85
+ this.dispatchSessionChanged(e.srcElement._session, key);
86
+ }
87
+ };
88
+
89
+ set model(m) {
90
+ this._model = m;
91
+
92
+ customElements.whenDefined(MC_TAG_NAME).then(() => {
93
+ this.setPartModel(this.partA, 'partA');
94
+ this.setPartModel(this.partB, 'partB');
95
+ });
96
+ }
97
+
98
+ set session(s) {
99
+ this._session = s;
100
+
101
+ customElements.whenDefined(MC_TAG_NAME).then(() => {
102
+ this.setPartSession(this.partA, 'partA');
103
+ this.setPartSession(this.partB, 'partB');
104
+ });
105
+ }
106
+
107
+ get session() {
108
+ return this._session;
109
+ }
110
+
111
+ setPartModel(part, key) {
112
+ if (this._model && this._model[key] && part) {
113
+ const { mode } = this._model;
114
+
115
+ part.model = {
116
+ ...this._model[key],
117
+ mode,
118
+ keyMode: this._model[key].choicePrefix,
119
+ };
120
+
121
+ // Parts of an EBSR item should not render their own SR headings —
122
+ // the EBSR element itself provides the item-level heading.
123
+ const { includeSrHeading, baseHeadingLevel } = getPlayerAttributes(this);
124
+ part.includeSrHeading = includeSrHeading;
125
+ part.baseHeadingLevel = baseHeadingLevel;
126
+ }
127
+ }
128
+
129
+ setPartSession(part, key) {
130
+ if (this._session && this._model && part) {
131
+ const { value } = this._session;
132
+ part.session = value && value[key] ? value[key] : { id: key };
133
+ }
134
+ }
135
+
136
+ dispatchSessionChanged(partSession, key) {
137
+ this._session.value = {
138
+ ...this._session.value,
139
+ [key]: partSession,
140
+ };
141
+
142
+ log('[onSessionChanged] session: ', this._session);
143
+ const complete = isSessionComplete(this._session);
144
+ this.dispatchEvent(new SessionChangedEvent(this.tagName.toLowerCase(), complete));
145
+ }
146
+
147
+ get partA() {
148
+ return this.querySelector(`${MC_TAG_NAME}#a`);
149
+ }
150
+
151
+ get partB() {
152
+ return this.querySelector(`${MC_TAG_NAME}#b`);
153
+ }
154
+
155
+ connectedCallback() {
156
+ this._render();
157
+ this._initPlayerObserver();
158
+ this.addEventListener(SESSION_CHANGED, this.onSessionUpdated);
159
+ }
160
+
161
+ disconnectedCallback() {
162
+ this._disconnectPlayerObserver();
163
+ this.removeEventListener(SESSION_CHANGED, this.onSessionUpdated);
164
+ }
165
+
166
+ _initPlayerObserver() {
167
+ const player = this.closest('pie-player') || this.closest('pie-item-player');
168
+ if (!player) return;
169
+
170
+ this._playerObserver = new MutationObserver(() => {
171
+ this._render();
172
+ });
173
+ this._playerObserver.observe(player, {
174
+ attributes: true,
175
+ attributeFilter: ['base-heading-level', 'baseheadinglevel', 'include-sr-heading', 'includesrheading'],
176
+ });
177
+ }
178
+
179
+ _disconnectPlayerObserver() {
180
+ if (this._playerObserver) {
181
+ this._playerObserver.disconnect();
182
+ this._playerObserver = null;
183
+ }
184
+ }
185
+
186
+ _render() {
187
+ this.ariaLabel = 'Two-Part Question';
188
+ this.role = 'region';
189
+
190
+ const { baseHeadingLevel: ebsrLevel, includeSrHeading } = getPlayerAttributes(this);
191
+ const headingTag = ebsrLevel ? `h${Math.min(6, ebsrLevel)}` : 'h2';
192
+ const srHeading = includeSrHeading ? `<${headingTag} class="srOnly">Two-Part Question</${headingTag}>` : '';
193
+
194
+ this.innerHTML = `
195
+ <style>
196
+ .srOnly {
197
+ position: absolute;
198
+ width: 1px;
199
+ height: 1px;
200
+ padding: 0;
201
+ margin: -1px;
202
+ overflow: hidden;
203
+ left: -10000px;
204
+ top: auto;
205
+ }
206
+ ${this._model?.extraCSSRules?.rules}
207
+ </style>
208
+ ${srHeading}
209
+ <${MC_TAG_NAME} id="a"></${MC_TAG_NAME}>
210
+ <${MC_TAG_NAME} id="b"></${MC_TAG_NAME}>
211
+ `;
212
+
213
+ // when item is re-rendered (due to connectedCallback), if the custom element is already defined,
214
+ // we need to set the model and session, otherwise the setters are not reached again
215
+ if (customElements.get(MC_TAG_NAME)) {
216
+ this.setPartModel(this.partA, 'partA');
217
+ this.setPartModel(this.partB, 'partB');
218
+ this.setPartSession(this.partA, 'partA');
219
+ this.setPartSession(this.partB, 'partB');
220
+ }
221
+ }
222
+ }
package/src/print.js ADDED
@@ -0,0 +1,207 @@
1
+ import { cloneDeep, get } from 'lodash-es';
2
+ import MultipleChoice from '@pie-element/multiple-choice';
3
+ import debug from 'debug';
4
+ import { SessionChangedEvent } from '@pie-framework/pie-player-events';
5
+ const MC_TAG_NAME = 'ebsr-multiple-choice';
6
+ const SESSION_CHANGED = SessionChangedEvent.TYPE;
7
+ import Translator from '@pie-lib/translator';
8
+
9
+ const { translator } = Translator;
10
+
11
+ const log = debug('pie-element:ebsr:print');
12
+
13
+ /**
14
+ * Live in same package as main element - so we can access some of the shared comps!
15
+ *
16
+ * - update pslb to build print if src/print.js is there
17
+ * - update demo el
18
+ * - get configure/controller building
19
+ */
20
+
21
+ const preparePrintModel = (model, opts) => {
22
+ const instr = opts.role === 'instructor';
23
+ const printModel = cloneDeep(model);
24
+
25
+ printModel.prompt = printModel.promptEnabled !== false ? printModel.prompt : undefined;
26
+ printModel.teacherInstructions =
27
+ instr && printModel.teacherInstructionsEnabled !== false ? printModel.teacherInstructions : undefined;
28
+ printModel.showTeacherInstructions = instr;
29
+ printModel.alwaysShowCorrect = instr;
30
+ printModel.mode = instr ? 'evaluate' : 'gather';
31
+
32
+ printModel.disabled = true;
33
+ printModel.animationsDisabled = true;
34
+ printModel.lockChoiceOrder = true;
35
+ printModel.choicesLayout = printModel.choicesLayout || 'vertical';
36
+
37
+ printModel.choices = (printModel.choices || []).map((c) => {
38
+ c.rationale = instr && printModel.rationaleEnabled !== false ? c.rationale : undefined;
39
+ c.hideTick = instr;
40
+ c.feedback = undefined;
41
+ return c;
42
+ });
43
+
44
+ printModel.keyMode = printModel.choicePrefix || 'letters';
45
+
46
+ return printModel;
47
+ };
48
+
49
+ class EbsrMC extends MultipleChoice {}
50
+
51
+ const defineMultipleChoice = () => {
52
+ if (!customElements.get(MC_TAG_NAME)) {
53
+ customElements.define(MC_TAG_NAME, EbsrMC);
54
+ }
55
+ };
56
+
57
+ defineMultipleChoice();
58
+
59
+ const isNonEmptyArray = (a) => Array.isArray(a) && a.length > 0;
60
+
61
+ export const isSessionComplete = (session) => {
62
+ const a = get(session, 'value.partA.value');
63
+ const b = get(session, 'value.partB.value');
64
+
65
+ return isNonEmptyArray(a) && isNonEmptyArray(b);
66
+ };
67
+
68
+ export default class Ebsr extends HTMLElement {
69
+ constructor() {
70
+ super();
71
+ this._model = {};
72
+ this._session = {};
73
+ this._options = null;
74
+ }
75
+
76
+ onSessionUpdated = (e) => {
77
+ if (e.target === this) {
78
+ return;
79
+ }
80
+
81
+ e.preventDefault();
82
+ e.stopImmediatePropagation();
83
+
84
+ const id = e.target.getAttribute('id');
85
+
86
+ if (id) {
87
+ const key = `part${id.toUpperCase()}`;
88
+
89
+ if (e.update) {
90
+ this._model[key] = e.update;
91
+ }
92
+ //TODO: accessing a private property here. The session event should contain the update in future to prevent this.
93
+ this.dispatchSessionChanged(e.srcElement._session, key);
94
+ }
95
+ };
96
+
97
+ set model(m) {
98
+ this._model = m;
99
+ this._updateParts();
100
+ }
101
+
102
+ set session(s) {
103
+ this._session = s;
104
+
105
+ customElements.whenDefined(MC_TAG_NAME).then(() => {
106
+ this.setPartSession(this.partA, 'partA');
107
+ this.setPartSession(this.partB, 'partB');
108
+ });
109
+ }
110
+
111
+ _updateParts() {
112
+ customElements.whenDefined(MC_TAG_NAME).then(() => {
113
+ this.setPartModel(this.partA, 'partA');
114
+ this.setPartModel(this.partB, 'partB');
115
+ });
116
+ }
117
+
118
+ setPartModel(part, key) {
119
+ if (this._model && this._model[key] && part && this._options) {
120
+ let labels = {
121
+ partA: undefined,
122
+ partB: undefined,
123
+ };
124
+
125
+ if (this._model.partLabels) {
126
+ const language = this._model.language;
127
+
128
+ labels = {
129
+ partA: translator.t('ebsr.part', {
130
+ lng: language,
131
+ index: this._model.partLabelType === 'Letters' ? 'A' : '1',
132
+ }),
133
+ partB: translator.t('ebsr.part', {
134
+ lng: language,
135
+ index: this._model.partLabelType === 'Letters' ? 'B' : '2',
136
+ }),
137
+ };
138
+ }
139
+
140
+ part.model = {
141
+ ...preparePrintModel(this._model[key], this._options),
142
+ keyMode: this._model[key].choicePrefix,
143
+ partLabel: labels[key],
144
+ };
145
+
146
+ // pass options to enable print mode detection in multiple-choice component
147
+ part.options = this._options;
148
+
149
+ if (!part._session) {
150
+ // for print, "set session" is not called,
151
+ // but ebsr needs sessions in order to render the elements,
152
+ // so we set it here it was not set already
153
+ part.session = {};
154
+ }
155
+ }
156
+ }
157
+
158
+ set options(o) {
159
+ this._options = o;
160
+ // re-render parts so role changes (student/instructor) propagate to each part
161
+ this._updateParts();
162
+ }
163
+
164
+ setPartSession(part, key) {
165
+ if (this._session && this._model && part) {
166
+ const { value } = this._session;
167
+ part.session = value && value[key] ? value[key] : { id: key };
168
+ }
169
+ }
170
+
171
+ dispatchSessionChanged(partSession, key) {
172
+ this._session.value = {
173
+ ...this._session.value,
174
+ [key]: partSession,
175
+ };
176
+
177
+ log('[onSessionChanged] session: ', this._session);
178
+ const complete = isSessionComplete(this._session);
179
+ this.dispatchEvent(new SessionChangedEvent(this.tagName.toLowerCase(), complete));
180
+ }
181
+
182
+ get partA() {
183
+ return this.querySelector(`${MC_TAG_NAME}#a`);
184
+ }
185
+
186
+ get partB() {
187
+ return this.querySelector(`${MC_TAG_NAME}#b`);
188
+ }
189
+
190
+ connectedCallback() {
191
+ this._render();
192
+ this.addEventListener(SESSION_CHANGED, this.onSessionUpdated);
193
+ }
194
+
195
+ disconnectedCallback() {
196
+ this.removeEventListener(SESSION_CHANGED, this.onSessionUpdated);
197
+ }
198
+
199
+ _render() {
200
+ this.innerHTML = `
201
+ <div>
202
+ <${MC_TAG_NAME} id="a"></${MC_TAG_NAME}>
203
+ <${MC_TAG_NAME} id="b"></${MC_TAG_NAME}>
204
+ </div>
205
+ `;
206
+ }
207
+ }
@@ -1,66 +0,0 @@
1
- /**
2
- * @synced-from pie-elements/packages/ebsr/configure/src/defaults.js
3
- * @auto-generated
4
- *
5
- * This file is automatically synced from pie-elements and converted to TypeScript.
6
- * Manual edits will be overwritten on next sync.
7
- * To make changes, edit the upstream JavaScript file and run sync again.
8
- */
9
- declare const _default: {
10
- model: {
11
- partLabels: boolean;
12
- partLabelType: string;
13
- partA: any;
14
- partB: any;
15
- };
16
- configuration: {
17
- baseInputConfiguration: {
18
- h3: {
19
- disabled: boolean;
20
- };
21
- audio: {
22
- disabled: boolean;
23
- };
24
- video: {
25
- disabled: boolean;
26
- };
27
- image: {
28
- disabled: boolean;
29
- };
30
- textAlign: {
31
- disabled: boolean;
32
- };
33
- showParagraphs: {
34
- disabled: boolean;
35
- };
36
- separateParagraphs: {
37
- disabled: boolean;
38
- };
39
- };
40
- partialScoring: {
41
- label: string;
42
- settings: boolean;
43
- };
44
- scoringType: {
45
- settings: boolean;
46
- label: string;
47
- };
48
- partA: any;
49
- partB: any;
50
- partLabels: {
51
- settings: boolean;
52
- label: string;
53
- };
54
- settingsPanelDisabled: boolean;
55
- language: {
56
- settings: boolean;
57
- label: string;
58
- enabled: boolean;
59
- };
60
- languageChoices: {
61
- label: string;
62
- options: never[];
63
- };
64
- };
65
- };
66
- export default _default;