@khanacademy/perseus 0.0.1 → 0.2.1

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 (507) hide show
  1. package/.babelrc.js +1 -1
  2. package/CHANGELOG.md +29 -0
  3. package/dist/es/index.css +4361 -0
  4. package/dist/es/index.js +7 -1
  5. package/dist/es/index.js.map +1 -1
  6. package/dist/index.css +4361 -0
  7. package/dist/index.js +7 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/strings.js +148 -46
  10. package/package.json +50 -4
  11. package/src/README.md +35 -0
  12. package/src/__stories__/item-renderer.stories.jsx +27 -0
  13. package/src/__stories__/server-item-renderer.stories.jsx +27 -0
  14. package/src/__testdata__/item-renderer_testdata.js +161 -0
  15. package/src/__testdata__/renderer_testdata.js +123 -0
  16. package/src/__tests__/__snapshots__/item-renderer_test.jsx.snap +233 -0
  17. package/src/__tests__/__snapshots__/perseus-markdown_test.jsx.snap +516 -0
  18. package/src/__tests__/__snapshots__/pure-markdown_test.js.snap +113 -0
  19. package/src/__tests__/__snapshots__/renderer_test.jsx.snap +576 -0
  20. package/src/__tests__/__snapshots__/server-item-renderer_test.jsx.snap +306 -0
  21. package/src/__tests__/a11y_test.jsx +304 -0
  22. package/src/__tests__/item-renderer_test.jsx +892 -0
  23. package/src/__tests__/mock-asset-loading-widget.jsx +57 -0
  24. package/src/__tests__/mock-widget.jsx +35 -0
  25. package/src/__tests__/perseus-markdown_test.jsx +747 -0
  26. package/src/__tests__/pure-markdown_test.js +552 -0
  27. package/src/__tests__/renderability_test.jsx +481 -0
  28. package/src/__tests__/renderer-api_test.jsx +333 -0
  29. package/src/__tests__/renderer_test.jsx +1792 -0
  30. package/src/__tests__/server-item-renderer_test.jsx +516 -0
  31. package/src/__tests__/test-items/image-item.js +25 -0
  32. package/src/__tests__/test-items/input-number-1-item.js +27 -0
  33. package/src/__tests__/test-items/input-number-2-item.js +39 -0
  34. package/src/__tests__/test-items/table-item.js +30 -0
  35. package/src/__tests__/tex-wrangler_test.js +83 -0
  36. package/src/__tests__/util_test.js +41 -0
  37. package/src/a11y.js +46 -0
  38. package/src/all-widgets.js +9 -0
  39. package/src/article-renderer.jsx +215 -0
  40. package/src/asset-context.js +30 -0
  41. package/src/basic-widgets.js +13 -0
  42. package/src/components/__stories__/button-group.stories.jsx +61 -0
  43. package/src/components/__stories__/fixed-to-responsive.stories.jsx +132 -0
  44. package/src/components/__stories__/graph.stories.jsx +27 -0
  45. package/src/components/__stories__/graphie.stories.jsx +28 -0
  46. package/src/components/__stories__/hud.stories.jsx +36 -0
  47. package/src/components/__stories__/icon.stories.jsx +56 -0
  48. package/src/components/__stories__/image-loader.stories.jsx +60 -0
  49. package/src/components/__stories__/info-tip.stories.jsx +33 -0
  50. package/src/components/__stories__/inline-icon.stories.jsx +39 -0
  51. package/src/components/__stories__/input-with-examples.stories.jsx +51 -0
  52. package/src/components/__stories__/lint.stories.jsx +40 -0
  53. package/src/components/__stories__/math-input.stories.jsx +29 -0
  54. package/src/components/__stories__/math-output.stories.jsx +24 -0
  55. package/src/components/__stories__/multi-button-group.stories.jsx +69 -0
  56. package/src/components/__stories__/number-input.stories.jsx +42 -0
  57. package/src/components/__stories__/possible-answers.stories.jsx +22 -0
  58. package/src/components/__stories__/prop-check-box.stories.jsx +62 -0
  59. package/src/components/__stories__/range-input.stories.jsx +28 -0
  60. package/src/components/__stories__/simple-keypad-input.stories.jsx +28 -0
  61. package/src/components/__stories__/sortable.stories.jsx +73 -0
  62. package/src/components/__stories__/stub-tag-editor.stories.jsx +44 -0
  63. package/src/components/__stories__/svg-image.stories.jsx +60 -0
  64. package/src/components/__stories__/tex.stories.jsx +18 -0
  65. package/src/components/__stories__/text-buttons.stories.jsx +51 -0
  66. package/src/components/__stories__/text-input.stories.jsx +34 -0
  67. package/src/components/__stories__/text-list-editor.stories.jsx +33 -0
  68. package/src/components/__stories__/zoomable-tex.stories.jsx +39 -0
  69. package/src/components/__stories__/zoomable.stories.jsx +40 -0
  70. package/src/components/__testdata__/sorter_testdata.js +20 -0
  71. package/src/components/__tests__/__snapshots__/sortable_test.jsx.snap +79 -0
  72. package/src/components/__tests__/__snapshots__/sorter_test.jsx.snap +297 -0
  73. package/src/components/__tests__/number-input_test.jsx +112 -0
  74. package/src/components/__tests__/sortable_test.jsx +234 -0
  75. package/src/components/__tests__/sorter_test.jsx +111 -0
  76. package/src/components/__tests__/zoomable_test.jsx +388 -0
  77. package/src/components/button-group.jsx +131 -0
  78. package/src/components/constants.js +15 -0
  79. package/src/components/fixed-to-responsive.jsx +164 -0
  80. package/src/components/graph.jsx +415 -0
  81. package/src/components/graphie-classes.jsx +148 -0
  82. package/src/components/graphie-movables.jsx +342 -0
  83. package/src/components/graphie.jsx +353 -0
  84. package/src/components/highlighting/highlightable-content.jsx +245 -0
  85. package/src/components/highlighting/highlights.js +208 -0
  86. package/src/components/highlighting/ranges.js +299 -0
  87. package/src/components/highlighting/types.js +73 -0
  88. package/src/components/highlighting/ui/highlight-renderer.jsx +179 -0
  89. package/src/components/highlighting/ui/highlight-set-renderer.jsx +190 -0
  90. package/src/components/highlighting/ui/highlight-tooltip.jsx +153 -0
  91. package/src/components/highlighting/ui/highlighting-ui.jsx +163 -0
  92. package/src/components/highlighting/ui/selection-tracker.jsx +195 -0
  93. package/src/components/highlighting/ui/types.js +21 -0
  94. package/src/components/highlighting/ui/util.js +166 -0
  95. package/src/components/highlighting/word-indexer.jsx +155 -0
  96. package/src/components/hud.jsx +179 -0
  97. package/src/components/icon.jsx +149 -0
  98. package/src/components/image-loader.jsx +175 -0
  99. package/src/components/info-tip/info-tip.jsx +146 -0
  100. package/src/components/info-tip.jsx +38 -0
  101. package/src/components/inline-icon.jsx +81 -0
  102. package/src/components/input-with-examples.jsx +231 -0
  103. package/src/components/lint.jsx +454 -0
  104. package/src/components/math-input.jsx +282 -0
  105. package/src/components/math-output.jsx +128 -0
  106. package/src/components/multi-button-group.jsx +137 -0
  107. package/src/components/new-tooltip/README.md +110 -0
  108. package/src/components/new-tooltip/__stories__/flexible-position.stories.jsx +437 -0
  109. package/src/components/new-tooltip/__stories__/new-tooltip.stories.jsx +665 -0
  110. package/src/components/new-tooltip/__stories__/tooltip-arrow.stories.jsx +70 -0
  111. package/src/components/new-tooltip/__stories__/tooltip-bubble.stories.jsx +98 -0
  112. package/src/components/new-tooltip/__tests__/style-constants_test.js +8 -0
  113. package/src/components/new-tooltip/__tests__/util_test.js +47 -0
  114. package/src/components/new-tooltip/flexible-position.jsx +182 -0
  115. package/src/components/new-tooltip/new-tooltip.jsx +399 -0
  116. package/src/components/new-tooltip/style-constants.js +13 -0
  117. package/src/components/new-tooltip/tooltip-arrow.jsx +184 -0
  118. package/src/components/new-tooltip/tooltip-bubble.jsx +223 -0
  119. package/src/components/new-tooltip/tooltip-portal.jsx +101 -0
  120. package/src/components/new-tooltip/tooltip-positioner.jsx +529 -0
  121. package/src/components/new-tooltip/types.js +183 -0
  122. package/src/components/new-tooltip/util.js +27 -0
  123. package/src/components/number-input.jsx +253 -0
  124. package/src/components/possible-answers.jsx +36 -0
  125. package/src/components/prop-check-box.jsx +80 -0
  126. package/src/components/range-input.jsx +61 -0
  127. package/src/components/simple-keypad-input.jsx +91 -0
  128. package/src/components/sortable.jsx +873 -0
  129. package/src/components/stub-tag-editor.jsx +54 -0
  130. package/src/components/svg-image.jsx +762 -0
  131. package/src/components/tex-buttons.jsx +322 -0
  132. package/src/components/tex.jsx +70 -0
  133. package/src/components/text-input.jsx +82 -0
  134. package/src/components/text-list-editor.jsx +157 -0
  135. package/src/components/tooltip.jsx +395 -0
  136. package/src/components/visibility-observer/__stories__/visibility-observer.stories.jsx +140 -0
  137. package/src/components/visibility-observer/get-scroll-parent.js +45 -0
  138. package/src/components/visibility-observer/visibility-observer.js +109 -0
  139. package/src/components/visibility-observer/visibility-observer.jsx +123 -0
  140. package/src/components/zoomable-tex.jsx +70 -0
  141. package/src/components/zoomable.jsx +304 -0
  142. package/src/components.js +17 -0
  143. package/src/dependencies.js +22 -0
  144. package/src/error-boundary.jsx +48 -0
  145. package/src/extra-widgets.js +75 -0
  146. package/src/gorgon/README +40 -0
  147. package/src/gorgon/__tests__/matcher_test.js +497 -0
  148. package/src/gorgon/__tests__/rule_test.js +101 -0
  149. package/src/gorgon/__tests__/rules_test.js +487 -0
  150. package/src/gorgon/__tests__/selector-parser_test.js +52 -0
  151. package/src/gorgon/__tests__/tree-transformer_test.js +446 -0
  152. package/src/gorgon/gorgon.js +290 -0
  153. package/src/gorgon/proptypes.js +29 -0
  154. package/src/gorgon/rule.js +413 -0
  155. package/src/gorgon/rules/absolute-url.js +24 -0
  156. package/src/gorgon/rules/all-rules.js +72 -0
  157. package/src/gorgon/rules/blockquoted-math.js +10 -0
  158. package/src/gorgon/rules/blockquoted-widget.js +10 -0
  159. package/src/gorgon/rules/double-spacing-after-terminal.js +12 -0
  160. package/src/gorgon/rules/extra-content-spacing.js +12 -0
  161. package/src/gorgon/rules/heading-level-1.js +14 -0
  162. package/src/gorgon/rules/heading-level-skip.js +20 -0
  163. package/src/gorgon/rules/heading-sentence-case.js +11 -0
  164. package/src/gorgon/rules/heading-title-case.js +63 -0
  165. package/src/gorgon/rules/image-alt-text.js +21 -0
  166. package/src/gorgon/rules/image-in-table.js +10 -0
  167. package/src/gorgon/rules/image-spaces-around-urls.js +35 -0
  168. package/src/gorgon/rules/image-widget.js +50 -0
  169. package/src/gorgon/rules/link-click-here.js +11 -0
  170. package/src/gorgon/rules/lint-utils.js +48 -0
  171. package/src/gorgon/rules/long-paragraph.js +14 -0
  172. package/src/gorgon/rules/math-adjacent.js +10 -0
  173. package/src/gorgon/rules/math-align-extra-break.js +11 -0
  174. package/src/gorgon/rules/math-align-linebreaks.js +43 -0
  175. package/src/gorgon/rules/math-empty.js +10 -0
  176. package/src/gorgon/rules/math-font-size.js +12 -0
  177. package/src/gorgon/rules/math-frac.js +10 -0
  178. package/src/gorgon/rules/math-nested.js +11 -0
  179. package/src/gorgon/rules/math-starts-with-space.js +12 -0
  180. package/src/gorgon/rules/math-text-empty.js +10 -0
  181. package/src/gorgon/rules/math-without-dollars.js +14 -0
  182. package/src/gorgon/rules/nested-lists.js +11 -0
  183. package/src/gorgon/rules/profanity.js +10 -0
  184. package/src/gorgon/rules/table-missing-cells.js +20 -0
  185. package/src/gorgon/rules/unbalanced-code-delimiters.js +14 -0
  186. package/src/gorgon/rules/unescaped-dollar.js +10 -0
  187. package/src/gorgon/rules/widget-in-table.js +10 -0
  188. package/src/gorgon/selector.js +506 -0
  189. package/src/gorgon/tree-transformer.js +588 -0
  190. package/src/hint-renderer.jsx +159 -0
  191. package/src/hints-renderer.jsx +359 -0
  192. package/src/icon-paths.js +120 -0
  193. package/src/index.js +149 -2
  194. package/src/init.js +49 -0
  195. package/src/interaction-tracker.js +60 -0
  196. package/src/interactive2/__tests__/movable-mock.js +48 -0
  197. package/src/interactive2/__tests__/movable-point_test.js +146 -0
  198. package/src/interactive2/interactive-util.js +152 -0
  199. package/src/interactive2/movable-helper-methods.js +160 -0
  200. package/src/interactive2/movable-line-options.js +392 -0
  201. package/src/interactive2/movable-line.js +322 -0
  202. package/src/interactive2/movable-point-options.js +190 -0
  203. package/src/interactive2/movable-point.jsx +603 -0
  204. package/src/interactive2/movable-polygon-options.js +351 -0
  205. package/src/interactive2/movable-polygon.js +368 -0
  206. package/src/interactive2/movable.js +273 -0
  207. package/src/interactive2/objective_.js +79 -0
  208. package/src/interactive2/types.js +3 -0
  209. package/src/interactive2/wrapped-defaults.js +86 -0
  210. package/src/interactive2/wrapped-ellipse.js +87 -0
  211. package/src/interactive2/wrapped-line.js +109 -0
  212. package/src/interactive2/wrapped-path.js +47 -0
  213. package/src/interactive2.js +91 -0
  214. package/src/item-renderer.jsx +518 -0
  215. package/src/item-version.js +12 -0
  216. package/src/jipt-paragraphs.js +44 -0
  217. package/src/jquery.mobile.vmouse.js +545 -0
  218. package/src/keypad-context.js +33 -0
  219. package/src/loading-context.js +20 -0
  220. package/src/logging/log.js +107 -0
  221. package/src/logging/log_test.js +41 -0
  222. package/src/mixins/changeable.jsx +115 -0
  223. package/src/mixins/editor-jsonify.jsx +13 -0
  224. package/src/mixins/provide-keypad.jsx +129 -0
  225. package/src/mixins/widget-jsonify-deprecated.jsx +23 -0
  226. package/src/mixins/widget-prop-blacklist.js +36 -0
  227. package/src/multi-items/__stories__/multi-renderer.stories.js +88 -0
  228. package/src/multi-items/__testdata__/multi-renderer_testdata.js +174 -0
  229. package/src/multi-items/__tests__/__snapshots__/multi-renderer_test.js.snap +994 -0
  230. package/src/multi-items/__tests__/items_test.js +245 -0
  231. package/src/multi-items/__tests__/multi-renderer_test.js +903 -0
  232. package/src/multi-items/__tests__/prop-type-builders_test.js +134 -0
  233. package/src/multi-items/__tests__/shapes_test.js +44 -0
  234. package/src/multi-items/__tests__/trees_test.js +316 -0
  235. package/src/multi-items/item-types.js +55 -0
  236. package/src/multi-items/items.js +176 -0
  237. package/src/multi-items/multi-renderer.jsx +543 -0
  238. package/src/multi-items/prop-type-builders.js +105 -0
  239. package/src/multi-items/shape-types.js +47 -0
  240. package/src/multi-items/shapes.js +53 -0
  241. package/src/multi-items/tree-types.js +42 -0
  242. package/src/multi-items/trees.js +345 -0
  243. package/src/multi-items.js +76 -0
  244. package/src/not-gorgon.js +129 -0
  245. package/src/perseus-api.jsx +270 -0
  246. package/src/perseus-env.js +26 -0
  247. package/src/perseus-error.js +19 -0
  248. package/src/perseus-markdown.jsx +433 -0
  249. package/src/perseus-types.js +1597 -0
  250. package/src/pure-markdown.js +347 -0
  251. package/src/question-paragraph.jsx +30 -0
  252. package/src/renderability.jsx +108 -0
  253. package/src/renderer.jsx +1932 -0
  254. package/src/server-item-renderer.jsx +467 -0
  255. package/src/sigfigs.jsx +492 -0
  256. package/src/styles/articles.less +748 -0
  257. package/src/styles/constants.js +119 -0
  258. package/src/styles/global-constants.js +350 -0
  259. package/src/styles/global-styles.js +307 -0
  260. package/src/styles/khan-exercise.css +1304 -0
  261. package/src/styles/media-queries.js +48 -0
  262. package/src/styles/perseus-renderer.less +1007 -0
  263. package/src/styles/shared.js +132 -0
  264. package/src/styles/util.less +47 -0
  265. package/src/styles/variables.boostrap.less +301 -0
  266. package/src/styles/variables.less +68 -0
  267. package/src/styles/variables.shared.less +356 -0
  268. package/src/styles/widgets/categorizer.less +39 -0
  269. package/src/styles/widgets/definition.less +86 -0
  270. package/src/styles/widgets/dropdown.less +3 -0
  271. package/src/styles/widgets/expression.less +147 -0
  272. package/src/styles/widgets/graded-group.less +36 -0
  273. package/src/styles/widgets/grapher.less +11 -0
  274. package/src/styles/widgets/group.less +19 -0
  275. package/src/styles/widgets/image.less +29 -0
  276. package/src/styles/widgets/interactive-graph.less +61 -0
  277. package/src/styles/widgets/label-image.less +41 -0
  278. package/src/styles/widgets/matcher.less +8 -0
  279. package/src/styles/widgets/matrix.less +120 -0
  280. package/src/styles/widgets/measurer.less +20 -0
  281. package/src/styles/widgets/orderer.less +97 -0
  282. package/src/styles/widgets/passage.less +151 -0
  283. package/src/styles/widgets/plotter.less +33 -0
  284. package/src/styles/widgets/radio.less +52 -0
  285. package/src/styles/widgets/reaction-diagram.less +35 -0
  286. package/src/styles/widgets/sequence.less +5 -0
  287. package/src/styles/widgets/sortable.less +127 -0
  288. package/src/styles/widgets/table.less +56 -0
  289. package/src/styles/widgets/transformer.less +28 -0
  290. package/src/styles/widgets/unit.less +14 -0
  291. package/src/tex-wrangler.js +176 -0
  292. package/src/traversal.jsx +141 -0
  293. package/src/types.js +538 -0
  294. package/src/util/a11y.js +24 -0
  295. package/src/util/answer-types.js +862 -0
  296. package/src/util/answer-types_test.js +115 -0
  297. package/src/util/colors.js +94 -0
  298. package/src/util/fix-passage-refs.jsx +122 -0
  299. package/src/util/graph-utils.js +16 -0
  300. package/src/util/graphie.js +1586 -0
  301. package/src/util/interactive.js +4078 -0
  302. package/src/util/katex-preprocess.js +16 -0
  303. package/src/util/math.js +296 -0
  304. package/src/util/mobile-native-utils.js +14 -0
  305. package/src/util/mobile-native-utils_test.js +24 -0
  306. package/src/util/register-all-widgets-for-testing.js +12 -0
  307. package/src/util/scroll-utils.js +162 -0
  308. package/src/util/sizing-utils.js +46 -0
  309. package/src/util/tex.js +203 -0
  310. package/src/util/url-utils.js +36 -0
  311. package/src/util.js +990 -0
  312. package/src/version.js +11 -0
  313. package/src/widget-container.jsx +174 -0
  314. package/src/widgets/__stories__/categorizer.stories.jsx +15 -0
  315. package/src/widgets/__stories__/cs-program.stories.jsx +15 -0
  316. package/src/widgets/__stories__/definition.stories.jsx +38 -0
  317. package/src/widgets/__stories__/dropdown.stories.jsx +15 -0
  318. package/src/widgets/__stories__/explanation.stories.jsx +19 -0
  319. package/src/widgets/__stories__/expression.stories.jsx +26 -0
  320. package/src/widgets/__stories__/graded-group-set.stories.jsx +32 -0
  321. package/src/widgets/__stories__/graded-group.stories.jsx +32 -0
  322. package/src/widgets/__stories__/grapher.stories.jsx +47 -0
  323. package/src/widgets/__stories__/group.stories.jsx +15 -0
  324. package/src/widgets/__stories__/iframe.stories.jsx +15 -0
  325. package/src/widgets/__stories__/image.stories.jsx +62 -0
  326. package/src/widgets/__stories__/input-number.stories.jsx +90 -0
  327. package/src/widgets/__stories__/interaction.stories.jsx +15 -0
  328. package/src/widgets/__stories__/interactive-graph.stories.jsx +61 -0
  329. package/src/widgets/__stories__/matcher.stories.jsx +15 -0
  330. package/src/widgets/__stories__/matrix.stories.jsx +15 -0
  331. package/src/widgets/__stories__/number-line.stories.jsx +15 -0
  332. package/src/widgets/__stories__/numeric-input.stories.jsx +19 -0
  333. package/src/widgets/__stories__/orderer.stories.jsx +15 -0
  334. package/src/widgets/__stories__/passage-ref.stories.jsx +19 -0
  335. package/src/widgets/__stories__/passage.stories.jsx +19 -0
  336. package/src/widgets/__stories__/radio.stories.jsx +82 -0
  337. package/src/widgets/__stories__/sorter.stories.jsx +15 -0
  338. package/src/widgets/__stories__/transformer.stories.jsx +15 -0
  339. package/src/widgets/__stories__/unit.stories.jsx +45 -0
  340. package/src/widgets/__stories__/video-transcript-link.stories.jsx +24 -0
  341. package/src/widgets/__stories__/video.stories.jsx +15 -0
  342. package/src/widgets/__testdata__/categorizer_testdata.js +50 -0
  343. package/src/widgets/__testdata__/cs-program_testdata.js +28 -0
  344. package/src/widgets/__testdata__/dropdown_testdata.js +34 -0
  345. package/src/widgets/__testdata__/explanation_testdata.js +56 -0
  346. package/src/widgets/__testdata__/expression_testdata.js +95 -0
  347. package/src/widgets/__testdata__/graded-group-set_testdata.js +358 -0
  348. package/src/widgets/__testdata__/graded-group_testdata.js +79 -0
  349. package/src/widgets/__testdata__/grapher_testdata.js +376 -0
  350. package/src/widgets/__testdata__/group_testdata.js +156 -0
  351. package/src/widgets/__testdata__/iframe_testdata.js +36 -0
  352. package/src/widgets/__testdata__/image_testdata.js +38 -0
  353. package/src/widgets/__testdata__/input-number_testdata.js +73 -0
  354. package/src/widgets/__testdata__/interaction_testdata.js +264 -0
  355. package/src/widgets/__testdata__/interactive-graph_testdata.js +646 -0
  356. package/src/widgets/__testdata__/matcher_testdata.js +34 -0
  357. package/src/widgets/__testdata__/matrix_testdata.js +29 -0
  358. package/src/widgets/__testdata__/number-line_testdata.js +31 -0
  359. package/src/widgets/__testdata__/numeric-input_testdata.js +266 -0
  360. package/src/widgets/__testdata__/orderer_testdata.js +58 -0
  361. package/src/widgets/__testdata__/passage-ref_testdata.js +41 -0
  362. package/src/widgets/__testdata__/passage_testdata.js +71 -0
  363. package/src/widgets/__testdata__/radio_testdata.js +210 -0
  364. package/src/widgets/__testdata__/sorter_testdata.js +20 -0
  365. package/src/widgets/__testdata__/transformer_testdata.js +109 -0
  366. package/src/widgets/__testdata__/video_testdata.js +22 -0
  367. package/src/widgets/__tests__/__snapshots__/categorizer_test.jsx.snap +928 -0
  368. package/src/widgets/__tests__/__snapshots__/cs-program_test.jsx.snap +75 -0
  369. package/src/widgets/__tests__/__snapshots__/definition_test.js.snap +99 -0
  370. package/src/widgets/__tests__/__snapshots__/dropdown_test.jsx.snap +143 -0
  371. package/src/widgets/__tests__/__snapshots__/explanation_test.js.snap +473 -0
  372. package/src/widgets/__tests__/__snapshots__/expression_test.jsx.snap +38 -0
  373. package/src/widgets/__tests__/__snapshots__/graded-group-set-jipt_test.jsx.snap +754 -0
  374. package/src/widgets/__tests__/__snapshots__/graded-group-set_test.jsx.snap +310 -0
  375. package/src/widgets/__tests__/__snapshots__/graded-group_test.jsx.snap +863 -0
  376. package/src/widgets/__tests__/__snapshots__/grapher_test.jsx.snap +2880 -0
  377. package/src/widgets/__tests__/__snapshots__/group_test.jsx.snap +1154 -0
  378. package/src/widgets/__tests__/__snapshots__/iframe_test.jsx.snap +69 -0
  379. package/src/widgets/__tests__/__snapshots__/image_test.jsx.snap +388 -0
  380. package/src/widgets/__tests__/__snapshots__/input-number_test.jsx.snap +978 -0
  381. package/src/widgets/__tests__/__snapshots__/interaction_test.jsx.snap +311 -0
  382. package/src/widgets/__tests__/__snapshots__/interactive-graph_test.jsx.snap +2915 -0
  383. package/src/widgets/__tests__/__snapshots__/matcher_test.jsx.snap +1039 -0
  384. package/src/widgets/__tests__/__snapshots__/matrix_test.jsx.snap +450 -0
  385. package/src/widgets/__tests__/__snapshots__/number-line_test.jsx.snap +888 -0
  386. package/src/widgets/__tests__/__snapshots__/numeric-input_test.jsx.snap +930 -0
  387. package/src/widgets/__tests__/__snapshots__/orderer_test.jsx.snap +275 -0
  388. package/src/widgets/__tests__/__snapshots__/passage-ref_test.jsx.snap +446 -0
  389. package/src/widgets/__tests__/__snapshots__/passage_test.jsx.snap +1988 -0
  390. package/src/widgets/__tests__/__snapshots__/radio_test.jsx.snap +7107 -0
  391. package/src/widgets/__tests__/__snapshots__/video_test.jsx.snap +163 -0
  392. package/src/widgets/__tests__/categorizer_test.jsx +205 -0
  393. package/src/widgets/__tests__/cs-program_test.jsx +45 -0
  394. package/src/widgets/__tests__/definition_test.js +152 -0
  395. package/src/widgets/__tests__/dropdown_test.jsx +106 -0
  396. package/src/widgets/__tests__/explanation_test.js +199 -0
  397. package/src/widgets/__tests__/expression_test.jsx +439 -0
  398. package/src/widgets/__tests__/graded-group-set-jipt_test.jsx +33 -0
  399. package/src/widgets/__tests__/graded-group-set_test.jsx +270 -0
  400. package/src/widgets/__tests__/graded-group_test.jsx +233 -0
  401. package/src/widgets/__tests__/grapher.cypress.jsx +486 -0
  402. package/src/widgets/__tests__/grapher_test.jsx +35 -0
  403. package/src/widgets/__tests__/group_test.jsx +512 -0
  404. package/src/widgets/__tests__/iframe_test.jsx +47 -0
  405. package/src/widgets/__tests__/image_test.jsx +65 -0
  406. package/src/widgets/__tests__/input-number_test.jsx +360 -0
  407. package/src/widgets/__tests__/interaction_test.jsx +33 -0
  408. package/src/widgets/__tests__/interactive-graph.cypress.jsx +697 -0
  409. package/src/widgets/__tests__/interactive-graph_test.jsx +105 -0
  410. package/src/widgets/__tests__/matcher_test.jsx +157 -0
  411. package/src/widgets/__tests__/matrix_test.jsx +84 -0
  412. package/src/widgets/__tests__/number-line_test.jsx +81 -0
  413. package/src/widgets/__tests__/numeric-input_test.jsx +574 -0
  414. package/src/widgets/__tests__/orderer_test.jsx +75 -0
  415. package/src/widgets/__tests__/passage-ref_test.jsx +166 -0
  416. package/src/widgets/__tests__/passage_test.jsx +133 -0
  417. package/src/widgets/__tests__/radio/base-radio_test.jsx +82 -0
  418. package/src/widgets/__tests__/radio_test.jsx +651 -0
  419. package/src/widgets/__tests__/renderQuestion.jsx +66 -0
  420. package/src/widgets/__tests__/unit_test.jsx +144 -0
  421. package/src/widgets/__tests__/video_test.jsx +55 -0
  422. package/src/widgets/categorizer.jsx +338 -0
  423. package/src/widgets/cs-program.jsx +227 -0
  424. package/src/widgets/definition.jsx +141 -0
  425. package/src/widgets/dropdown.jsx +143 -0
  426. package/src/widgets/explanation.jsx +315 -0
  427. package/src/widgets/expression.jsx +652 -0
  428. package/src/widgets/graded-group-answer-bar.jsx +152 -0
  429. package/src/widgets/graded-group-set.jsx +285 -0
  430. package/src/widgets/graded-group.jsx +448 -0
  431. package/src/widgets/grapher/util.jsx +806 -0
  432. package/src/widgets/grapher.jsx +663 -0
  433. package/src/widgets/group.jsx +213 -0
  434. package/src/widgets/iframe.jsx +198 -0
  435. package/src/widgets/image.jsx +310 -0
  436. package/src/widgets/input-number.jsx +411 -0
  437. package/src/widgets/interaction/arrow-picker.jsx +39 -0
  438. package/src/widgets/interaction/color-picker.jsx +69 -0
  439. package/src/widgets/interaction/dash-picker.jsx +46 -0
  440. package/src/widgets/interaction/element-container.jsx +97 -0
  441. package/src/widgets/interaction.jsx +742 -0
  442. package/src/widgets/interactive-graph.jsx +2820 -0
  443. package/src/widgets/label-image/__stories__/answer-choices.stories.jsx +93 -0
  444. package/src/widgets/label-image/__stories__/marker.stories.jsx +172 -0
  445. package/src/widgets/label-image/answer-choices.jsx +311 -0
  446. package/src/widgets/label-image/marker.jsx +365 -0
  447. package/src/widgets/label-image/types.js +33 -0
  448. package/src/widgets/label-image.jsx +841 -0
  449. package/src/widgets/label-image_test.js +840 -0
  450. package/src/widgets/lights-puzzle.jsx +356 -0
  451. package/src/widgets/matcher.jsx +271 -0
  452. package/src/widgets/matrix.jsx +616 -0
  453. package/src/widgets/measurer.jsx +215 -0
  454. package/src/widgets/molecule/__tests__/layout_test.jsx +159 -0
  455. package/src/widgets/molecule/__tests__/parser_test.jsx +142 -0
  456. package/src/widgets/molecule/molecule-drawing.jsx +175 -0
  457. package/src/widgets/molecule/molecule-layout.jsx +367 -0
  458. package/src/widgets/molecule/smiles-parser.jsx +300 -0
  459. package/src/widgets/molecule.jsx +172 -0
  460. package/src/widgets/number-line.jsx +858 -0
  461. package/src/widgets/numeric-input.jsx +622 -0
  462. package/src/widgets/orderer.jsx +753 -0
  463. package/src/widgets/passage/__tests__/passage-markdown_test.jsx +382 -0
  464. package/src/widgets/passage/get-line-height-for-node.js +10 -0
  465. package/src/widgets/passage/passage-markdown.jsx +416 -0
  466. package/src/widgets/passage-ref-target.jsx +70 -0
  467. package/src/widgets/passage-ref.jsx +198 -0
  468. package/src/widgets/passage.jsx +601 -0
  469. package/src/widgets/plotter.jsx +1198 -0
  470. package/src/widgets/radio/__stories__/base-radio.stories.jsx +40 -0
  471. package/src/widgets/radio/__stories__/choice-icon.stories.jsx +157 -0
  472. package/src/widgets/radio/__stories__/choice-none-above.stories.jsx +26 -0
  473. package/src/widgets/radio/__stories__/cross-out-button.stories.jsx +64 -0
  474. package/src/widgets/radio/__stories__/cross-out-menu.stories.jsx +59 -0
  475. package/src/widgets/radio/__stories__/cross-out-tooltip.stories.jsx +59 -0
  476. package/src/widgets/radio/__stories__/focus-ring.stories.jsx +38 -0
  477. package/src/widgets/radio/__stories__/option-status.stories.jsx +118 -0
  478. package/src/widgets/radio/__stories__/toggleable-radio-button.stories.jsx +28 -0
  479. package/src/widgets/radio/base-radio.jsx +642 -0
  480. package/src/widgets/radio/choice-icon.jsx +468 -0
  481. package/src/widgets/radio/choice-none-above.jsx +54 -0
  482. package/src/widgets/radio/choice.jsx +692 -0
  483. package/src/widgets/radio/choice.jsx.fixture.js +64 -0
  484. package/src/widgets/radio/cross-out-button.jsx +136 -0
  485. package/src/widgets/radio/cross-out-menu-wrapper.jsx +492 -0
  486. package/src/widgets/radio/cross-out-tooltip.jsx +129 -0
  487. package/src/widgets/radio/focus-ring.jsx +51 -0
  488. package/src/widgets/radio/option-status.jsx +89 -0
  489. package/src/widgets/radio/toggleable-radio-button.jsx +133 -0
  490. package/src/widgets/radio/util.js +32 -0
  491. package/src/widgets/radio/util_test.js +19 -0
  492. package/src/widgets/radio/widget.jsx +470 -0
  493. package/src/widgets/radio.jsx +156 -0
  494. package/src/widgets/reaction-diagram.jsx +137 -0
  495. package/src/widgets/sequence.jsx +140 -0
  496. package/src/widgets/simulator.jsx +808 -0
  497. package/src/widgets/sorter.jsx +146 -0
  498. package/src/widgets/table.jsx +394 -0
  499. package/src/widgets/transformer.jsx +2876 -0
  500. package/src/widgets/unit.jsx +372 -0
  501. package/src/widgets/video-transcript-link.jsx +84 -0
  502. package/src/widgets/video-transcript-link_test.js +211 -0
  503. package/src/widgets/video.jsx +126 -0
  504. package/src/widgets.js +431 -0
  505. package/src/zoom.js +539 -0
  506. package/README.md +0 -3
  507. package/src/__tests__/index.test.js +0 -14
