@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.
- package/.babelrc.js +1 -1
- package/CHANGELOG.md +29 -0
- package/dist/es/index.css +4361 -0
- package/dist/es/index.js +7 -1
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +4361 -0
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/strings.js +148 -46
- package/package.json +50 -4
- package/src/README.md +35 -0
- package/src/__stories__/item-renderer.stories.jsx +27 -0
- package/src/__stories__/server-item-renderer.stories.jsx +27 -0
- package/src/__testdata__/item-renderer_testdata.js +161 -0
- package/src/__testdata__/renderer_testdata.js +123 -0
- package/src/__tests__/__snapshots__/item-renderer_test.jsx.snap +233 -0
- package/src/__tests__/__snapshots__/perseus-markdown_test.jsx.snap +516 -0
- package/src/__tests__/__snapshots__/pure-markdown_test.js.snap +113 -0
- package/src/__tests__/__snapshots__/renderer_test.jsx.snap +576 -0
- package/src/__tests__/__snapshots__/server-item-renderer_test.jsx.snap +306 -0
- package/src/__tests__/a11y_test.jsx +304 -0
- package/src/__tests__/item-renderer_test.jsx +892 -0
- package/src/__tests__/mock-asset-loading-widget.jsx +57 -0
- package/src/__tests__/mock-widget.jsx +35 -0
- package/src/__tests__/perseus-markdown_test.jsx +747 -0
- package/src/__tests__/pure-markdown_test.js +552 -0
- package/src/__tests__/renderability_test.jsx +481 -0
- package/src/__tests__/renderer-api_test.jsx +333 -0
- package/src/__tests__/renderer_test.jsx +1792 -0
- package/src/__tests__/server-item-renderer_test.jsx +516 -0
- package/src/__tests__/test-items/image-item.js +25 -0
- package/src/__tests__/test-items/input-number-1-item.js +27 -0
- package/src/__tests__/test-items/input-number-2-item.js +39 -0
- package/src/__tests__/test-items/table-item.js +30 -0
- package/src/__tests__/tex-wrangler_test.js +83 -0
- package/src/__tests__/util_test.js +41 -0
- package/src/a11y.js +46 -0
- package/src/all-widgets.js +9 -0
- package/src/article-renderer.jsx +215 -0
- package/src/asset-context.js +30 -0
- package/src/basic-widgets.js +13 -0
- package/src/components/__stories__/button-group.stories.jsx +61 -0
- package/src/components/__stories__/fixed-to-responsive.stories.jsx +132 -0
- package/src/components/__stories__/graph.stories.jsx +27 -0
- package/src/components/__stories__/graphie.stories.jsx +28 -0
- package/src/components/__stories__/hud.stories.jsx +36 -0
- package/src/components/__stories__/icon.stories.jsx +56 -0
- package/src/components/__stories__/image-loader.stories.jsx +60 -0
- package/src/components/__stories__/info-tip.stories.jsx +33 -0
- package/src/components/__stories__/inline-icon.stories.jsx +39 -0
- package/src/components/__stories__/input-with-examples.stories.jsx +51 -0
- package/src/components/__stories__/lint.stories.jsx +40 -0
- package/src/components/__stories__/math-input.stories.jsx +29 -0
- package/src/components/__stories__/math-output.stories.jsx +24 -0
- package/src/components/__stories__/multi-button-group.stories.jsx +69 -0
- package/src/components/__stories__/number-input.stories.jsx +42 -0
- package/src/components/__stories__/possible-answers.stories.jsx +22 -0
- package/src/components/__stories__/prop-check-box.stories.jsx +62 -0
- package/src/components/__stories__/range-input.stories.jsx +28 -0
- package/src/components/__stories__/simple-keypad-input.stories.jsx +28 -0
- package/src/components/__stories__/sortable.stories.jsx +73 -0
- package/src/components/__stories__/stub-tag-editor.stories.jsx +44 -0
- package/src/components/__stories__/svg-image.stories.jsx +60 -0
- package/src/components/__stories__/tex.stories.jsx +18 -0
- package/src/components/__stories__/text-buttons.stories.jsx +51 -0
- package/src/components/__stories__/text-input.stories.jsx +34 -0
- package/src/components/__stories__/text-list-editor.stories.jsx +33 -0
- package/src/components/__stories__/zoomable-tex.stories.jsx +39 -0
- package/src/components/__stories__/zoomable.stories.jsx +40 -0
- package/src/components/__testdata__/sorter_testdata.js +20 -0
- package/src/components/__tests__/__snapshots__/sortable_test.jsx.snap +79 -0
- package/src/components/__tests__/__snapshots__/sorter_test.jsx.snap +297 -0
- package/src/components/__tests__/number-input_test.jsx +112 -0
- package/src/components/__tests__/sortable_test.jsx +234 -0
- package/src/components/__tests__/sorter_test.jsx +111 -0
- package/src/components/__tests__/zoomable_test.jsx +388 -0
- package/src/components/button-group.jsx +131 -0
- package/src/components/constants.js +15 -0
- package/src/components/fixed-to-responsive.jsx +164 -0
- package/src/components/graph.jsx +415 -0
- package/src/components/graphie-classes.jsx +148 -0
- package/src/components/graphie-movables.jsx +342 -0
- package/src/components/graphie.jsx +353 -0
- package/src/components/highlighting/highlightable-content.jsx +245 -0
- package/src/components/highlighting/highlights.js +208 -0
- package/src/components/highlighting/ranges.js +299 -0
- package/src/components/highlighting/types.js +73 -0
- package/src/components/highlighting/ui/highlight-renderer.jsx +179 -0
- package/src/components/highlighting/ui/highlight-set-renderer.jsx +190 -0
- package/src/components/highlighting/ui/highlight-tooltip.jsx +153 -0
- package/src/components/highlighting/ui/highlighting-ui.jsx +163 -0
- package/src/components/highlighting/ui/selection-tracker.jsx +195 -0
- package/src/components/highlighting/ui/types.js +21 -0
- package/src/components/highlighting/ui/util.js +166 -0
- package/src/components/highlighting/word-indexer.jsx +155 -0
- package/src/components/hud.jsx +179 -0
- package/src/components/icon.jsx +149 -0
- package/src/components/image-loader.jsx +175 -0
- package/src/components/info-tip/info-tip.jsx +146 -0
- package/src/components/info-tip.jsx +38 -0
- package/src/components/inline-icon.jsx +81 -0
- package/src/components/input-with-examples.jsx +231 -0
- package/src/components/lint.jsx +454 -0
- package/src/components/math-input.jsx +282 -0
- package/src/components/math-output.jsx +128 -0
- package/src/components/multi-button-group.jsx +137 -0
- package/src/components/new-tooltip/README.md +110 -0
- package/src/components/new-tooltip/__stories__/flexible-position.stories.jsx +437 -0
- package/src/components/new-tooltip/__stories__/new-tooltip.stories.jsx +665 -0
- package/src/components/new-tooltip/__stories__/tooltip-arrow.stories.jsx +70 -0
- package/src/components/new-tooltip/__stories__/tooltip-bubble.stories.jsx +98 -0
- package/src/components/new-tooltip/__tests__/style-constants_test.js +8 -0
- package/src/components/new-tooltip/__tests__/util_test.js +47 -0
- package/src/components/new-tooltip/flexible-position.jsx +182 -0
- package/src/components/new-tooltip/new-tooltip.jsx +399 -0
- package/src/components/new-tooltip/style-constants.js +13 -0
- package/src/components/new-tooltip/tooltip-arrow.jsx +184 -0
- package/src/components/new-tooltip/tooltip-bubble.jsx +223 -0
- package/src/components/new-tooltip/tooltip-portal.jsx +101 -0
- package/src/components/new-tooltip/tooltip-positioner.jsx +529 -0
- package/src/components/new-tooltip/types.js +183 -0
- package/src/components/new-tooltip/util.js +27 -0
- package/src/components/number-input.jsx +253 -0
- package/src/components/possible-answers.jsx +36 -0
- package/src/components/prop-check-box.jsx +80 -0
- package/src/components/range-input.jsx +61 -0
- package/src/components/simple-keypad-input.jsx +91 -0
- package/src/components/sortable.jsx +873 -0
- package/src/components/stub-tag-editor.jsx +54 -0
- package/src/components/svg-image.jsx +762 -0
- package/src/components/tex-buttons.jsx +322 -0
- package/src/components/tex.jsx +70 -0
- package/src/components/text-input.jsx +82 -0
- package/src/components/text-list-editor.jsx +157 -0
- package/src/components/tooltip.jsx +395 -0
- package/src/components/visibility-observer/__stories__/visibility-observer.stories.jsx +140 -0
- package/src/components/visibility-observer/get-scroll-parent.js +45 -0
- package/src/components/visibility-observer/visibility-observer.js +109 -0
- package/src/components/visibility-observer/visibility-observer.jsx +123 -0
- package/src/components/zoomable-tex.jsx +70 -0
- package/src/components/zoomable.jsx +304 -0
- package/src/components.js +17 -0
- package/src/dependencies.js +22 -0
- package/src/error-boundary.jsx +48 -0
- package/src/extra-widgets.js +75 -0
- package/src/gorgon/README +40 -0
- package/src/gorgon/__tests__/matcher_test.js +497 -0
- package/src/gorgon/__tests__/rule_test.js +101 -0
- package/src/gorgon/__tests__/rules_test.js +487 -0
- package/src/gorgon/__tests__/selector-parser_test.js +52 -0
- package/src/gorgon/__tests__/tree-transformer_test.js +446 -0
- package/src/gorgon/gorgon.js +290 -0
- package/src/gorgon/proptypes.js +29 -0
- package/src/gorgon/rule.js +413 -0
- package/src/gorgon/rules/absolute-url.js +24 -0
- package/src/gorgon/rules/all-rules.js +72 -0
- package/src/gorgon/rules/blockquoted-math.js +10 -0
- package/src/gorgon/rules/blockquoted-widget.js +10 -0
- package/src/gorgon/rules/double-spacing-after-terminal.js +12 -0
- package/src/gorgon/rules/extra-content-spacing.js +12 -0
- package/src/gorgon/rules/heading-level-1.js +14 -0
- package/src/gorgon/rules/heading-level-skip.js +20 -0
- package/src/gorgon/rules/heading-sentence-case.js +11 -0
- package/src/gorgon/rules/heading-title-case.js +63 -0
- package/src/gorgon/rules/image-alt-text.js +21 -0
- package/src/gorgon/rules/image-in-table.js +10 -0
- package/src/gorgon/rules/image-spaces-around-urls.js +35 -0
- package/src/gorgon/rules/image-widget.js +50 -0
- package/src/gorgon/rules/link-click-here.js +11 -0
- package/src/gorgon/rules/lint-utils.js +48 -0
- package/src/gorgon/rules/long-paragraph.js +14 -0
- package/src/gorgon/rules/math-adjacent.js +10 -0
- package/src/gorgon/rules/math-align-extra-break.js +11 -0
- package/src/gorgon/rules/math-align-linebreaks.js +43 -0
- package/src/gorgon/rules/math-empty.js +10 -0
- package/src/gorgon/rules/math-font-size.js +12 -0
- package/src/gorgon/rules/math-frac.js +10 -0
- package/src/gorgon/rules/math-nested.js +11 -0
- package/src/gorgon/rules/math-starts-with-space.js +12 -0
- package/src/gorgon/rules/math-text-empty.js +10 -0
- package/src/gorgon/rules/math-without-dollars.js +14 -0
- package/src/gorgon/rules/nested-lists.js +11 -0
- package/src/gorgon/rules/profanity.js +10 -0
- package/src/gorgon/rules/table-missing-cells.js +20 -0
- package/src/gorgon/rules/unbalanced-code-delimiters.js +14 -0
- package/src/gorgon/rules/unescaped-dollar.js +10 -0
- package/src/gorgon/rules/widget-in-table.js +10 -0
- package/src/gorgon/selector.js +506 -0
- package/src/gorgon/tree-transformer.js +588 -0
- package/src/hint-renderer.jsx +159 -0
- package/src/hints-renderer.jsx +359 -0
- package/src/icon-paths.js +120 -0
- package/src/index.js +149 -2
- package/src/init.js +49 -0
- package/src/interaction-tracker.js +60 -0
- package/src/interactive2/__tests__/movable-mock.js +48 -0
- package/src/interactive2/__tests__/movable-point_test.js +146 -0
- package/src/interactive2/interactive-util.js +152 -0
- package/src/interactive2/movable-helper-methods.js +160 -0
- package/src/interactive2/movable-line-options.js +392 -0
- package/src/interactive2/movable-line.js +322 -0
- package/src/interactive2/movable-point-options.js +190 -0
- package/src/interactive2/movable-point.jsx +603 -0
- package/src/interactive2/movable-polygon-options.js +351 -0
- package/src/interactive2/movable-polygon.js +368 -0
- package/src/interactive2/movable.js +273 -0
- package/src/interactive2/objective_.js +79 -0
- package/src/interactive2/types.js +3 -0
- package/src/interactive2/wrapped-defaults.js +86 -0
- package/src/interactive2/wrapped-ellipse.js +87 -0
- package/src/interactive2/wrapped-line.js +109 -0
- package/src/interactive2/wrapped-path.js +47 -0
- package/src/interactive2.js +91 -0
- package/src/item-renderer.jsx +518 -0
- package/src/item-version.js +12 -0
- package/src/jipt-paragraphs.js +44 -0
- package/src/jquery.mobile.vmouse.js +545 -0
- package/src/keypad-context.js +33 -0
- package/src/loading-context.js +20 -0
- package/src/logging/log.js +107 -0
- package/src/logging/log_test.js +41 -0
- package/src/mixins/changeable.jsx +115 -0
- package/src/mixins/editor-jsonify.jsx +13 -0
- package/src/mixins/provide-keypad.jsx +129 -0
- package/src/mixins/widget-jsonify-deprecated.jsx +23 -0
- package/src/mixins/widget-prop-blacklist.js +36 -0
- package/src/multi-items/__stories__/multi-renderer.stories.js +88 -0
- package/src/multi-items/__testdata__/multi-renderer_testdata.js +174 -0
- package/src/multi-items/__tests__/__snapshots__/multi-renderer_test.js.snap +994 -0
- package/src/multi-items/__tests__/items_test.js +245 -0
- package/src/multi-items/__tests__/multi-renderer_test.js +903 -0
- package/src/multi-items/__tests__/prop-type-builders_test.js +134 -0
- package/src/multi-items/__tests__/shapes_test.js +44 -0
- package/src/multi-items/__tests__/trees_test.js +316 -0
- package/src/multi-items/item-types.js +55 -0
- package/src/multi-items/items.js +176 -0
- package/src/multi-items/multi-renderer.jsx +543 -0
- package/src/multi-items/prop-type-builders.js +105 -0
- package/src/multi-items/shape-types.js +47 -0
- package/src/multi-items/shapes.js +53 -0
- package/src/multi-items/tree-types.js +42 -0
- package/src/multi-items/trees.js +345 -0
- package/src/multi-items.js +76 -0
- package/src/not-gorgon.js +129 -0
- package/src/perseus-api.jsx +270 -0
- package/src/perseus-env.js +26 -0
- package/src/perseus-error.js +19 -0
- package/src/perseus-markdown.jsx +433 -0
- package/src/perseus-types.js +1597 -0
- package/src/pure-markdown.js +347 -0
- package/src/question-paragraph.jsx +30 -0
- package/src/renderability.jsx +108 -0
- package/src/renderer.jsx +1932 -0
- package/src/server-item-renderer.jsx +467 -0
- package/src/sigfigs.jsx +492 -0
- package/src/styles/articles.less +748 -0
- package/src/styles/constants.js +119 -0
- package/src/styles/global-constants.js +350 -0
- package/src/styles/global-styles.js +307 -0
- package/src/styles/khan-exercise.css +1304 -0
- package/src/styles/media-queries.js +48 -0
- package/src/styles/perseus-renderer.less +1007 -0
- package/src/styles/shared.js +132 -0
- package/src/styles/util.less +47 -0
- package/src/styles/variables.boostrap.less +301 -0
- package/src/styles/variables.less +68 -0
- package/src/styles/variables.shared.less +356 -0
- package/src/styles/widgets/categorizer.less +39 -0
- package/src/styles/widgets/definition.less +86 -0
- package/src/styles/widgets/dropdown.less +3 -0
- package/src/styles/widgets/expression.less +147 -0
- package/src/styles/widgets/graded-group.less +36 -0
- package/src/styles/widgets/grapher.less +11 -0
- package/src/styles/widgets/group.less +19 -0
- package/src/styles/widgets/image.less +29 -0
- package/src/styles/widgets/interactive-graph.less +61 -0
- package/src/styles/widgets/label-image.less +41 -0
- package/src/styles/widgets/matcher.less +8 -0
- package/src/styles/widgets/matrix.less +120 -0
- package/src/styles/widgets/measurer.less +20 -0
- package/src/styles/widgets/orderer.less +97 -0
- package/src/styles/widgets/passage.less +151 -0
- package/src/styles/widgets/plotter.less +33 -0
- package/src/styles/widgets/radio.less +52 -0
- package/src/styles/widgets/reaction-diagram.less +35 -0
- package/src/styles/widgets/sequence.less +5 -0
- package/src/styles/widgets/sortable.less +127 -0
- package/src/styles/widgets/table.less +56 -0
- package/src/styles/widgets/transformer.less +28 -0
- package/src/styles/widgets/unit.less +14 -0
- package/src/tex-wrangler.js +176 -0
- package/src/traversal.jsx +141 -0
- package/src/types.js +538 -0
- package/src/util/a11y.js +24 -0
- package/src/util/answer-types.js +862 -0
- package/src/util/answer-types_test.js +115 -0
- package/src/util/colors.js +94 -0
- package/src/util/fix-passage-refs.jsx +122 -0
- package/src/util/graph-utils.js +16 -0
- package/src/util/graphie.js +1586 -0
- package/src/util/interactive.js +4078 -0
- package/src/util/katex-preprocess.js +16 -0
- package/src/util/math.js +296 -0
- package/src/util/mobile-native-utils.js +14 -0
- package/src/util/mobile-native-utils_test.js +24 -0
- package/src/util/register-all-widgets-for-testing.js +12 -0
- package/src/util/scroll-utils.js +162 -0
- package/src/util/sizing-utils.js +46 -0
- package/src/util/tex.js +203 -0
- package/src/util/url-utils.js +36 -0
- package/src/util.js +990 -0
- package/src/version.js +11 -0
- package/src/widget-container.jsx +174 -0
- package/src/widgets/__stories__/categorizer.stories.jsx +15 -0
- package/src/widgets/__stories__/cs-program.stories.jsx +15 -0
- package/src/widgets/__stories__/definition.stories.jsx +38 -0
- package/src/widgets/__stories__/dropdown.stories.jsx +15 -0
- package/src/widgets/__stories__/explanation.stories.jsx +19 -0
- package/src/widgets/__stories__/expression.stories.jsx +26 -0
- package/src/widgets/__stories__/graded-group-set.stories.jsx +32 -0
- package/src/widgets/__stories__/graded-group.stories.jsx +32 -0
- package/src/widgets/__stories__/grapher.stories.jsx +47 -0
- package/src/widgets/__stories__/group.stories.jsx +15 -0
- package/src/widgets/__stories__/iframe.stories.jsx +15 -0
- package/src/widgets/__stories__/image.stories.jsx +62 -0
- package/src/widgets/__stories__/input-number.stories.jsx +90 -0
- package/src/widgets/__stories__/interaction.stories.jsx +15 -0
- package/src/widgets/__stories__/interactive-graph.stories.jsx +61 -0
- package/src/widgets/__stories__/matcher.stories.jsx +15 -0
- package/src/widgets/__stories__/matrix.stories.jsx +15 -0
- package/src/widgets/__stories__/number-line.stories.jsx +15 -0
- package/src/widgets/__stories__/numeric-input.stories.jsx +19 -0
- package/src/widgets/__stories__/orderer.stories.jsx +15 -0
- package/src/widgets/__stories__/passage-ref.stories.jsx +19 -0
- package/src/widgets/__stories__/passage.stories.jsx +19 -0
- package/src/widgets/__stories__/radio.stories.jsx +82 -0
- package/src/widgets/__stories__/sorter.stories.jsx +15 -0
- package/src/widgets/__stories__/transformer.stories.jsx +15 -0
- package/src/widgets/__stories__/unit.stories.jsx +45 -0
- package/src/widgets/__stories__/video-transcript-link.stories.jsx +24 -0
- package/src/widgets/__stories__/video.stories.jsx +15 -0
- package/src/widgets/__testdata__/categorizer_testdata.js +50 -0
- package/src/widgets/__testdata__/cs-program_testdata.js +28 -0
- package/src/widgets/__testdata__/dropdown_testdata.js +34 -0
- package/src/widgets/__testdata__/explanation_testdata.js +56 -0
- package/src/widgets/__testdata__/expression_testdata.js +95 -0
- package/src/widgets/__testdata__/graded-group-set_testdata.js +358 -0
- package/src/widgets/__testdata__/graded-group_testdata.js +79 -0
- package/src/widgets/__testdata__/grapher_testdata.js +376 -0
- package/src/widgets/__testdata__/group_testdata.js +156 -0
- package/src/widgets/__testdata__/iframe_testdata.js +36 -0
- package/src/widgets/__testdata__/image_testdata.js +38 -0
- package/src/widgets/__testdata__/input-number_testdata.js +73 -0
- package/src/widgets/__testdata__/interaction_testdata.js +264 -0
- package/src/widgets/__testdata__/interactive-graph_testdata.js +646 -0
- package/src/widgets/__testdata__/matcher_testdata.js +34 -0
- package/src/widgets/__testdata__/matrix_testdata.js +29 -0
- package/src/widgets/__testdata__/number-line_testdata.js +31 -0
- package/src/widgets/__testdata__/numeric-input_testdata.js +266 -0
- package/src/widgets/__testdata__/orderer_testdata.js +58 -0
- package/src/widgets/__testdata__/passage-ref_testdata.js +41 -0
- package/src/widgets/__testdata__/passage_testdata.js +71 -0
- package/src/widgets/__testdata__/radio_testdata.js +210 -0
- package/src/widgets/__testdata__/sorter_testdata.js +20 -0
- package/src/widgets/__testdata__/transformer_testdata.js +109 -0
- package/src/widgets/__testdata__/video_testdata.js +22 -0
- package/src/widgets/__tests__/__snapshots__/categorizer_test.jsx.snap +928 -0
- package/src/widgets/__tests__/__snapshots__/cs-program_test.jsx.snap +75 -0
- package/src/widgets/__tests__/__snapshots__/definition_test.js.snap +99 -0
- package/src/widgets/__tests__/__snapshots__/dropdown_test.jsx.snap +143 -0
- package/src/widgets/__tests__/__snapshots__/explanation_test.js.snap +473 -0
- package/src/widgets/__tests__/__snapshots__/expression_test.jsx.snap +38 -0
- package/src/widgets/__tests__/__snapshots__/graded-group-set-jipt_test.jsx.snap +754 -0
- package/src/widgets/__tests__/__snapshots__/graded-group-set_test.jsx.snap +310 -0
- package/src/widgets/__tests__/__snapshots__/graded-group_test.jsx.snap +863 -0
- package/src/widgets/__tests__/__snapshots__/grapher_test.jsx.snap +2880 -0
- package/src/widgets/__tests__/__snapshots__/group_test.jsx.snap +1154 -0
- package/src/widgets/__tests__/__snapshots__/iframe_test.jsx.snap +69 -0
- package/src/widgets/__tests__/__snapshots__/image_test.jsx.snap +388 -0
- package/src/widgets/__tests__/__snapshots__/input-number_test.jsx.snap +978 -0
- package/src/widgets/__tests__/__snapshots__/interaction_test.jsx.snap +311 -0
- package/src/widgets/__tests__/__snapshots__/interactive-graph_test.jsx.snap +2915 -0
- package/src/widgets/__tests__/__snapshots__/matcher_test.jsx.snap +1039 -0
- package/src/widgets/__tests__/__snapshots__/matrix_test.jsx.snap +450 -0
- package/src/widgets/__tests__/__snapshots__/number-line_test.jsx.snap +888 -0
- package/src/widgets/__tests__/__snapshots__/numeric-input_test.jsx.snap +930 -0
- package/src/widgets/__tests__/__snapshots__/orderer_test.jsx.snap +275 -0
- package/src/widgets/__tests__/__snapshots__/passage-ref_test.jsx.snap +446 -0
- package/src/widgets/__tests__/__snapshots__/passage_test.jsx.snap +1988 -0
- package/src/widgets/__tests__/__snapshots__/radio_test.jsx.snap +7107 -0
- package/src/widgets/__tests__/__snapshots__/video_test.jsx.snap +163 -0
- package/src/widgets/__tests__/categorizer_test.jsx +205 -0
- package/src/widgets/__tests__/cs-program_test.jsx +45 -0
- package/src/widgets/__tests__/definition_test.js +152 -0
- package/src/widgets/__tests__/dropdown_test.jsx +106 -0
- package/src/widgets/__tests__/explanation_test.js +199 -0
- package/src/widgets/__tests__/expression_test.jsx +439 -0
- package/src/widgets/__tests__/graded-group-set-jipt_test.jsx +33 -0
- package/src/widgets/__tests__/graded-group-set_test.jsx +270 -0
- package/src/widgets/__tests__/graded-group_test.jsx +233 -0
- package/src/widgets/__tests__/grapher.cypress.jsx +486 -0
- package/src/widgets/__tests__/grapher_test.jsx +35 -0
- package/src/widgets/__tests__/group_test.jsx +512 -0
- package/src/widgets/__tests__/iframe_test.jsx +47 -0
- package/src/widgets/__tests__/image_test.jsx +65 -0
- package/src/widgets/__tests__/input-number_test.jsx +360 -0
- package/src/widgets/__tests__/interaction_test.jsx +33 -0
- package/src/widgets/__tests__/interactive-graph.cypress.jsx +697 -0
- package/src/widgets/__tests__/interactive-graph_test.jsx +105 -0
- package/src/widgets/__tests__/matcher_test.jsx +157 -0
- package/src/widgets/__tests__/matrix_test.jsx +84 -0
- package/src/widgets/__tests__/number-line_test.jsx +81 -0
- package/src/widgets/__tests__/numeric-input_test.jsx +574 -0
- package/src/widgets/__tests__/orderer_test.jsx +75 -0
- package/src/widgets/__tests__/passage-ref_test.jsx +166 -0
- package/src/widgets/__tests__/passage_test.jsx +133 -0
- package/src/widgets/__tests__/radio/base-radio_test.jsx +82 -0
- package/src/widgets/__tests__/radio_test.jsx +651 -0
- package/src/widgets/__tests__/renderQuestion.jsx +66 -0
- package/src/widgets/__tests__/unit_test.jsx +144 -0
- package/src/widgets/__tests__/video_test.jsx +55 -0
- package/src/widgets/categorizer.jsx +338 -0
- package/src/widgets/cs-program.jsx +227 -0
- package/src/widgets/definition.jsx +141 -0
- package/src/widgets/dropdown.jsx +143 -0
- package/src/widgets/explanation.jsx +315 -0
- package/src/widgets/expression.jsx +652 -0
- package/src/widgets/graded-group-answer-bar.jsx +152 -0
- package/src/widgets/graded-group-set.jsx +285 -0
- package/src/widgets/graded-group.jsx +448 -0
- package/src/widgets/grapher/util.jsx +806 -0
- package/src/widgets/grapher.jsx +663 -0
- package/src/widgets/group.jsx +213 -0
- package/src/widgets/iframe.jsx +198 -0
- package/src/widgets/image.jsx +310 -0
- package/src/widgets/input-number.jsx +411 -0
- package/src/widgets/interaction/arrow-picker.jsx +39 -0
- package/src/widgets/interaction/color-picker.jsx +69 -0
- package/src/widgets/interaction/dash-picker.jsx +46 -0
- package/src/widgets/interaction/element-container.jsx +97 -0
- package/src/widgets/interaction.jsx +742 -0
- package/src/widgets/interactive-graph.jsx +2820 -0
- package/src/widgets/label-image/__stories__/answer-choices.stories.jsx +93 -0
- package/src/widgets/label-image/__stories__/marker.stories.jsx +172 -0
- package/src/widgets/label-image/answer-choices.jsx +311 -0
- package/src/widgets/label-image/marker.jsx +365 -0
- package/src/widgets/label-image/types.js +33 -0
- package/src/widgets/label-image.jsx +841 -0
- package/src/widgets/label-image_test.js +840 -0
- package/src/widgets/lights-puzzle.jsx +356 -0
- package/src/widgets/matcher.jsx +271 -0
- package/src/widgets/matrix.jsx +616 -0
- package/src/widgets/measurer.jsx +215 -0
- package/src/widgets/molecule/__tests__/layout_test.jsx +159 -0
- package/src/widgets/molecule/__tests__/parser_test.jsx +142 -0
- package/src/widgets/molecule/molecule-drawing.jsx +175 -0
- package/src/widgets/molecule/molecule-layout.jsx +367 -0
- package/src/widgets/molecule/smiles-parser.jsx +300 -0
- package/src/widgets/molecule.jsx +172 -0
- package/src/widgets/number-line.jsx +858 -0
- package/src/widgets/numeric-input.jsx +622 -0
- package/src/widgets/orderer.jsx +753 -0
- package/src/widgets/passage/__tests__/passage-markdown_test.jsx +382 -0
- package/src/widgets/passage/get-line-height-for-node.js +10 -0
- package/src/widgets/passage/passage-markdown.jsx +416 -0
- package/src/widgets/passage-ref-target.jsx +70 -0
- package/src/widgets/passage-ref.jsx +198 -0
- package/src/widgets/passage.jsx +601 -0
- package/src/widgets/plotter.jsx +1198 -0
- package/src/widgets/radio/__stories__/base-radio.stories.jsx +40 -0
- package/src/widgets/radio/__stories__/choice-icon.stories.jsx +157 -0
- package/src/widgets/radio/__stories__/choice-none-above.stories.jsx +26 -0
- package/src/widgets/radio/__stories__/cross-out-button.stories.jsx +64 -0
- package/src/widgets/radio/__stories__/cross-out-menu.stories.jsx +59 -0
- package/src/widgets/radio/__stories__/cross-out-tooltip.stories.jsx +59 -0
- package/src/widgets/radio/__stories__/focus-ring.stories.jsx +38 -0
- package/src/widgets/radio/__stories__/option-status.stories.jsx +118 -0
- package/src/widgets/radio/__stories__/toggleable-radio-button.stories.jsx +28 -0
- package/src/widgets/radio/base-radio.jsx +642 -0
- package/src/widgets/radio/choice-icon.jsx +468 -0
- package/src/widgets/radio/choice-none-above.jsx +54 -0
- package/src/widgets/radio/choice.jsx +692 -0
- package/src/widgets/radio/choice.jsx.fixture.js +64 -0
- package/src/widgets/radio/cross-out-button.jsx +136 -0
- package/src/widgets/radio/cross-out-menu-wrapper.jsx +492 -0
- package/src/widgets/radio/cross-out-tooltip.jsx +129 -0
- package/src/widgets/radio/focus-ring.jsx +51 -0
- package/src/widgets/radio/option-status.jsx +89 -0
- package/src/widgets/radio/toggleable-radio-button.jsx +133 -0
- package/src/widgets/radio/util.js +32 -0
- package/src/widgets/radio/util_test.js +19 -0
- package/src/widgets/radio/widget.jsx +470 -0
- package/src/widgets/radio.jsx +156 -0
- package/src/widgets/reaction-diagram.jsx +137 -0
- package/src/widgets/sequence.jsx +140 -0
- package/src/widgets/simulator.jsx +808 -0
- package/src/widgets/sorter.jsx +146 -0
- package/src/widgets/table.jsx +394 -0
- package/src/widgets/transformer.jsx +2876 -0
- package/src/widgets/unit.jsx +372 -0
- package/src/widgets/video-transcript-link.jsx +84 -0
- package/src/widgets/video-transcript-link_test.js +211 -0
- package/src/widgets/video.jsx +126 -0
- package/src/widgets.js +431 -0
- package/src/zoom.js +539 -0
- package/README.md +0 -3
- package/src/__tests__/index.test.js +0 -14
package/src/index.js
CHANGED
|
@@ -1,4 +1,151 @@
|
|
|
1
1
|
// @flow
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Main entry point
|
|
4
|
+
*/
|
|
3
5
|
|
|
4
|
-
|
|
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;
|