@khanacademy/perseus 19.1.5 → 19.1.7

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 (489) hide show
  1. package/dist/components/graph.d.ts +0 -1
  2. package/dist/components/graphie.d.ts +0 -1
  3. package/dist/es/index.js +319 -212
  4. package/dist/es/index.js.map +1 -1
  5. package/dist/index.js +338 -222
  6. package/dist/index.js.map +1 -1
  7. package/dist/interactive2/movable-point.d.ts +195 -1
  8. package/dist/interactive2/movable.d.ts +1 -1
  9. package/dist/interactive2/types.d.ts +4 -2
  10. package/dist/interactive2.d.ts +2 -1
  11. package/dist/server-item-renderer.d.ts +2 -2
  12. package/dist/util/graphie.d.ts +12 -2
  13. package/dist/widgets/expression.d.ts +6 -6
  14. package/package.json +11 -8
  15. package/.babelrc.js +0 -8
  16. package/.eslintrc.js +0 -12
  17. package/CHANGELOG.md +0 -1432
  18. package/src/__stories__/article-renderer.stories.tsx +0 -100
  19. package/src/__stories__/hints-renderer.stories.tsx +0 -55
  20. package/src/__stories__/server-item-renderer.stories.tsx +0 -44
  21. package/src/__testdata__/article-renderer.testdata.ts +0 -212
  22. package/src/__testdata__/graphie.testdata.ts +0 -51
  23. package/src/__testdata__/renderer.testdata.ts +0 -274
  24. package/src/__testdata__/server-item-renderer.testdata.ts +0 -171
  25. package/src/__tests__/__snapshots__/perseus-markdown.test.ts.snap +0 -507
  26. package/src/__tests__/__snapshots__/renderer.test.tsx.snap +0 -525
  27. package/src/__tests__/__snapshots__/server-item-renderer.test.tsx.snap +0 -285
  28. package/src/__tests__/a11y.test.ts +0 -303
  29. package/src/__tests__/article-renderer.test.tsx +0 -130
  30. package/src/__tests__/error-boundary.test.tsx +0 -76
  31. package/src/__tests__/extract-perseus-data.test.ts +0 -1027
  32. package/src/__tests__/init.test.ts +0 -10
  33. package/src/__tests__/jipt-paragraphs.test.ts +0 -32
  34. package/src/__tests__/mock-asset-loading-widget.tsx +0 -53
  35. package/src/__tests__/mock-widget.tsx +0 -33
  36. package/src/__tests__/perseus-markdown.test.ts +0 -764
  37. package/src/__tests__/renderability.test.ts +0 -480
  38. package/src/__tests__/renderer-api.test.tsx +0 -302
  39. package/src/__tests__/renderer.test.tsx +0 -1816
  40. package/src/__tests__/server-item-renderer.test.tsx +0 -582
  41. package/src/__tests__/test-items/image-item.ts +0 -24
  42. package/src/__tests__/test-items/input-number-1-item.ts +0 -26
  43. package/src/__tests__/test-items/input-number-2-item.ts +0 -38
  44. package/src/__tests__/test-items/table-item.ts +0 -29
  45. package/src/__tests__/tex-wrangler.test.ts +0 -82
  46. package/src/__tests__/util.test.ts +0 -40
  47. package/src/__tests__/widget-container.test.tsx +0 -126
  48. package/src/__tests__/widgets.test.ts +0 -91
  49. package/src/a11y.ts +0 -45
  50. package/src/all-widgets.ts +0 -9
  51. package/src/article-renderer.tsx +0 -237
  52. package/src/asset-context.ts +0 -30
  53. package/src/basic-widgets.ts +0 -16
  54. package/src/components/__stories__/button-group.stories.tsx +0 -55
  55. package/src/components/__stories__/fixed-to-responsive.stories.tsx +0 -141
  56. package/src/components/__stories__/graph.stories.tsx +0 -28
  57. package/src/components/__stories__/graphie.stories.tsx +0 -33
  58. package/src/components/__stories__/hud.stories.tsx +0 -35
  59. package/src/components/__stories__/icon.stories.tsx +0 -63
  60. package/src/components/__stories__/image-loader.stories.tsx +0 -63
  61. package/src/components/__stories__/info-tip.stories.tsx +0 -31
  62. package/src/components/__stories__/inline-icon.stories.tsx +0 -40
  63. package/src/components/__stories__/input-with-examples.stories.tsx +0 -53
  64. package/src/components/__stories__/lint.stories.tsx +0 -86
  65. package/src/components/__stories__/math-input.stories.tsx +0 -43
  66. package/src/components/__stories__/math-output.stories.tsx +0 -23
  67. package/src/components/__stories__/multi-button-group.stories.tsx +0 -66
  68. package/src/components/__stories__/number-input.stories.tsx +0 -41
  69. package/src/components/__stories__/prop-check-box.stories.tsx +0 -65
  70. package/src/components/__stories__/range-input.stories.tsx +0 -29
  71. package/src/components/__stories__/simple-keypad-input.stories.tsx +0 -27
  72. package/src/components/__stories__/sortable.stories.tsx +0 -77
  73. package/src/components/__stories__/stub-tag-editor.stories.tsx +0 -45
  74. package/src/components/__stories__/svg-image.stories.tsx +0 -74
  75. package/src/components/__stories__/tex.stories.tsx +0 -23
  76. package/src/components/__stories__/text-input.stories.tsx +0 -33
  77. package/src/components/__stories__/text-list-editor.stories.tsx +0 -32
  78. package/src/components/__stories__/tooltip.stories.tsx +0 -52
  79. package/src/components/__stories__/zoomable-tex.stories.tsx +0 -41
  80. package/src/components/__stories__/zoomable.stories.tsx +0 -49
  81. package/src/components/__testdata__/sorter.testdata.ts +0 -19
  82. package/src/components/__tests__/__snapshots__/sortable.test.tsx.snap +0 -163
  83. package/src/components/__tests__/__snapshots__/sorter.test.tsx.snap +0 -265
  84. package/src/components/__tests__/math-input.test.tsx +0 -147
  85. package/src/components/__tests__/number-input.test.tsx +0 -128
  86. package/src/components/__tests__/sortable.test.tsx +0 -269
  87. package/src/components/__tests__/sorter.test.tsx +0 -114
  88. package/src/components/__tests__/zoomable.test.tsx +0 -399
  89. package/src/components/button-group.tsx +0 -130
  90. package/src/components/constants.ts +0 -14
  91. package/src/components/fixed-to-responsive.tsx +0 -169
  92. package/src/components/graph.tsx +0 -444
  93. package/src/components/graphie-classes.ts +0 -153
  94. package/src/components/graphie-movables.ts +0 -338
  95. package/src/components/graphie.tsx +0 -400
  96. package/src/components/highlighting/highlightable-content.tsx +0 -240
  97. package/src/components/highlighting/highlights.ts +0 -207
  98. package/src/components/highlighting/ranges.ts +0 -304
  99. package/src/components/highlighting/types.ts +0 -73
  100. package/src/components/highlighting/ui/highlight-renderer.tsx +0 -172
  101. package/src/components/highlighting/ui/highlight-set-renderer.tsx +0 -185
  102. package/src/components/highlighting/ui/highlight-tooltip.tsx +0 -141
  103. package/src/components/highlighting/ui/highlighting-ui.tsx +0 -143
  104. package/src/components/highlighting/ui/selection-tracker.tsx +0 -186
  105. package/src/components/highlighting/ui/types.ts +0 -21
  106. package/src/components/highlighting/ui/util.ts +0 -165
  107. package/src/components/highlighting/word-indexer.tsx +0 -152
  108. package/src/components/hud.tsx +0 -167
  109. package/src/components/icon.tsx +0 -141
  110. package/src/components/image-loader.tsx +0 -177
  111. package/src/components/info-tip/info-tip.tsx +0 -144
  112. package/src/components/info-tip.tsx +0 -39
  113. package/src/components/inline-icon.tsx +0 -60
  114. package/src/components/input-with-examples.tsx +0 -249
  115. package/src/components/lint.tsx +0 -459
  116. package/src/components/math-input.tsx +0 -474
  117. package/src/components/math-output.tsx +0 -134
  118. package/src/components/multi-button-group.tsx +0 -135
  119. package/src/components/number-input.tsx +0 -249
  120. package/src/components/prop-check-box.tsx +0 -79
  121. package/src/components/range-input.tsx +0 -60
  122. package/src/components/simple-keypad-input.tsx +0 -88
  123. package/src/components/sortable.tsx +0 -958
  124. package/src/components/stub-tag-editor.tsx +0 -53
  125. package/src/components/svg-image.tsx +0 -779
  126. package/src/components/tex.tsx +0 -67
  127. package/src/components/text-input.tsx +0 -129
  128. package/src/components/text-list-editor.tsx +0 -166
  129. package/src/components/tooltip.tsx +0 -410
  130. package/src/components/visibility-observer/__stories__/visibility-observer.stories.tsx +0 -141
  131. package/src/components/visibility-observer/create-visibility-observer.ts +0 -108
  132. package/src/components/visibility-observer/get-scroll-parent.ts +0 -46
  133. package/src/components/visibility-observer/visibility-observer.tsx +0 -124
  134. package/src/components/zoomable-tex.tsx +0 -78
  135. package/src/components/zoomable.tsx +0 -304
  136. package/src/components.ts +0 -15
  137. package/src/definition-context.tsx +0 -59
  138. package/src/dependencies.ts +0 -40
  139. package/src/error-boundary.tsx +0 -70
  140. package/src/extra-widgets.ts +0 -75
  141. package/src/hint-renderer.tsx +0 -151
  142. package/src/hints-renderer.tsx +0 -372
  143. package/src/icon-paths.ts +0 -119
  144. package/src/index.ts +0 -171
  145. package/src/init.ts +0 -56
  146. package/src/interaction-tracker.ts +0 -62
  147. package/src/interactive2/__tests__/movable-mock.ts +0 -55
  148. package/src/interactive2/__tests__/movable-point.test.ts +0 -144
  149. package/src/interactive2/interactive-util.test.ts +0 -93
  150. package/src/interactive2/interactive-util.ts +0 -159
  151. package/src/interactive2/movable-helper-methods.ts +0 -166
  152. package/src/interactive2/movable-line-options.ts +0 -419
  153. package/src/interactive2/movable-line.ts +0 -307
  154. package/src/interactive2/movable-point-options.ts +0 -224
  155. package/src/interactive2/movable-point.tsx +0 -585
  156. package/src/interactive2/movable-polygon-options.ts +0 -389
  157. package/src/interactive2/movable-polygon.ts +0 -360
  158. package/src/interactive2/movable.test.ts +0 -249
  159. package/src/interactive2/movable.ts +0 -437
  160. package/src/interactive2/objective_.ts +0 -79
  161. package/src/interactive2/types.ts +0 -17
  162. package/src/interactive2/wrapped-defaults.ts +0 -87
  163. package/src/interactive2/wrapped-ellipse.ts +0 -94
  164. package/src/interactive2/wrapped-line.ts +0 -116
  165. package/src/interactive2/wrapped-path.ts +0 -51
  166. package/src/interactive2.ts +0 -70
  167. package/src/item-version.ts +0 -10
  168. package/src/jipt-paragraphs.ts +0 -49
  169. package/src/jquery.mobile.vmouse.js +0 -545
  170. package/src/loading-context.ts +0 -21
  171. package/src/logging/log.test.ts +0 -39
  172. package/src/logging/log.ts +0 -97
  173. package/src/mixins/__tests__/widget-prop-denylist.test.ts +0 -21
  174. package/src/mixins/changeable.ts +0 -133
  175. package/src/mixins/editor-jsonify.ts +0 -13
  176. package/src/mixins/widget-jsonify-deprecated.ts +0 -23
  177. package/src/mixins/widget-prop-denylist.ts +0 -48
  178. package/src/multi-items/__stories__/multi-renderer.stories.tsx +0 -83
  179. package/src/multi-items/__testdata__/multi-renderer.testdata.ts +0 -172
  180. package/src/multi-items/__tests__/__snapshots__/multi-renderer.test.tsx.snap +0 -1164
  181. package/src/multi-items/__tests__/items.test.ts +0 -240
  182. package/src/multi-items/__tests__/multi-renderer.test.tsx +0 -914
  183. package/src/multi-items/__tests__/prop-type-builders.test.ts +0 -133
  184. package/src/multi-items/__tests__/shapes.test.ts +0 -43
  185. package/src/multi-items/__tests__/trees.test.ts +0 -317
  186. package/src/multi-items/item-types.ts +0 -56
  187. package/src/multi-items/items.ts +0 -176
  188. package/src/multi-items/multi-renderer.tsx +0 -569
  189. package/src/multi-items/prop-type-builders.ts +0 -106
  190. package/src/multi-items/shape-types.ts +0 -52
  191. package/src/multi-items/shapes.ts +0 -52
  192. package/src/multi-items/tree-types.ts +0 -47
  193. package/src/multi-items/trees.ts +0 -360
  194. package/src/multi-items.ts +0 -75
  195. package/src/perseus-api.tsx +0 -188
  196. package/src/perseus-env.ts +0 -27
  197. package/src/perseus-error.ts +0 -17
  198. package/src/perseus-markdown.tsx +0 -405
  199. package/src/perseus-types.ts +0 -1366
  200. package/src/perseus-version.ts +0 -9
  201. package/src/question-paragraph.tsx +0 -34
  202. package/src/renderability.ts +0 -109
  203. package/src/renderer.tsx +0 -2000
  204. package/src/server-item-renderer.tsx +0 -495
  205. package/src/sigfigs.ts +0 -490
  206. package/src/styles/articles.less +0 -749
  207. package/src/styles/constants.ts +0 -94
  208. package/src/styles/global-constants.ts +0 -343
  209. package/src/styles/global-styles.ts +0 -306
  210. package/src/styles/khan-exercise.css +0 -1468
  211. package/src/styles/media-queries.ts +0 -47
  212. package/src/styles/perseus-renderer.less +0 -732
  213. package/src/styles/shared.ts +0 -130
  214. package/src/styles/util.less +0 -47
  215. package/src/styles/variables.boostrap.less +0 -277
  216. package/src/styles/variables.less +0 -56
  217. package/src/styles/variables.shared.less +0 -340
  218. package/src/styles/widgets/categorizer.less +0 -38
  219. package/src/styles/widgets/dropdown.less +0 -3
  220. package/src/styles/widgets/expression.less +0 -65
  221. package/src/styles/widgets/graded-group.less +0 -36
  222. package/src/styles/widgets/grapher.less +0 -12
  223. package/src/styles/widgets/group.less +0 -19
  224. package/src/styles/widgets/image.less +0 -54
  225. package/src/styles/widgets/interactive-graph.less +0 -64
  226. package/src/styles/widgets/label-image.less +0 -57
  227. package/src/styles/widgets/matcher.less +0 -8
  228. package/src/styles/widgets/matrix.less +0 -126
  229. package/src/styles/widgets/measurer.less +0 -20
  230. package/src/styles/widgets/orderer.less +0 -98
  231. package/src/styles/widgets/passage.less +0 -154
  232. package/src/styles/widgets/plotter.less +0 -31
  233. package/src/styles/widgets/radio.less +0 -58
  234. package/src/styles/widgets/reaction-diagram.less +0 -35
  235. package/src/styles/widgets/sequence.less +0 -5
  236. package/src/styles/widgets/sortable.less +0 -113
  237. package/src/styles/widgets/table.less +0 -57
  238. package/src/styles/widgets/unit.less +0 -15
  239. package/src/tex-wrangler.ts +0 -182
  240. package/src/translation-linter.ts +0 -126
  241. package/src/traversal.ts +0 -138
  242. package/src/types.ts +0 -513
  243. package/src/util/a11y.ts +0 -23
  244. package/src/util/answer-types.test.ts +0 -114
  245. package/src/util/answer-types.ts +0 -876
  246. package/src/util/colors.ts +0 -93
  247. package/src/util/drawing-transform.test.ts +0 -67
  248. package/src/util/drawing-transform.ts +0 -102
  249. package/src/util/extract-perseus-data.ts +0 -539
  250. package/src/util/fix-passage-refs.ts +0 -121
  251. package/src/util/geometry.test.ts +0 -75
  252. package/src/util/geometry.ts +0 -312
  253. package/src/util/graph-bounds.ts +0 -23
  254. package/src/util/graph-utils.ts +0 -15
  255. package/src/util/graphie.test.ts +0 -1277
  256. package/src/util/graphie.ts +0 -1576
  257. package/src/util/interactive.ts +0 -4174
  258. package/src/util/interval.ts +0 -4
  259. package/src/util/katex-preprocess.ts +0 -14
  260. package/src/util/math.test.ts +0 -11
  261. package/src/util/math.ts +0 -294
  262. package/src/util/mobile-native-utils.test.ts +0 -22
  263. package/src/util/mobile-native-utils.ts +0 -12
  264. package/src/util/parse-perseus-json.test.ts +0 -10
  265. package/src/util/parse-perseus-json.ts +0 -13
  266. package/src/util/react-render.tsx +0 -27
  267. package/src/util/register-all-widgets-for-testing.ts +0 -13
  268. package/src/util/scroll-utils.ts +0 -155
  269. package/src/util/sizing-utils.ts +0 -46
  270. package/src/util/tex.ts +0 -73
  271. package/src/util/url-utils.ts +0 -34
  272. package/src/util.graphie.test.ts +0 -45
  273. package/src/util.graphie.ts +0 -59
  274. package/src/util.ts +0 -966
  275. package/src/version.ts +0 -10
  276. package/src/widget-container.tsx +0 -199
  277. package/src/widgets/__stories__/categorizer.stories.tsx +0 -14
  278. package/src/widgets/__stories__/cs-program.stories.tsx +0 -14
  279. package/src/widgets/__stories__/definition.stories.tsx +0 -114
  280. package/src/widgets/__stories__/dropdown.stories.tsx +0 -14
  281. package/src/widgets/__stories__/explanation.stories.tsx +0 -18
  282. package/src/widgets/__stories__/expression.stories.tsx +0 -145
  283. package/src/widgets/__stories__/graded-group-set.stories.tsx +0 -31
  284. package/src/widgets/__stories__/graded-group.stories.tsx +0 -31
  285. package/src/widgets/__stories__/grapher.stories.tsx +0 -46
  286. package/src/widgets/__stories__/group.stories.tsx +0 -14
  287. package/src/widgets/__stories__/iframe.stories.tsx +0 -14
  288. package/src/widgets/__stories__/image.stories.tsx +0 -85
  289. package/src/widgets/__stories__/input-number.stories.tsx +0 -101
  290. package/src/widgets/__stories__/interaction.stories.tsx +0 -14
  291. package/src/widgets/__stories__/interactive-graph.stories.tsx +0 -60
  292. package/src/widgets/__stories__/label-image.stories.tsx +0 -130
  293. package/src/widgets/__stories__/matcher.stories.tsx +0 -14
  294. package/src/widgets/__stories__/matrix.stories.tsx +0 -14
  295. package/src/widgets/__stories__/number-line.stories.tsx +0 -14
  296. package/src/widgets/__stories__/numeric-input.stories.tsx +0 -105
  297. package/src/widgets/__stories__/orderer.stories.tsx +0 -18
  298. package/src/widgets/__stories__/passage-ref.stories.tsx +0 -33
  299. package/src/widgets/__stories__/passage.stories.tsx +0 -39
  300. package/src/widgets/__stories__/plotter.stories.tsx +0 -27
  301. package/src/widgets/__stories__/radio.stories.tsx +0 -86
  302. package/src/widgets/__stories__/random-widgets.stories.tsx +0 -59
  303. package/src/widgets/__stories__/sorter.stories.tsx +0 -14
  304. package/src/widgets/__stories__/test-keypad-context-wrapper.tsx +0 -66
  305. package/src/widgets/__stories__/unit.stories.tsx +0 -28
  306. package/src/widgets/__stories__/video-transcript-link.stories.tsx +0 -23
  307. package/src/widgets/__stories__/video.stories.tsx +0 -22
  308. package/src/widgets/__testdata__/base-radio.testdata.ts +0 -21
  309. package/src/widgets/__testdata__/categorizer.testdata.ts +0 -89
  310. package/src/widgets/__testdata__/cs-program.testdata.ts +0 -27
  311. package/src/widgets/__testdata__/dropdown.testdata.ts +0 -71
  312. package/src/widgets/__testdata__/explanation.testdata.ts +0 -85
  313. package/src/widgets/__testdata__/expression.testdata.ts +0 -198
  314. package/src/widgets/__testdata__/graded-group-set.testdata.ts +0 -356
  315. package/src/widgets/__testdata__/graded-group.testdata.ts +0 -77
  316. package/src/widgets/__testdata__/grapher.testdata.ts +0 -374
  317. package/src/widgets/__testdata__/group.testdata.ts +0 -153
  318. package/src/widgets/__testdata__/iframe.testdata.ts +0 -35
  319. package/src/widgets/__testdata__/image.testdata.ts +0 -36
  320. package/src/widgets/__testdata__/input-number.testdata.ts +0 -72
  321. package/src/widgets/__testdata__/interaction.testdata.ts +0 -262
  322. package/src/widgets/__testdata__/interactive-graph-random.testdata.ts +0 -269
  323. package/src/widgets/__testdata__/interactive-graph.testdata.ts +0 -644
  324. package/src/widgets/__testdata__/label-image.testdata.ts +0 -308
  325. package/src/widgets/__testdata__/matcher.testdata.ts +0 -33
  326. package/src/widgets/__testdata__/matrix.testdata.ts +0 -28
  327. package/src/widgets/__testdata__/number-line.testdata.ts +0 -30
  328. package/src/widgets/__testdata__/numeric-input.testdata.ts +0 -265
  329. package/src/widgets/__testdata__/orderer.testdata.ts +0 -123
  330. package/src/widgets/__testdata__/passage-ref.testdata.ts +0 -101
  331. package/src/widgets/__testdata__/passage.testdata.ts +0 -95
  332. package/src/widgets/__testdata__/plotter.testdata.ts +0 -36
  333. package/src/widgets/__testdata__/radio.testdata.ts +0 -324
  334. package/src/widgets/__testdata__/randomizers.ts +0 -51
  335. package/src/widgets/__testdata__/sorter.testdata.ts +0 -19
  336. package/src/widgets/__testdata__/video.testdata.ts +0 -61
  337. package/src/widgets/__tests__/__snapshots__/categorizer.test.ts.snap +0 -940
  338. package/src/widgets/__tests__/__snapshots__/cs-program.test.ts.snap +0 -67
  339. package/src/widgets/__tests__/__snapshots__/definition.test.ts.snap +0 -97
  340. package/src/widgets/__tests__/__snapshots__/dropdown.test.ts.snap +0 -133
  341. package/src/widgets/__tests__/__snapshots__/explanation.test.ts.snap +0 -425
  342. package/src/widgets/__tests__/__snapshots__/graded-group-set-jipt.test.ts.snap +0 -729
  343. package/src/widgets/__tests__/__snapshots__/graded-group-set.test.ts.snap +0 -339
  344. package/src/widgets/__tests__/__snapshots__/graded-group.test.ts.snap +0 -801
  345. package/src/widgets/__tests__/__snapshots__/grapher.test.ts.snap +0 -2673
  346. package/src/widgets/__tests__/__snapshots__/group.test.tsx.snap +0 -1211
  347. package/src/widgets/__tests__/__snapshots__/iframe.test.ts.snap +0 -61
  348. package/src/widgets/__tests__/__snapshots__/image.test.ts.snap +0 -378
  349. package/src/widgets/__tests__/__snapshots__/input-number.test.ts.snap +0 -495
  350. package/src/widgets/__tests__/__snapshots__/interaction.test.ts.snap +0 -292
  351. package/src/widgets/__tests__/__snapshots__/interactive-graph.test.ts.snap +0 -2889
  352. package/src/widgets/__tests__/__snapshots__/matcher.test.tsx.snap +0 -883
  353. package/src/widgets/__tests__/__snapshots__/matrix.test.ts.snap +0 -514
  354. package/src/widgets/__tests__/__snapshots__/number-line.test.ts.snap +0 -814
  355. package/src/widgets/__tests__/__snapshots__/numeric-input.test.ts.snap +0 -470
  356. package/src/widgets/__tests__/__snapshots__/orderer.test.ts.snap +0 -243
  357. package/src/widgets/__tests__/__snapshots__/passage-ref.test.ts.snap +0 -434
  358. package/src/widgets/__tests__/__snapshots__/passage.test.tsx.snap +0 -1956
  359. package/src/widgets/__tests__/__snapshots__/plotter.test.tsx.snap +0 -827
  360. package/src/widgets/__tests__/__snapshots__/radio.test.ts.snap +0 -4237
  361. package/src/widgets/__tests__/__snapshots__/unit.test.tsx.snap +0 -20
  362. package/src/widgets/__tests__/__snapshots__/video.test.ts.snap +0 -153
  363. package/src/widgets/__tests__/categorizer.test.ts +0 -203
  364. package/src/widgets/__tests__/cs-program.test.ts +0 -43
  365. package/src/widgets/__tests__/definition.test.ts +0 -136
  366. package/src/widgets/__tests__/dropdown.test.ts +0 -105
  367. package/src/widgets/__tests__/explanation.test.ts +0 -198
  368. package/src/widgets/__tests__/expression-mobile.test.tsx +0 -363
  369. package/src/widgets/__tests__/expression.test.tsx +0 -484
  370. package/src/widgets/__tests__/graded-group-set-jipt.test.ts +0 -30
  371. package/src/widgets/__tests__/graded-group-set.test.ts +0 -288
  372. package/src/widgets/__tests__/graded-group.test.ts +0 -232
  373. package/src/widgets/__tests__/grapher.cypress.ts +0 -576
  374. package/src/widgets/__tests__/grapher.test.ts +0 -33
  375. package/src/widgets/__tests__/group.test.tsx +0 -510
  376. package/src/widgets/__tests__/iframe.test.ts +0 -45
  377. package/src/widgets/__tests__/image.test.ts +0 -62
  378. package/src/widgets/__tests__/input-number.test.ts +0 -354
  379. package/src/widgets/__tests__/interaction.test.ts +0 -31
  380. package/src/widgets/__tests__/interactive-graph.cypress.ts +0 -815
  381. package/src/widgets/__tests__/interactive-graph.test.ts +0 -106
  382. package/src/widgets/__tests__/matcher.test.tsx +0 -176
  383. package/src/widgets/__tests__/matrix.test.ts +0 -82
  384. package/src/widgets/__tests__/number-line.test.ts +0 -79
  385. package/src/widgets/__tests__/numeric-input.test.ts +0 -575
  386. package/src/widgets/__tests__/orderer.test.ts +0 -73
  387. package/src/widgets/__tests__/passage-ref.test.ts +0 -168
  388. package/src/widgets/__tests__/passage.test.tsx +0 -224
  389. package/src/widgets/__tests__/plotter.test.tsx +0 -69
  390. package/src/widgets/__tests__/radio/base-radio.test.tsx +0 -470
  391. package/src/widgets/__tests__/radio/choice-icon.test.tsx +0 -90
  392. package/src/widgets/__tests__/radio/choice.test.tsx +0 -310
  393. package/src/widgets/__tests__/radio/focus-ring.test.tsx +0 -22
  394. package/src/widgets/__tests__/radio/option-status.test.tsx +0 -77
  395. package/src/widgets/__tests__/radio.test.ts +0 -807
  396. package/src/widgets/__tests__/randomizers.test.ts +0 -53
  397. package/src/widgets/__tests__/renderQuestion.tsx +0 -101
  398. package/src/widgets/__tests__/unit.test.tsx +0 -168
  399. package/src/widgets/__tests__/video.test.ts +0 -69
  400. package/src/widgets/categorizer.tsx +0 -344
  401. package/src/widgets/cs-program.tsx +0 -227
  402. package/src/widgets/definition.tsx +0 -121
  403. package/src/widgets/deprecated-standin/__stories__/deprecated-standin.stories.tsx +0 -30
  404. package/src/widgets/deprecated-standin/__tests__/__snapshots__/deprecated-standin.test.ts.snap +0 -70
  405. package/src/widgets/deprecated-standin/__tests__/deprecated-standin.test.ts +0 -93
  406. package/src/widgets/deprecated-standin/index.tsx +0 -58
  407. package/src/widgets/dropdown.tsx +0 -142
  408. package/src/widgets/explanation.tsx +0 -317
  409. package/src/widgets/expression.tsx +0 -707
  410. package/src/widgets/graded-group-answer-bar.tsx +0 -142
  411. package/src/widgets/graded-group-set.tsx +0 -338
  412. package/src/widgets/graded-group.tsx +0 -471
  413. package/src/widgets/grapher/util.tsx +0 -799
  414. package/src/widgets/grapher.tsx +0 -660
  415. package/src/widgets/group.tsx +0 -195
  416. package/src/widgets/iframe.tsx +0 -195
  417. package/src/widgets/image.tsx +0 -312
  418. package/src/widgets/input-number.tsx +0 -412
  419. package/src/widgets/interaction/arrow-picker.tsx +0 -38
  420. package/src/widgets/interaction/color-picker.tsx +0 -69
  421. package/src/widgets/interaction/dash-picker.tsx +0 -45
  422. package/src/widgets/interaction/element-container.tsx +0 -100
  423. package/src/widgets/interaction.tsx +0 -826
  424. package/src/widgets/interactive-graph.tsx +0 -2597
  425. package/src/widgets/label-image/__stories__/answer-choices.stories.tsx +0 -91
  426. package/src/widgets/label-image/__stories__/answer-pill.stories.tsx +0 -62
  427. package/src/widgets/label-image/__stories__/marker.stories.tsx +0 -171
  428. package/src/widgets/label-image/__tests__/answer-pill.test.tsx +0 -75
  429. package/src/widgets/label-image/__tests__/hide-answers-toggle.test.tsx +0 -39
  430. package/src/widgets/label-image/answer-choices.tsx +0 -88
  431. package/src/widgets/label-image/answer-pill.tsx +0 -103
  432. package/src/widgets/label-image/hide-answers-toggle.tsx +0 -40
  433. package/src/widgets/label-image/marker.tsx +0 -268
  434. package/src/widgets/label-image/strings.ts +0 -5
  435. package/src/widgets/label-image/types.ts +0 -27
  436. package/src/widgets/label-image.test.ts +0 -928
  437. package/src/widgets/label-image.tsx +0 -819
  438. package/src/widgets/lights-puzzle.tsx +0 -359
  439. package/src/widgets/matcher.tsx +0 -298
  440. package/src/widgets/matrix.tsx +0 -634
  441. package/src/widgets/measurer.tsx +0 -222
  442. package/src/widgets/molecule/__tests__/layout.test.ts +0 -162
  443. package/src/widgets/molecule/__tests__/parser.test.ts +0 -155
  444. package/src/widgets/molecule/molecule-drawing.ts +0 -173
  445. package/src/widgets/molecule/molecule-layout.ts +0 -362
  446. package/src/widgets/molecule/smiles-parser.ts +0 -296
  447. package/src/widgets/molecule.tsx +0 -172
  448. package/src/widgets/number-line.tsx +0 -862
  449. package/src/widgets/numeric-input.tsx +0 -576
  450. package/src/widgets/orderer.tsx +0 -786
  451. package/src/widgets/passage/__tests__/passage-markdown.test.ts +0 -376
  452. package/src/widgets/passage/passage-markdown.tsx +0 -475
  453. package/src/widgets/passage-ref-target.tsx +0 -76
  454. package/src/widgets/passage-ref.tsx +0 -213
  455. package/src/widgets/passage.tsx +0 -582
  456. package/src/widgets/plotter.tsx +0 -1194
  457. package/src/widgets/radio/__stories__/base-radio.stories.tsx +0 -196
  458. package/src/widgets/radio/__stories__/choice-icon.stories.tsx +0 -166
  459. package/src/widgets/radio/__stories__/choice-none-above.stories.tsx +0 -40
  460. package/src/widgets/radio/__stories__/choice.stories.tsx +0 -137
  461. package/src/widgets/radio/__stories__/focus-ring.stories.tsx +0 -43
  462. package/src/widgets/radio/__stories__/option-status.stories.tsx +0 -103
  463. package/src/widgets/radio/base-radio.tsx +0 -511
  464. package/src/widgets/radio/choice-a11y-text.ts +0 -61
  465. package/src/widgets/radio/choice-icon/choice-icon.tsx +0 -218
  466. package/src/widgets/radio/choice-icon/cross-out-line.tsx +0 -51
  467. package/src/widgets/radio/choice-icon/shared-styles.ts +0 -15
  468. package/src/widgets/radio/choice-none-above.tsx +0 -56
  469. package/src/widgets/radio/choice.jsx.fixture.ts +0 -45
  470. package/src/widgets/radio/choice.tsx +0 -359
  471. package/src/widgets/radio/focus-ring.tsx +0 -57
  472. package/src/widgets/radio/option-status.tsx +0 -98
  473. package/src/widgets/radio/util.test.ts +0 -18
  474. package/src/widgets/radio/util.ts +0 -31
  475. package/src/widgets/radio/widget.tsx +0 -520
  476. package/src/widgets/radio.ts +0 -157
  477. package/src/widgets/reaction-diagram.tsx +0 -144
  478. package/src/widgets/sequence.tsx +0 -142
  479. package/src/widgets/simulator.tsx +0 -829
  480. package/src/widgets/sorter.tsx +0 -155
  481. package/src/widgets/table.tsx +0 -393
  482. package/src/widgets/unit.tsx +0 -374
  483. package/src/widgets/video-transcript-link.test.tsx +0 -213
  484. package/src/widgets/video-transcript-link.tsx +0 -84
  485. package/src/widgets/video.tsx +0 -135
  486. package/src/widgets.ts +0 -489
  487. package/src/zoom.ts +0 -555
  488. package/tsconfig-build.json +0 -26
  489. package/tsconfig-build.tsbuildinfo +0 -1