package/src/index.js CHANGED
@@ -1,4 +1,151 @@
1
1
  // @flow
2
- import * as i18n from "@khanacademy/wonder-blocks-i18n";
2
+ /**
3
+ * Main entry point
4
+ */
3
5
 
4
- export const foo = (): string => i18n._("foo");
6
+ import version from "./version.js";
7
+
8
+ export {default as init} from "./init.js";
9
+
10
+ export {ApiOptions, ClassNames} from "./perseus-api.jsx";
11
+
12
+ export const apiVersion = version.apiVersion;
13
+ export const itemDataVersion = version.itemDataVersion;
14
+ export {default as itemVersion} from "./item-version.js";
15
+
16
+ /**
17
+ * Renderers
18
+ */
19
+ export {default as ArticleRenderer} from "./article-renderer.jsx";
20
+ export {default as ItemRenderer} from "./item-renderer.jsx";
21
+ export {default as ServerItemRenderer} from "./server-item-renderer.jsx";
22
+ export {default as HintsRenderer} from "./hints-renderer.jsx";
23
+ export {default as HintRenderer} from "./hint-renderer.jsx";
24
+ export {default as Renderer} from "./renderer.jsx";
25
+
26
+ /**
27
+ * Widgets
28
+ */
29
+ export * as Widgets from "./widgets.js";
30
+ export {default as widgets} from "./all-widgets.js";
31
+ export {Expression} from "./widgets/expression.jsx";
32
+ export {default as InputNumber} from "./widgets/input-number.jsx";
33
+ export {default as NumericInput} from "./widgets/numeric-input.jsx";
34
+ export {default as Radio} from "./widgets/radio.jsx";
35
+ export {default as BaseRadio} from "./widgets/radio/base-radio.jsx";
36
+ export {default as Categorizer} from "./widgets/categorizer.jsx";
37
+ export {default as InteractiveGraphWidget} from "./widgets/interactive-graph.jsx";
38
+ export {default as TransformerWidget} from "./widgets/transformer.jsx";
39
+ export {default as MatrixWidget} from "./widgets/matrix.jsx";
40
+ export {default as TableWidget} from "./widgets/table.jsx";
41
+ export {default as PlotterWidget} from "./widgets/plotter.jsx";
42
+ export {default as GrapherWidget} from "./widgets/grapher.jsx";
43
+
44
+ export {default as ArrowPicker} from "./widgets/interaction/arrow-picker.jsx";
45
+ export {default as ColorPicker} from "./widgets/interaction/color-picker.jsx";
46
+ export {default as DashPicker} from "./widgets/interaction/dash-picker.jsx";
47
+ export {default as ElementContainer} from "./widgets/interaction/element-container.jsx";
48
+ export * as GrapherUtil from "./widgets/grapher/util.jsx";
49
+
50
+ /**
51
+ * Misc
52
+ */
53
+ export * as components from "./components.js";
54
+ export * as constants from "./components/constants.js";
55
+ // TODO(FEI-4504): Replace globalStyles with wonder-blocks where possible
56
+ export * as globalStyles from "./styles/global-styles.js";
57
+ // TODO(FEI-4504): Replace globalStyles with wonder-blocks where possible
58
+ export * as globalConstants from "./styles/global-constants.js";
59
+ export * as icons from "./icon-paths.js";
60
+ export * as Dependencies from "./dependencies.js";
61
+ export {Errors, Log} from "./logging/log.js";
62
+ export {PerseusError} from "./perseus-error.js";
63
+ export {default as JiptParagraphs} from "./jipt-paragraphs.js";
64
+ export {default as KeypadContext} from "./keypad-context.js";
65
+ export {default as KhanMath} from "./util/math.js";
66
+ export {default as LoadingContext} from "./loading-context.js";
67
+ export {default as mediaQueries} from "./styles/media-queries.js";
68
+ export {default as PerseusMarkdown} from "./perseus-markdown.jsx";
69
+ export {traverse} from "./traversal.jsx";
70
+ export {isItemRenderableByVersion} from "./renderability.jsx";
71
+ export {violatingWidgets} from "./a11y.js";
72
+ export {interactiveSizes} from "./styles/constants.js";
73
+ export {displaySigFigs} from "./sigfigs.jsx";
74
+
75
+ /**
76
+ * Util
77
+ */
78
+ export {default as Util} from "./util.js";
79
+ export {default as KhanColors} from "./util/colors.js";
80
+ export {default as preprocessTex} from "./util/katex-preprocess.js";
81
+ export {registerAllWidgetsForTesting} from "./util/register-all-widgets-for-testing.js";
82
+ export * as SizingUtils from "./util/sizing-utils.js";
83
+
84
+ /**
85
+ * Mixins
86
+ */
87
+ export * as Changeable from "./mixins/changeable.jsx";
88
+ export {default as EditorJsonify} from "./mixins/editor-jsonify.jsx";
89
+ export {default as WidgetJsonifyDeprecated} from "./mixins/widget-jsonify-deprecated.jsx";
90
+ export {default as WIDGET_PROP_BLACKLIST} from "./mixins/widget-prop-blacklist.js";
91
+
92
+ /**
93
+ * Types
94
+ */
95
+ export type {PerseusOptions} from "./init.js";
96
+ export type {ILogger, LogErrorOptions, ErrorKind} from "./logging/log.js";
97
+ export type {ServerItemRenderer as ServerItemRendererComponent} from "./server-item-renderer.jsx";
98
+ export type {
99
+ Alignment,
100
+ APIOptions,
101
+ APIOptionsWithDefaults,
102
+ ChangeHandler,
103
+ DeviceType,
104
+ DomInsertCheckFn,
105
+ EditorMode,
106
+ Hint,
107
+ ImageDict,
108
+ ImageUploader,
109
+ JiptLabelStore,
110
+ JiptRenderer,
111
+ KEScore,
112
+ LinterContextProps,
113
+ PerseusDependencies,
114
+ PerseusScore,
115
+ RendererInterface,
116
+ Version,
117
+ WidgetDict,
118
+ WidgetExports,
119
+ WidgetInfo,
120
+ } from "./types.js";
121
+ export type {InputNumberWidget, PerseusRenderer} from "./perseus-types.js";
122
+ export type {Format} from "./util/math.js";
123
+ export type {Coord} from "./interactive2/types.js";
124
+ export type {MarkerType} from "./widgets/label-image/types.js";
125
+
126
+ /**
127
+ * Multi-items
128
+ */
129
+ export {default as MultiItems} from "./multi-items.js";
130
+ export {buildEmptyItemTreeForShape, itemToTree} from "./multi-items/items.js";
131
+ export {default as shapes} from "./multi-items/shapes.js";
132
+ export {buildMapper} from "./multi-items/trees.js";
133
+
134
+ export type {
135
+ ContentNode,
136
+ HintNode,
137
+ Item,
138
+ ItemTree,
139
+ ItemObjectNode,
140
+ ItemArrayNode,
141
+ TagsNode,
142
+ } from "./multi-items/item-types.js";
143
+ export type {
144
+ Shape,
145
+ ArrayShape,
146
+ ObjectShape,
147
+ ContentShape,
148
+ HintShape,
149
+ TagsShape,
150
+ } from "./multi-items/shape-types.js";
151
+ export type {Path} from "./multi-items/trees.js";
package/src/init.js ADDED
@@ -0,0 +1,49 @@
1
+ // @flow
2
+ import basicWidgets from "./basic-widgets.js";
3
+ import extraWidgets from "./extra-widgets.js";
4
+ import * as Widgets from "./widgets.js";
5
+
6
+ declare var MathJax: any;
7
+
8
+ export type PerseusOptions = {|
9
+ skipMathJax: boolean,
10
+ |};
11
+
12
+ /**
13
+ * This should be called by all clients, specifying whether extra widgets are
14
+ * needed via `loadExtraWidgets`. It is idempotent, so it's not a problem to
15
+ * call it multiple times.
16
+ *
17
+ * skipMathJax:
18
+ * If false/undefined, MathJax will be configured, and the
19
+ * promise will wait for MathJax to load (if it hasn't already).
20
+ */
21
+ const init = function (options: PerseusOptions): Promise<void> {
22
+ Widgets.registerWidgets(basicWidgets);
23
+ Widgets.registerWidgets(extraWidgets);
24
+
25
+ // Pass skipMathJax: true if MathJax is already loaded and configured.
26
+ const skipMathJax = options.skipMathJax;
27
+
28
+ if (skipMathJax) {
29
+ return Promise.resolve();
30
+ }
31
+
32
+ return new Promise((resolve, reject) => {
33
+ MathJax.Hub.Config({
34
+ messageStyle: "none",
35
+ skipStartupTypeset: "none",
36
+ "HTML-CSS": {
37
+ availableFonts: ["TeX"],
38
+ imageFont: null,
39
+ scale: 100,
40
+ showMathMenu: false,
41
+ },
42
+ });
43
+
44
+ MathJax.Hub.Configured();
45
+ MathJax.Hub.Queue(resolve);
46
+ });
47
+ };
48
+
49
+ export default init;
@@ -0,0 +1,60 @@
1
+ // @flow
2
+
3
+ /**
4
+ * This alternate version of `.track` does nothing as an optimization.
5
+ */
6
+ function _noop() {}
7
+
8
+ /**
9
+ * Wrapper for the trackInteraction apiOption.
10
+ */
11
+ class InteractionTracker {
12
+ _tracked: boolean;
13
+ setting: string;
14
+ track: (extraData?: any) => void;
15
+ // eslint-disable-next-line flowtype/no-weak-types
16
+ trackApi: Function;
17
+ widgetID: string;
18
+ widgetType: string;
19
+
20
+ constructor(
21
+ // eslint-disable-next-line flowtype/no-weak-types
22
+ trackApi: Function, // original apiOptions.trackInteraction
23
+ widgetType: string,
24
+ widgetID: string,
25
+ setting: "" | "all", // "" means track once
26
+ ) {
27
+ if (!trackApi) {
28
+ this.track = _noop;
29
+ } else {
30
+ this._tracked = false;
31
+ this.trackApi = trackApi;
32
+ this.widgetType = widgetType;
33
+ this.widgetID = widgetID;
34
+ this.setting = setting;
35
+ this.track = this._track;
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Function that actually calls the API to mark the interaction. This is
41
+ * private. The public version is just `.track` and is bound to this object
42
+ * for easy use in other context.
43
+ *
44
+ * @param extraData Any extra data to track about the event.
45
+ * @private
46
+ */
47
+ _track: (extraData: mixed) => void = (extraData: mixed) => {
48
+ if (this._tracked && !this.setting) {
49
+ return;
50
+ }
51
+ this._tracked = true;
52
+ this.trackApi({
53
+ type: this.widgetType,
54
+ id: this.widgetID,
55
+ ...extraData,
56
+ });
57
+ };
58
+ }
59
+
60
+ export default InteractionTracker;
@@ -0,0 +1,48 @@
1
+ // @flow
2
+ /**
3
+ * Create a Mocked Movable
4
+ */
5
+
6
+ import _ from "underscore";
7
+
8
+ import Movable from "../movable.js";
9
+
10
+ const createMock = function (): $FlowFixMe {
11
+ // $FlowFixMe[invalid-constructor]
12
+ const movable = new Movable(null, {
13
+ mouseTarget: null,
14
+ });
15
+ // $FlowFixMe[prop-missing]
16
+ movable.modify = function (options) {
17
+ // $FlowFixMe[prop-missing]
18
+ Movable.prototype.modify.call(movable, _.omit(options, "mouseTarget"));
19
+ };
20
+ _.each(
21
+ ["onMoveStart", "onMove", "onMoveEnd", "onClick"],
22
+ function (eventName) {
23
+ movable[eventName] = function (coord, prevCoord) {
24
+ this._fireEvent(this.state[eventName], coord, prevCoord);
25
+ };
26
+ },
27
+ );
28
+ // $FlowFixMe[prop-missing]
29
+ movable.move = function () {
30
+ const args = _.toArray(arguments);
31
+ const startPoint = _.first(args);
32
+ // TODO(jack): Move these into onMoveStart, onMove, and onMoveEnd
33
+ movable.state.isMouseOver = true;
34
+ movable.state.isHovering = true;
35
+ movable.onMoveStart(startPoint, startPoint);
36
+ _.each(_.rest(args), function (point, i) {
37
+ movable.state.isDragging = true;
38
+ movable.onMove(point, args[i]);
39
+ });
40
+ movable.onMoveEnd(_.last(args), startPoint);
41
+ movable.state.dragging = false;
42
+ movable.state.isMouseOver = false;
43
+ movable.state.isHovering = false;
44
+ };
45
+ return movable;
46
+ };
47
+
48
+ export default createMock;
@@ -0,0 +1,146 @@
1
+ // @flow
2
+ // System requires
3
+ import _ from "underscore";
4
+
5
+ // Interactive2 requires
6
+ import MovablePoint from "../movable-point.jsx";
7
+
8
+ import _createMockMovable from "./movable-mock.js";
9
+
10
+ // Create a testable MovablePoint with a mocked out Movable
11
+ const createPoint = function (options) {
12
+ const movable = _createMockMovable();
13
+ // $FlowFixMe[invalid-constructor]
14
+ const point = new MovablePoint(
15
+ null,
16
+ movable,
17
+ _.extend(options, {
18
+ static: true,
19
+ draw: null,
20
+ showHairlines: () => {},
21
+ hideHairlines: () => {},
22
+
23
+ // Mock visibleShape which is only added when a movable point is used
24
+ // with a shape.
25
+ // TODO(kevinb): update MovablePoint to require a visibleShape
26
+ visibleShape: {
27
+ wrapper: {},
28
+ },
29
+ }),
30
+ );
31
+ return {
32
+ movable: movable,
33
+ point: point,
34
+
35
+ /**
36
+ * Convenience function to fill in the no-drawing defaults
37
+ * for a modify call
38
+ */
39
+ modify: function (options) {
40
+ point.modify(
41
+ _.extend(
42
+ {
43
+ static: true,
44
+ draw: null,
45
+ },
46
+ options,
47
+ ),
48
+ );
49
+ },
50
+ };
51
+ };
52
+
53
+ describe("MovablePoint", function () {
54
+ describe("add", function () {
55
+ it("should snap to the grid when a snap is specified", function () {
56
+ const point = createPoint({
57
+ coord: [1.1, 1.1],
58
+ // $FlowFixMe[prop-missing]
59
+ constraints: MovablePoint.constraints.snap([1, 1]),
60
+ }).point;
61
+
62
+ expect(point.coord()).toEqual([1, 1]);
63
+ });
64
+ });
65
+
66
+ describe("modify", function () {
67
+ it("should reset the point's size", function () {
68
+ const defaultPointSize = createPoint({
69
+ coord: [1, 1], // uses the default pointSize
70
+ }).point.pointSize();
71
+
72
+ // verify that 10 was not, in fact, the default, or we should
73
+ // change 10 to something else
74
+ expect(defaultPointSize).not.toEqual(10);
75
+
76
+ const handle = createPoint({
77
+ coord: [0, 0],
78
+ pointSize: 10, // arbitrary size larger than the default
79
+ });
80
+ expect(handle.point.pointSize()).toBe(10);
81
+
82
+ handle.modify({
83
+ coord: [0, 0], // reset to the default pointSize
84
+ });
85
+ expect(handle.point.pointSize()).toBe(defaultPointSize);
86
+ });
87
+
88
+ it("should allow you to change the point's size", function () {
89
+ const handle = createPoint({
90
+ coord: [0, 0],
91
+ pointSize: 5,
92
+ });
93
+ expect(handle.point.pointSize()).toBe(5);
94
+
95
+ handle.modify({
96
+ pointSize: 6,
97
+ });
98
+ expect(handle.point.pointSize()).toBe(6);
99
+ });
100
+ });
101
+
102
+ describe("onMove", function () {
103
+ it("should be called when movable is moved", function () {
104
+ let movedToCoord;
105
+ const handle = createPoint({
106
+ coord: [1, 2],
107
+ onMove: function (newCoord, prevCoord) {
108
+ expect(prevCoord).toEqual([1, 2]);
109
+ movedToCoord = newCoord;
110
+ },
111
+ });
112
+ // move mouse from [2.5, 4] to [3, 4]
113
+ handle.movable.move([2.5, 4], [3, 4]);
114
+ expect(movedToCoord).toEqual([3, 4]);
115
+ expect(handle.point.coord()).toEqual([3, 4]);
116
+ });
117
+ });
118
+
119
+ describe("onClick", function () {
120
+ it("should be called if the point didn't move", function () {
121
+ let clickCoord;
122
+ const handle = createPoint({
123
+ coord: [1, 2],
124
+ onClick: function (coord) {
125
+ clickCoord = coord;
126
+ },
127
+ });
128
+ // move mouse from [1, 2] to [1, 2]
129
+ handle.movable.move([1, 2], [1, 2]);
130
+ expect(clickCoord).toEqual([1, 2]);
131
+ expect(handle.point.coord()).toEqual([1, 2]);
132
+ });
133
+
134
+ it("should not be called if the point did move", function () {
135
+ const handle = createPoint({
136
+ coord: [1, 2],
137
+ onClick: function (coord) {
138
+ expect(false).toBeTruthy();
139
+ },
140
+ });
141
+ // move mouse from [1, 2] to [3, 4]
142
+ handle.movable.move([1, 2], [3, 4]);
143
+ expect(handle.point.coord()).toEqual([3, 4]);
144
+ });
145
+ });
146
+ });
@@ -0,0 +1,152 @@
1
+ // @flow
2
+ /**
3
+ * Utility functions for writing Interactive2 movablethings
4
+ */
5
+
6
+ import _ from "underscore";
7
+
8
+ import {Errors} from "../logging/log.js";
9
+ import {PerseusError} from "../perseus-error.js";
10
+
11
+ import MovableHelperMethods from "./movable-helper-methods.js";
12
+
13
+ /**
14
+ * Compute the correct vendor-prefixed `transform`.
15
+ */
16
+ let prefixedTransform = null;
17
+ function computePrefixedTransform(): ?string {
18
+ // Temporary element for testing prefix validity
19
+ const el = document.createElement("div");
20
+
21
+ const prefixes = [
22
+ "transform",
23
+ "msTransform",
24
+ "MozTransform",
25
+ "WebkitTransform",
26
+ "OTransform",
27
+ ];
28
+ let correctPrefix = null;
29
+ _.each(prefixes, function (prefix) {
30
+ if (typeof el.style[prefix] !== "undefined") {
31
+ correctPrefix = prefix;
32
+ }
33
+ });
34
+
35
+ return correctPrefix;
36
+ }
37
+
38
+ /**
39
+ * Compute whether the browser can use 3d transforms by trying to use the
40
+ * translateZ transformation.
41
+ */
42
+ let canUse3dTransform = null;
43
+ function computeCanUse3dTransform(): boolean {
44
+ const el = document.createElement("div");
45
+
46
+ const prefix = InteractiveUtil.getPrefixedTransform();
47
+
48
+ // Prefix could be null.
49
+ // $FlowFixMe[incompatible-type]
50
+ el.style[prefix] = "translateZ(0px)";
51
+ // $FlowFixMe[incompatible-type]
52
+ return !!el.style[prefix];
53
+ }
54
+
55
+ const InteractiveUtil = {
56
+ assert: function (isTrue: boolean, message?: string) {
57
+ if (!isTrue) {
58
+ throw new PerseusError(
59
+ "Assertion Error" + (message ? ": " + message : ""),
60
+ Errors.Internal,
61
+ );
62
+ }
63
+ },
64
+
65
+ /**
66
+ * Create getters for this.state, based on the default state, `defaults`
67
+ */
68
+ createGettersFor: function (Class: $FlowFixMe, defaults: {...}) {
69
+ _.each(_.keys(defaults), function (key) {
70
+ if (Class.prototype[key] === undefined) {
71
+ Class.prototype[key] = function () {
72
+ return this.state[key];
73
+ };
74
+ }
75
+ });
76
+ },
77
+
78
+ /**
79
+ * Add MovableHelperMethods methods to a MovableThing class
80
+ */
81
+ addMovableHelperMethodsTo: function (Class: $FlowFixMe) {
82
+ _.each(MovableHelperMethods, function (methodFunc, methodName) {
83
+ if (Class.prototype[methodName] === undefined) {
84
+ Class.prototype[methodName] = methodFunc;
85
+ }
86
+ });
87
+ },
88
+
89
+ /**
90
+ * Turn a function or an array of functions into an array of functions
91
+ */
92
+ arrayify: function (
93
+ funcOrArray:
94
+ | ((...args: $ReadOnlyArray<mixed>) => mixed)
95
+ | $ReadOnlyArray<mixed>,
96
+ ): $ReadOnlyArray<mixed> {
97
+ if (funcOrArray == null) {
98
+ return [];
99
+ }
100
+ if (_.isArray(funcOrArray)) {
101
+ return _.filter(_.flatten(funcOrArray), _.identity);
102
+ }
103
+ return [funcOrArray];
104
+ },
105
+
106
+ /**
107
+ * Convert all function-or-array arguments to arrays of functions
108
+ */
109
+ normalizeOptions: function (
110
+ arrayOptionNames: $ReadOnlyArray<string>,
111
+ options: {...},
112
+ ): {...} {
113
+ // TODO(jack): Having to clone here is annoying; this
114
+ // function should really just modify this.state in place
115
+ // (and maybe be a function on MovableHelperMethods to get access
116
+ // to this.state), which would also be nicer because we could
117
+ // normalizeOptions once in this.modify
118
+ const result = _.clone(options);
119
+ _.each(arrayOptionNames, function (eventName) {
120
+ const funcOrArray = options[eventName];
121
+ // Only propagate values which were set; not present values
122
+ // shouldn't be added to options because we'd like them to
123
+ // fall through to defaults
124
+ if (funcOrArray !== undefined) {
125
+ const funcArray = InteractiveUtil.arrayify(funcOrArray);
126
+ result[eventName] = funcArray;
127
+ }
128
+ });
129
+ return result;
130
+ },
131
+
132
+ /**
133
+ * Get the correct vendor-prefixed `transform`.
134
+ */
135
+ getPrefixedTransform: function (): ?string {
136
+ // Cache result to avoid re-computation
137
+ prefixedTransform = prefixedTransform || computePrefixedTransform();
138
+ return prefixedTransform;
139
+ },
140
+
141
+ /**
142
+ * Get whether the browser can use 3d transforms.
143
+ */
144
+ getCanUse3dTransform: function (): boolean {
145
+ if (canUse3dTransform == null) {
146
+ canUse3dTransform = computeCanUse3dTransform();
147
+ }
148
+ return canUse3dTransform;
149
+ },
150
+ };
151
+
152
+ export default InteractiveUtil;