@@ -1,400 +0,0 @@
1
- import $ from "jquery";
2
- import * as React from "react";
3
- import ReactDOM from "react-dom";
4
- import _ from "underscore";
5
-
6
- import InteractiveUtil from "../interactive2/interactive-util";
7
- import {Errors, Log} from "../logging/log";
8
- import Util from "../util";
9
- import GraphUtils from "../util/graph-utils";
10
- import {Graphie as GraphieDrawingContext} from "../util/graphie";
11
-
12
- import GraphieClasses from "./graphie-classes";
13
- import Movables from "./graphie-movables";
14
-
15
- import type {Coord} from "../interactive2/types";
16
- import type {Range, Size} from "../perseus-types";
17
-
18
- const GraphieMovable = GraphieClasses.GraphieMovable;
19
-
20
- const createGraphie = GraphUtils.createGraphie;
21
- const {deepEq, nestedMap} = Util;
22
- const {assert} = InteractiveUtil;
23
-
24
- type Props = {
25
- addMouseLayer?: boolean;
26
- box: Size;
27
- range: [Coord, Coord];
28
- ranges?: [Range, Range];
29
- gridStep?: [number, number];
30
- step?: [number, number];
31
- scale?: [number, number];
32
-
33
- isMobile?: boolean;
34
- responsive?: boolean;
35
-
36
- children?: React.ReactNode;
37
-
38
- // TODO(LC-772) - type this prop!
39
- options: any;
40
-
41
- setDrawingAreaAvailable?: (boolean) => void;
42
- setup: (
43
- graphie: any,
44
- options: {
45
- range: [Coord, Coord];
46
- scale: [number, number];
47
- },
48
- ) => void;
49
-
50
- onClick?: (at: Coord) => void;
51
- onMouseDown?: (at: Coord) => void;
52
- onMouseMove?: (at: Coord) => void;
53
- onMouseUp?: (at: Coord) => void;
54
- };
55
-
56
- type DefaultProps = {
57
- range: Props["range"];
58
- options: Props["options"];
59
- responsive: Props["responsive"];
60
- addMouseLayer: Props["addMouseLayer"];
61
- };
62
-
63
- interface Movable {
64
- remove(): void;
65
- props: unknown;
66
- modify(graphie: GraphieDrawingContext): "reordered" | undefined;
67
- toFront(): void;
68
- }
69
-
70
- class Graphie extends React.Component<Props> {
71
- graphieDivRef = React.createRef<HTMLDivElement>();
72
- _graphie: GraphieDrawingContext = new GraphieDrawingContext(
73
- document.createElement("div"),
74
- );
75
- _movables: Record<string, Movable> = {};
76
- movables: Record<string, Movable> = {};
77
-
78
- static defaultProps: DefaultProps = {
79
- range: [
80
- [-10, 10],
81
- [-10, 10],
82
- ],
83
- options: {},
84
- responsive: false,
85
- addMouseLayer: true,
86
- };
87
-
88
- componentDidMount() {
89
- this._setupGraphie();
90
- this._updateMovables();
91
- }
92
-
93
- shouldComponentUpdate(nextProps: Props): boolean {
94
- // NOTE(jeresig): Prior to the React 16 upgrade this was using deepEq
95
- // However it started to throw errors. I switched to use Underscore's
96
- // isEqual method instead, hopefully having a similar effect.
97
- return !_.isEqual(this.props, nextProps);
98
- }
99
-
100
- componentDidUpdate(prevProps: Props) {
101
- // If someone changes the setup function passed in, we should
102
- // technically setup graphie again. But that's definitely an
103
- // anti-pattern, since it is most-likely caused by passing in an
104
- // anonymous function rather than a "real" change, and re-rendering
105
- // in that case would cause us to constantly re-setup graphie, which
106
- // would have horrible performance implications. In order to avoid
107
- // those, we just warn here.
108
- if (this.props.setup !== prevProps.setup) {
109
- Log.error(
110
- "<Graphie> was given a new setup function. " +
111
- "This is a bad idea; please refactor your code to give " +
112
- "the same setup function reference to <Graphie> on " +
113
- "every render.",
114
- Errors.Internal,
115
- );
116
- }
117
- if (
118
- !deepEq(this.props.options, prevProps.options) ||
119
- !deepEq(this.props.box, prevProps.box) ||
120
- !deepEq(this.props.range, prevProps.range)
121
- ) {
122
- this._setupGraphie();
123
- }
124
- this._updateMovables();
125
- }
126
-
127
- /**
128
- * Allow parents of the <Graphie> component to grab a reference to the
129
- * underlying graphie object using
130
- * `this.refs.graphieComponent.getGraphie()`
131
- *
132
- * This shouldn't be necessary for 90% of cases, but the power is there.
133
- * Use it for good and not evil.
134
- */
135
- getGraphie: () => any = () => {
136
- return this._graphie;
137
- };
138
-
139
- // bounds-checked range
140
- _range: () => [Coord, Coord] = () => {
141
- const boundsCheckRange = (range: Coord): Coord => {
142
- if (range[0] >= range[1]) {
143
- return [-10, 10];
144
- }
145
- return range;
146
- };
147
- return [
148
- boundsCheckRange(this.props.range[0]),
149
- boundsCheckRange(this.props.range[1]),
150
- ];
151
- };
152
-
153
- _box: () => Size = () => {
154
- const ensureMinSize = (pixelDim: number): number => {
155
- // 340 = default size in the editor. exact value
156
- // is arbitrary; this is just a safety check.
157
- return pixelDim > 0 ? pixelDim : 340;
158
- };
159
-
160
- return [
161
- ensureMinSize(this.props.box[0]),
162
- ensureMinSize(this.props.box[1]),
163
- ];
164
- };
165
-
166
- // @ts-expect-error - TS2322: Type '() => number[]' is not assignable to type '() => Coord'.
167
- _scale: () => Coord = () => {
168
- const box = this._box();
169
- const range = this._range();
170
- return box.map((pixelDim, i) => {
171
- const unitDim = range[i][1] - range[i][0];
172
- return pixelDim / unitDim;
173
- });
174
- };
175
-
176
- _setupGraphie: () => void = () => {
177
- this._removeMovables();
178
-
179
- const graphieDiv = ReactDOM.findDOMNode(this.graphieDivRef.current);
180
- if (graphieDiv == null || graphieDiv instanceof Text) {
181
- throw new Error("No graphie container div found");
182
- }
183
- graphieDiv.innerHTML = "";
184
- const graphie = (this._graphie = createGraphie(graphieDiv));
185
-
186
- // This has to be called before addMouseLayer. You can re-init
187
- // with graphInit later if you prefer
188
- graphie.init({
189
- range: this._range(),
190
- scale: this._scale(),
191
- isMobile: this.props.isMobile,
192
- });
193
- // Only add the mouselayer if we actually want one.
194
- if (this.props.addMouseLayer) {
195
- // @ts-expect-error - TS2339: Property 'addMouseLayer' does not exist on type 'Graphie'.
196
- graphie.addMouseLayer({
197
- onClick: this.props.onClick,
198
- onMouseDown: this.props.onMouseDown,
199
- onMouseUp: this.props.onMouseUp,
200
- onMouseMove: this.props.onMouseMove,
201
- setDrawingAreaAvailable: this.props.setDrawingAreaAvailable,
202
- });
203
- }
204
-
205
- // @ts-expect-error - TS2339: Property 'snap' does not exist on type 'Graphie'.
206
- graphie.snap = this.props.options.snapStep || [1, 1];
207
-
208
- if (this.props.responsive) {
209
- // Overwrite fixed styles set in init()
210
- // TODO(alex): Either make this component always responsive by
211
- // itself, or always wrap it in other components so that it is.
212
- $(graphieDiv).css({width: "100%", height: "100%"});
213
- graphie.raphael.setSize("100%", "100%");
214
- }
215
-
216
- this.props.setup(
217
- graphie,
218
- _.extend(
219
- {
220
- range: this._range(),
221
- scale: this._scale(),
222
- },
223
- this.props.options,
224
- ),
225
- );
226
- };
227
-
228
- _removeMovables: () => void = () => {
229
- // _.invoke works even when this._movables is undefined
230
- _.invoke(this._movables, "remove");
231
- this._movables = {};
232
- };
233
-
234
- // @ts-expect-error - TS2322 - Type '(children: readonly any[], options: any) => ReactElement<any, string | JSXElementConstructor<any>> | readonly ReactElement<any, string | JSXElementConstructor<any>>[]' is not assignable to type '(children: readonly any[], arg2: any) => ReactElement<any, string | JSXElementConstructor<any>>'.
235
- _renderMovables: (
236
- children: ReadonlyArray<any>,
237
- arg2: {
238
- nextKey: number;
239
- graphie: GraphieDrawingContext;
240
- oldMovables: Record<string, Movable>;
241
- newMovables: Record<string, Movable>;
242
- },
243
- ) => React.ReactElement = (children, options) => {
244
- // Each leaf of `children` is a movable descriptor created by a call to
245
- // some `GraphieMovable`, such as `MovablePoint`.
246
- //
247
- // This function takes these descriptors and renders them into
248
- // on-screen movables, or updates on-screen movables for
249
- // descriptors when possible.
250
- //
251
- // If there is no movable with that key already, this descriptor is
252
- // stored in this._movables and promoted to an on-screen movable by
253
- // calling `child.add(graphie)`.
254
- //
255
- // If a movable of the same type with the same key exists already,
256
- // we take `child.props` and give them to the already-existing
257
- // on-screen movable, and call `movable.modify()`
258
-
259
- const graphie = options.graphie;
260
- const oldMovables = options.oldMovables;
261
- const newMovables = options.newMovables; /* output parameter */
262
-
263
- const renderChildren = (elem: any) => {
264
- _.each(elem.movableProps, (prop) => {
265
- // Render the children, and save the results of that
266
- // render to the appropriate props
267
- elem.props[prop] = this._renderMovables(
268
- elem.props[prop],
269
- options,
270
- );
271
- });
272
- };
273
-
274
- // Add/modify movables
275
-
276
- // We want to keep track of whether we have added a new svg element,
277
- // because if we have, then we need to call .toFront() on any svg
278
- // elements occurring afterwards. If this happens, we set
279
- // `areMovablesOutOfOrder` to true:
280
- let areMovablesOutOfOrder = false;
281
- // @ts-expect-error - TS2554 - Expected 3 arguments, but got 2.
282
- return nestedMap(children, (childDescriptor) => {
283
- if (!childDescriptor) {
284
- // Still increment the key to avoid cascading key changes
285
- // on hiding/unhiding children, i.e. by using
286
- // {someBoolean && <MovablePoint />}
287
- options.nextKey++;
288
- // preserve the null/undefined in the resulting array
289
- return childDescriptor;
290
- }
291
-
292
- // Instantiate the descriptor to turn it into a real Movable
293
- const child = new childDescriptor.type(childDescriptor.props);
294
- assert(
295
- child instanceof GraphieMovable,
296
- "All children of a Graphie component must be Graphie " +
297
- "movables",
298
- );
299
-
300
- // Give each child a key
301
- const keyProp = childDescriptor.key;
302
- const key = keyProp == null ? "_no_id_" + options.nextKey : keyProp;
303
- options.nextKey++;
304
- const ref = childDescriptor.ref;
305
-
306
- // We render our children first. This allows us to replace any
307
- // `movableProps` on our child with the on-screen movables
308
- // corresponding with those descriptors.
309
- renderChildren(child);
310
-
311
- const prevMovable = oldMovables[key];
312
- if (!prevMovable) {
313
- // We're creating a new child
314
- child.add(graphie);
315
- areMovablesOutOfOrder = true;
316
-
317
- newMovables[key] = child;
318
- } else if (child.constructor === prevMovable.constructor) {
319
- // We're updating an old child
320
- prevMovable.props = child.props;
321
- const modifyResult = prevMovable.modify(graphie);
322
- if (modifyResult === "reordered") {
323
- areMovablesOutOfOrder = true;
324
- }
325
-
326
- newMovables[key] = prevMovable;
327
- } else {
328
- // We're destroying an old child and replacing it
329
- // with a new child of a different type
330
-
331
- // This generally is a bad idea, so warn about it if this
332
- // is being caused by implicit keys
333
- if (keyProp == null) {
334
- Log.error(
335
- "Replacing a <Graphie> child with a " +
336
- "child of a different type. Please add keys " +
337
- "to your <Graphie> children",
338
- Errors.Internal,
339
- );
340
- }
341
-
342
- prevMovable.remove();
343
- child.add(graphie);
344
- areMovablesOutOfOrder = true;
345
-
346
- newMovables[key] = child;
347
- }
348
-
349
- if (areMovablesOutOfOrder) {
350
- newMovables[key].toFront();
351
- }
352
-
353
- if (ref) {
354
- this.movables[ref] = newMovables[key];
355
- }
356
-
357
- return newMovables[key];
358
- });
359
- };
360
-
361
- // Sort of like react diffing, but for movables
362
- _updateMovables: () => void = () => {
363
- const graphie = this._graphie;
364
-
365
- const oldMovables = this._movables;
366
- const newMovables: Record<string, any> = {};
367
- this._movables = newMovables;
368
- this.movables = {};
369
-
370
- // @ts-expect-error - TS2345 - Argument of type 'ReactNode' is not assignable to parameter of type 'readonly any[]'.
371
- this._renderMovables(this.props.children, {
372
- nextKey: 1,
373
- graphie: graphie,
374
- oldMovables: oldMovables,
375
- newMovables: newMovables,
376
- });
377
-
378
- // Remove any movables that no longer exist in the child array
379
- _.each(oldMovables, (oldMovable, key) => {
380
- if (!newMovables[key]) {
381
- oldMovable.remove();
382
- }
383
- });
384
- };
385
-
386
- render(): React.ReactNode {
387
- return (
388
- <div className="graphie-container">
389
- <div className="graphie" ref={this.graphieDivRef} />
390
- </div>
391
- );
392
- }
393
- }
394
-
395
- // Attach Graphie.createClass and Graphie.createSimpleClass
396
- _.extend(Graphie, GraphieClasses);
397
- // Attach the Movable react components for easy reference
398
- _.extend(Graphie, Movables);
399
-
400
- export default Graphie;
@@ -1,240 +0,0 @@
1
- /**
2
- * The entry point for highlighting!
3
- *
4
- * Given a content node and a set of serialized highlights, this component
5
- * renders the content with the given highlights applied. The content's DOM is
6
- * not modified by this process, so any content should be safe to pass to this
7
- * component.
8
- *
9
- * This component also renders controls for the user to add/remove/update
10
- * highlights. When the user does so, this component will update the full set
11
- * of highlights, serialize them, and call `onSerializedHighlightsUpdate` with
12
- * new set of serialized highlights, which you can then persist and send back
13
- * down to this component. Easy peasy!
14
- */
15
- import {StyleSheet, css} from "aphrodite";
16
- import * as React from "react";
17
-
18
- import {
19
- addHighlight,
20
- buildHighlight,
21
- deserializeHighlight,
22
- serializeHighlight,
23
- } from "./highlights";
24
- import HighlightingUI from "./ui/highlighting-ui";
25
- import WordIndexer from "./word-indexer";
26
-
27
- import type {
28
- DOMHighlight,
29
- DOMHighlightSet,
30
- SerializedHighlightSet,
31
- DOMRange,
32
- } from "./types";
33
-
34
- type Props = {
35
- // The highlightable content itself. Highlights will be defined relative to
36
- // the content specified here.
37
- children?: React.ReactElement<any>;
38
- // Whether the highlights are user-editable. If false, highlights are
39
- // read-only.
40
- editable: boolean;
41
- // Whether highlighting is currently enabled. If false, highlights are not
42
- // visible and are read-only (regardless of the `editable` prop), and this
43
- // component is effectively a no-op.
44
- //
45
- // NOTE(mdr): The purpose of the `enabled` prop, as opposed to, say, just
46
- // *not* wrapping the content, is to enable quick toggles between
47
- // enabled/disabled while maintaining the same component structure.
48
- // Forcing React to rebuild the entire component tree is not kind!
49
- enabled: boolean;
50
- // When the user attempts to add/remove/update a highlight, this callback
51
- // will be called with a newly-updated full set of highlights that reflects
52
- // the user's intent.
53
- onSerializedHighlightsUpdate: (
54
- serializedHighlights: SerializedHighlightSet,
55
- ) => unknown;
56
- // The set of highlights to apply to the given content.
57
- serializedHighlights: SerializedHighlightSet;
58
- };
59
-
60
- type State = {
61
- // A cached list of DOMRanges, each representing one of the content's
62
- // semantic words. Sorted in document order.
63
- wordRanges: ReadonlyArray<DOMRange>;
64
- };
65
-
66
- class HighlightableContent extends React.PureComponent<Props, State> {
67
- // References to the mounted container and content divs.
68
- _container: HTMLElement | null | undefined;
69
- _content: HTMLElement | null | undefined;
70
-
71
- state: State = {
72
- wordRanges: [],
73
- };
74
-
75
- _buildHighlight(highlightRange: DOMRange): DOMHighlight | null | undefined {
76
- // TODO(mdr): If _buildHighlight starts getting called more often, we
77
- // might want to cache the DOMHighlightSet instead of recomputing
78
- // it here.
79
- return buildHighlight(
80
- this._getDOMHighlights(),
81
- this.state.wordRanges,
82
- highlightRange,
83
- );
84
- }
85
-
86
- /**
87
- * Take the highlights from props, and deserialize them into DOMHighlights,
88
- * according to the latest cache of word ranges.
89
- */
90
- _getDOMHighlights(): DOMHighlightSet {
91
- const {serializedHighlights} = this.props;
92
- const {wordRanges} = this.state;
93
-
94
- const domHighlights: Record<string, any> = {};
95
- for (const key of Object.keys(serializedHighlights)) {
96
- domHighlights[key] = deserializeHighlight(
97
- serializedHighlights[key],
98
- wordRanges,
99
- );
100
- }
101
- return domHighlights;
102
- }
103
-
104
- /**
105
- * Add the given DOMHighlight to the current set.
106
- */
107
- _handleAddHighlight: (highlight: DOMHighlight) => void = (
108
- highlight: DOMHighlight,
109
- ) => {
110
- const newDomHighlights = addHighlight(
111
- this._getDOMHighlights(),
112
- highlight,
113
- );
114
-
115
- const newSerializedHighlights: Record<string, any> = {};
116
- for (const key of Object.keys(newDomHighlights)) {
117
- newSerializedHighlights[key] = serializeHighlight(
118
- newDomHighlights[key],
119
- );
120
- }
121
-
122
- this.props.onSerializedHighlightsUpdate(newSerializedHighlights);
123
- };
124
-
125
- /**
126
- * Remove the given highlight from the list, and call our callback with the
127
- * new set of highlights.
128
- */
129
- _handleRemoveHighlight: (keyToRemove: string) => void = (
130
- keyToRemove: string,
131
- ) => {
132
- const {serializedHighlights} = this.props;
133
- const newSerializedHighlights = {...serializedHighlights} as const;
134
- // @ts-expect-error - TS2542 - Index signature in type '{ readonly [x: string]: SerializedHighlight; }' only permits reading.
135
- delete newSerializedHighlights[keyToRemove];
136
- this.props.onSerializedHighlightsUpdate(newSerializedHighlights);
137
- };
138
-
139
- /**
140
- * When our WordIndexer sends us a new cache of word ranges, store it in
141
- * our component state.
142
- */
143
- _handleWordsUpdate: (wordRanges: ReadonlyArray<DOMRange>) => void = (
144
- wordRanges: ReadonlyArray<DOMRange>,
145
- ) => {
146
- this.setState({wordRanges});
147
- };
148
-
149
- render(): React.ReactNode {
150
- const highlights = this._getDOMHighlights();
151
-
152
- // NOTE(mdr): This lambda is rebuilt every time this component updates,
153
- // so every update to HighlightableContent triggers an update in
154
- // the child HighlightingUI and SelectionTracker, even if the
155
- // behavior hasn't changed.
156
- //
157
- // Over-updating is preferable to under-updating here, because some
158
- // updates in this component's props/state *do* affect
159
- // `buildHighlight`'s behavior, and *should* trigger an update.
160
- //
161
- // A more performant approach would be to cache this function
162
- // object until its implicitly-bound inputs change. If profiling
163
- // leads us to implement such caching, this draft might be a good
164
- // starting point: https://phabricator.khanacademy.org/D35623?id=170698
165
- const buildHighlight = (r: DOMRange) => this._buildHighlight(r);
166
-
167
- return (
168
- <div
169
- className={css(styles.container)}
170
- ref={(container) => (this._container = container)}
171
- >
172
- <div>
173
- {this.props.enabled && this._container && this._content && (
174
- <HighlightingUI
175
- buildHighlight={buildHighlight}
176
- contentNode={this._content}
177
- editable={this.props.editable}
178
- highlights={highlights}
179
- offsetParent={this._container}
180
- zIndexes={{
181
- // The content has a z-index of 1, so, to
182
- // be below the content, use z-index of 0.
183
- //
184
- // TODO(mdr): Is this way of passing around
185
- // `z-index: 0` actually worth the
186
- // trouble? We used to have more, but
187
- // now we don't need them...
188
- belowContent: 0,
189
- }}
190
- onAddHighlight={this._handleAddHighlight}
191
- onRemoveHighlight={this._handleRemoveHighlight}
192
- />
193
- )}
194
- </div>
195
- <div
196
- className={css(styles.content)}
197
- ref={(content) => (this._content = content)}
198
- >
199
- <WordIndexer onWordsUpdate={this._handleWordsUpdate}>
200
- {this.props.children}
201
- </WordIndexer>
202
- </div>
203
- </div>
204
- );
205
- }
206
- }
207
-
208
- const styles = StyleSheet.create({
209
- // We render content with z-index 1, and highlights with z-index 0, so that
210
- // content will receive the browser's native pointer events. (Highlights
211
- // have their own magic code to manage hover detection, despite being
212
- // behind the content.)
213
-
214
- container: {
215
- // Position the container and give it a z-index, to scope the z-indexes
216
- // inside by creating a stacking context.
217
- // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
218
- //
219
- // This way, content's z-index of 1, and highlights' z-index of 0, and
220
- // tooltips' z-index of 2 don't interact with anything external;
221
- // external UI will see `HighlightableContent` as a single flat layer
222
- // with a z-index of 0. This removes the need for us to coordinate our
223
- // choices of z-index with external UI.
224
- position: "relative",
225
- zIndex: 0,
226
- },
227
-
228
- content: {
229
- // NOTE(mdr): Creating a stacking context for content of z-index 1 may
230
- // be problematic if the content and external page want to
231
- // interleave layers between each other, e.g., if the application UI
232
- // wants to render something above some parts of our content, but
233
- // below other parts. It's not relevant for the current Passage-only
234
- // call site, but could be relevant someday…
235
- position: "relative",
236
- zIndex: 1,
237
- },
238
- });
239
-
240
- export default HighlightableContent;