@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
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
.draggy-boxy-thing-hover (@color: #ffa500) {
|
|
2
|
+
border-color: @color;
|
|
3
|
+
@darker: darken(@color, 11%);
|
|
4
|
+
box-shadow: 0 0 4px @darker;
|
|
5
|
+
-moz-box-shadow: 0 0 4px @darker;
|
|
6
|
+
-ms-box-shadow: 0 0 4px @darker;
|
|
7
|
+
-o-box-shadow: 0 0 4px @darker;
|
|
8
|
+
-webkit-box-shadow: 0 0 4px @darker;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.draggy-boxy-thing {
|
|
12
|
+
.draggable-box,
|
|
13
|
+
.cards-area {
|
|
14
|
+
background: #eee;
|
|
15
|
+
border: 1px solid #ccc;
|
|
16
|
+
border-bottom: 1px solid #aaa;
|
|
17
|
+
|
|
18
|
+
box-shadow: 0 1px 2px #ccc;
|
|
19
|
+
-moz-box-shadow: 0 1px 2px #ccc;
|
|
20
|
+
-webkit-box-shadow: 0 1px 2px #ccc;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// TODO(jack): Make this work for the orderer too.
|
|
24
|
+
// Right now don't do this for the orderer because it uses
|
|
25
|
+
// more complicated positioning that this would break
|
|
26
|
+
.cards-area {
|
|
27
|
+
.above-scratchpad;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.card {
|
|
31
|
+
.perseus-interactive;
|
|
32
|
+
|
|
33
|
+
background-color: #fff;
|
|
34
|
+
border: 1px solid #b9b9b9;
|
|
35
|
+
border-bottom-color: #939393;
|
|
36
|
+
border-radius: 4px;
|
|
37
|
+
-moz-border-radius: 4px;
|
|
38
|
+
-webkit-border-radius: 4px;
|
|
39
|
+
-webkit-user-select: none;
|
|
40
|
+
-khtml-user-select: none;
|
|
41
|
+
-moz-user-select: none;
|
|
42
|
+
-o-user-select: none;
|
|
43
|
+
cursor: pointer;
|
|
44
|
+
touch-action: none;
|
|
45
|
+
|
|
46
|
+
&.placeholder {
|
|
47
|
+
background:#ddd;
|
|
48
|
+
border: 1px solid #ccc;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
&.drag-hint {
|
|
52
|
+
background: none;
|
|
53
|
+
border: 1px dashed #aaa;
|
|
54
|
+
cursor: auto;
|
|
55
|
+
|
|
56
|
+
&:hover {
|
|
57
|
+
border-color: #aaa;
|
|
58
|
+
box-shadow: none;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
&.dragging {
|
|
63
|
+
background-color: #ffedcd;
|
|
64
|
+
opacity: 0.8;
|
|
65
|
+
filter: opacity(0.8);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
&.stack {
|
|
69
|
+
z-index: auto;
|
|
70
|
+
&:after {
|
|
71
|
+
content: " ";
|
|
72
|
+
background-color: #fff;
|
|
73
|
+
border: 1px solid #b9b9b9;
|
|
74
|
+
border-bottom-color: #939393;
|
|
75
|
+
border-radius: 4px;
|
|
76
|
+
-moz-border-radius: 4px;
|
|
77
|
+
-webkit-border-radius: 4px;
|
|
78
|
+
height: 100%;
|
|
79
|
+
width: 100%;
|
|
80
|
+
z-index: -1;
|
|
81
|
+
top: 1px;
|
|
82
|
+
left: 1px;
|
|
83
|
+
position: absolute;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
&:hover {
|
|
88
|
+
.draggy-boxy-thing-hover();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// TODO(benkomalo): ideally all of these would be removed as all of the other
|
|
94
|
+
// sortable styles have been moved to inline styles using Aphrodite. However,
|
|
95
|
+
// these are all hacky styles that reach down into descendents in ways that
|
|
96
|
+
// they probably shouldn't, so Aphrodite doesn't support it. This will require
|
|
97
|
+
// a larger refactoring to wire down options to nested `Renderer`s so they can
|
|
98
|
+
// have their styling modified.
|
|
99
|
+
.perseus-sortable {
|
|
100
|
+
div.paragraph {
|
|
101
|
+
margin: 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.perseus-sortable-draggable {
|
|
105
|
+
&:before {
|
|
106
|
+
// Vertical-align, part 1
|
|
107
|
+
content: "";
|
|
108
|
+
display: inline-block;
|
|
109
|
+
height: 100%;
|
|
110
|
+
vertical-align: middle;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
& > div {
|
|
114
|
+
// Vertical-align, part 2
|
|
115
|
+
display: inline-block;
|
|
116
|
+
font-size: 14px;
|
|
117
|
+
max-width: 100%;
|
|
118
|
+
vertical-align: middle;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.perseus-sortable-draggable-unpadded {
|
|
123
|
+
img {
|
|
124
|
+
vertical-align: bottom;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Extra specifity is needed to counteract generic tables
|
|
2
|
+
.framework-perseus table.perseus-widget-table-of-values.non-markdown {
|
|
3
|
+
text-align: left;
|
|
4
|
+
margin: 20px auto;
|
|
5
|
+
border-collapse: collapse;
|
|
6
|
+
|
|
7
|
+
tr {
|
|
8
|
+
height: 23px;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
th, td {
|
|
12
|
+
border: 2px solid black;
|
|
13
|
+
border-width: 0 2px;
|
|
14
|
+
|
|
15
|
+
&:first-child {
|
|
16
|
+
border-left: 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
&:last-child {
|
|
20
|
+
border-right: 0;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
th {
|
|
25
|
+
font-weight: normal;
|
|
26
|
+
padding: 5px;
|
|
27
|
+
width: 80px;
|
|
28
|
+
text-align: left;
|
|
29
|
+
border-bottom: 2px solid black;
|
|
30
|
+
.paragraph {
|
|
31
|
+
margin: 0;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
td {
|
|
36
|
+
padding: 0px 5px;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
tbody tr:first-child td {
|
|
40
|
+
padding-top: 5px;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
.framework-perseus table.perseus-widget-table-of-values input,
|
|
44
|
+
#answer_area table.perseus-widget-table-of-values input {
|
|
45
|
+
// NOTE(charlie): This should be kept in-sync with the "width: 80" in
|
|
46
|
+
// table.jsx.
|
|
47
|
+
width: 80px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
body.mobile {
|
|
51
|
+
.framework-perseus table.perseus-widget-table-of-values.non-markdown {
|
|
52
|
+
td {
|
|
53
|
+
padding: 5px;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
.perseus-widget-transformer {
|
|
2
|
+
.highlighted-tool-button {
|
|
3
|
+
text-shadow: 1px 1px rgba(0, 0, 0, 0.25);
|
|
4
|
+
}
|
|
5
|
+
> .graphie-container {
|
|
6
|
+
margin-bottom: 10px;
|
|
7
|
+
position: relative;
|
|
8
|
+
overflow: hidden;
|
|
9
|
+
|
|
10
|
+
> img, > .unresponsive-svg-image {
|
|
11
|
+
position: absolute;
|
|
12
|
+
// Preserves background image alignment (if image is a graph,
|
|
13
|
+
// it can extend up and to the right to allow for axis labels)
|
|
14
|
+
bottom: 0;
|
|
15
|
+
left: 0;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
.transformer-undo-button {
|
|
19
|
+
float: right;
|
|
20
|
+
}
|
|
21
|
+
.perseus-transformation-list {
|
|
22
|
+
input {
|
|
23
|
+
width: 40px;
|
|
24
|
+
}
|
|
25
|
+
margin-top: 10px;
|
|
26
|
+
margin-bottom: 10px;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
.old-unit-input input, .unit-editor-canonical {
|
|
2
|
+
border: 1px solid #a4a4a4;
|
|
3
|
+
border-radius: 5px;
|
|
4
|
+
// box-sizing: border-box;
|
|
5
|
+
font-size: 14px;
|
|
6
|
+
// margin-bottom: 5px;
|
|
7
|
+
// max-width: 240px;
|
|
8
|
+
padding: 6px;
|
|
9
|
+
// width: 100%;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.unit-editor > div {
|
|
13
|
+
margin: 5px 0;
|
|
14
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
/*
|
|
3
|
+
* In this file, an `expression` is some portion of valid TeX enclosed in
|
|
4
|
+
* curly brackets.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
* Find the index at which an expression ends, i.e., has an unmatched
|
|
9
|
+
* closing curly bracket. This method assumes that we start with a non-open
|
|
10
|
+
* bracket character and end when we've seen more left than right brackets
|
|
11
|
+
* (rather than assuming that we start with a bracket character and wait for
|
|
12
|
+
* bracket equality).
|
|
13
|
+
*/
|
|
14
|
+
function findEndpoint(tex, currentIndex) {
|
|
15
|
+
let bracketDepth = 0;
|
|
16
|
+
|
|
17
|
+
for (let i = currentIndex, len = tex.length; i < len; i++) {
|
|
18
|
+
const c = tex[i];
|
|
19
|
+
|
|
20
|
+
if (c === "{") {
|
|
21
|
+
bracketDepth++;
|
|
22
|
+
} else if (c === "}") {
|
|
23
|
+
bracketDepth--;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (bracketDepth < 0) {
|
|
27
|
+
return i;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// If we never see unbalanced curly brackets, default to the
|
|
31
|
+
// entire string
|
|
32
|
+
return tex.length;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/*
|
|
36
|
+
* Parses an individual set of curly brackets into TeX.
|
|
37
|
+
*/
|
|
38
|
+
function parseNextExpression(tex, currentIndex, handler) {
|
|
39
|
+
// Find the first '{' and grab subsequent TeX
|
|
40
|
+
// Ex) tex: '{3}{7}', and we want the '3'
|
|
41
|
+
const openBracketIndex = tex.indexOf("{", currentIndex);
|
|
42
|
+
const nextExpIndex = openBracketIndex + 1;
|
|
43
|
+
|
|
44
|
+
// Truncate to only contain remaining TeX
|
|
45
|
+
const endpoint = findEndpoint(tex, nextExpIndex);
|
|
46
|
+
const expressionTeX = tex.substring(nextExpIndex, endpoint);
|
|
47
|
+
const parsedExp = walkTex(expressionTeX, handler);
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
endpoint: endpoint,
|
|
51
|
+
expression: parsedExp,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function getNextFracIndex(tex, currentIndex) {
|
|
56
|
+
const dfrac = "\\dfrac";
|
|
57
|
+
const frac = "\\frac";
|
|
58
|
+
|
|
59
|
+
const nextFrac = tex.indexOf(frac, currentIndex);
|
|
60
|
+
const nextDFrac = tex.indexOf(dfrac, currentIndex);
|
|
61
|
+
|
|
62
|
+
if (nextFrac > -1 && nextDFrac > -1) {
|
|
63
|
+
return Math.min(nextFrac, nextDFrac);
|
|
64
|
+
}
|
|
65
|
+
if (nextFrac > -1) {
|
|
66
|
+
return nextFrac;
|
|
67
|
+
}
|
|
68
|
+
if (nextDFrac > -1) {
|
|
69
|
+
return nextDFrac;
|
|
70
|
+
}
|
|
71
|
+
return -1;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function walkTex(tex: string, handler): string {
|
|
75
|
+
if (!tex) {
|
|
76
|
+
return "";
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Ex) tex: '2 \dfrac {3}{7}'
|
|
80
|
+
let parsedString = "";
|
|
81
|
+
let currentIndex = 0;
|
|
82
|
+
let nextFrac = getNextFracIndex(tex, currentIndex);
|
|
83
|
+
|
|
84
|
+
// For each \dfrac, find the two expressions (wrapped in {}) and recur
|
|
85
|
+
while (nextFrac > -1) {
|
|
86
|
+
// Gather first fragment, preceding \dfrac
|
|
87
|
+
// Ex) parsedString: '2 '
|
|
88
|
+
parsedString += tex.substring(currentIndex, nextFrac);
|
|
89
|
+
|
|
90
|
+
// Remove everything preceding \dfrac, which has been parsed
|
|
91
|
+
currentIndex = nextFrac;
|
|
92
|
+
|
|
93
|
+
// Parse first expression and move index past it
|
|
94
|
+
// Ex) firstParsedExpression.expression: '3'
|
|
95
|
+
const firstParsedExpression = parseNextExpression(
|
|
96
|
+
tex,
|
|
97
|
+
currentIndex,
|
|
98
|
+
handler,
|
|
99
|
+
);
|
|
100
|
+
currentIndex = firstParsedExpression.endpoint + 1;
|
|
101
|
+
|
|
102
|
+
// Parse second expression
|
|
103
|
+
// Ex) secondParsedExpression.expression: '7'
|
|
104
|
+
const secondParsedExpression = parseNextExpression(
|
|
105
|
+
tex,
|
|
106
|
+
currentIndex,
|
|
107
|
+
handler,
|
|
108
|
+
);
|
|
109
|
+
currentIndex = secondParsedExpression.endpoint + 1;
|
|
110
|
+
|
|
111
|
+
// Add expressions to running total of parsed expressions
|
|
112
|
+
if (parsedString.length) {
|
|
113
|
+
parsedString += " ";
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Apply a custom handler based on the parsed subexpressions
|
|
117
|
+
parsedString += handler(
|
|
118
|
+
firstParsedExpression.expression,
|
|
119
|
+
secondParsedExpression.expression,
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
// Find next DFrac, relative to currentIndex
|
|
123
|
+
nextFrac = getNextFracIndex(tex, currentIndex);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Add remaining TeX, which is \dfrac-free
|
|
127
|
+
parsedString += tex.slice(currentIndex);
|
|
128
|
+
|
|
129
|
+
return parsedString;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/*
|
|
133
|
+
* Modify a TeX expression, returning another TeX expression. The resulting
|
|
134
|
+
* expression will have its innermost fractions stubbed out with \fracs
|
|
135
|
+
* (as opposed to \dfracs). All other content will remain untouched.
|
|
136
|
+
*/
|
|
137
|
+
function modifyTex(tex: string): string {
|
|
138
|
+
function isNestedFraction(tex) {
|
|
139
|
+
return tex.indexOf("\\frac") > -1 || tex.indexOf("\\dfrac") > -1;
|
|
140
|
+
}
|
|
141
|
+
const handler = function (exp1, exp2) {
|
|
142
|
+
let prefix;
|
|
143
|
+
if (isNestedFraction(exp1) || isNestedFraction(exp2)) {
|
|
144
|
+
prefix = "\\dfrac";
|
|
145
|
+
} else {
|
|
146
|
+
prefix = "\\frac";
|
|
147
|
+
}
|
|
148
|
+
return prefix + " {" + exp1 + "}{" + exp2 + "}";
|
|
149
|
+
};
|
|
150
|
+
return walkTex(tex, handler);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/*
|
|
154
|
+
* Parse a TeX expression into something interpretable by input-number.
|
|
155
|
+
* The process is concerned with: (1) parsing fractions, i.e., \dfracs; and
|
|
156
|
+
* (2) removing backslash-escaping from certain characters (right now, only
|
|
157
|
+
* percent signs).
|
|
158
|
+
*
|
|
159
|
+
* The basic algorithm for handling \dfracs splits on \dfracs and then recurs
|
|
160
|
+
* on the subsequent "expressions", i.e., the {} pairs that follow \dfrac. The
|
|
161
|
+
* recursion is to allow for nested \dfrac elements.
|
|
162
|
+
*
|
|
163
|
+
* Backslash-escapes are removed with a simple search-and-replace.
|
|
164
|
+
*/
|
|
165
|
+
function parseTex(tex: string): string {
|
|
166
|
+
const handler = function (exp1, exp2) {
|
|
167
|
+
return exp1 + "/" + exp2;
|
|
168
|
+
};
|
|
169
|
+
const texWithoutFracs = walkTex(tex, handler);
|
|
170
|
+
return texWithoutFracs.replace("\\%", "%");
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export default {
|
|
174
|
+
parseTex,
|
|
175
|
+
modifyTex,
|
|
176
|
+
};
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
/**
|
|
3
|
+
* Traverses a {content, widgets, images} renderer props object,
|
|
4
|
+
* such as `itemData.question`
|
|
5
|
+
*
|
|
6
|
+
* This traversal is deep and handles some widget prop upgrades
|
|
7
|
+
* (TODO(aria): Handle minor prop upgrades :) )
|
|
8
|
+
*
|
|
9
|
+
* This is the right way to traverse itemData.
|
|
10
|
+
*
|
|
11
|
+
* NOTE: We should not expose this on the perseus API yet. Instead,
|
|
12
|
+
* build the traversal method you want inside perseus, and use this
|
|
13
|
+
* from that. We might eventually expose this, but I'd like to be
|
|
14
|
+
* more confident in the interface provided first.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import _ from "underscore";
|
|
18
|
+
|
|
19
|
+
// TODO(aria): Pull this out of interactive2 / replace with new _.mapObject
|
|
20
|
+
import objective_ from "./interactive2/objective_.js";
|
|
21
|
+
import * as Widgets from "./widgets.js";
|
|
22
|
+
|
|
23
|
+
const noop = function () {};
|
|
24
|
+
|
|
25
|
+
const deepCallbackFor = function (
|
|
26
|
+
contentCallback: ($FlowFixMe) => void,
|
|
27
|
+
widgetCallback: (widgetInfo: $FlowFixMe, widgetId: string) => $FlowFixMe,
|
|
28
|
+
optionsCallback: ($FlowFixMe) => void,
|
|
29
|
+
) {
|
|
30
|
+
const deepCallback = function (widgetInfo, widgetId) {
|
|
31
|
+
// This doesn't modify the widget info if the widget info
|
|
32
|
+
// is at a later version than is supported, which is important
|
|
33
|
+
// for our latestVersion test below.
|
|
34
|
+
const upgradedWidgetInfo =
|
|
35
|
+
Widgets.upgradeWidgetInfoToLatestVersion(widgetInfo);
|
|
36
|
+
const latestVersion = Widgets.getVersion(upgradedWidgetInfo.type);
|
|
37
|
+
|
|
38
|
+
// Only traverse our children if we can understand this version
|
|
39
|
+
// of the widget props.
|
|
40
|
+
// TODO(aria): This will break if the traversal code assumes that
|
|
41
|
+
// any props that usually get defaulted in are present. That is,
|
|
42
|
+
// it can fail on minor version upgrades.
|
|
43
|
+
// For this reason, and because the upgrade code doesn't handle
|
|
44
|
+
// minor versions correctly (it doesn't report anything useful
|
|
45
|
+
// about what minor version a widget is actually at, since it
|
|
46
|
+
// doesn't have meaning in the context of upgrades), we
|
|
47
|
+
// just check the major version here.
|
|
48
|
+
// TODO(aria): This is seriously quirky and would be unpleasant
|
|
49
|
+
// to think about while writing traverseChildWidgets code. Please
|
|
50
|
+
// make all of this a little tighter.
|
|
51
|
+
// I think once we use react class defaultProps instead of relying
|
|
52
|
+
// on getDefaultProps, this will become easier.
|
|
53
|
+
let newWidgetInfo;
|
|
54
|
+
if (
|
|
55
|
+
latestVersion &&
|
|
56
|
+
upgradedWidgetInfo.version?.major === latestVersion.major
|
|
57
|
+
) {
|
|
58
|
+
newWidgetInfo = Widgets.traverseChildWidgets(
|
|
59
|
+
upgradedWidgetInfo,
|
|
60
|
+
(rendererOptions) => {
|
|
61
|
+
return traverseRenderer(
|
|
62
|
+
rendererOptions,
|
|
63
|
+
contentCallback,
|
|
64
|
+
// so that we traverse grandchildren, too:
|
|
65
|
+
deepCallback,
|
|
66
|
+
optionsCallback,
|
|
67
|
+
);
|
|
68
|
+
},
|
|
69
|
+
);
|
|
70
|
+
} else {
|
|
71
|
+
newWidgetInfo = upgradedWidgetInfo;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const userWidgetInfo = widgetCallback(newWidgetInfo, widgetId);
|
|
75
|
+
if (userWidgetInfo !== undefined) {
|
|
76
|
+
return userWidgetInfo;
|
|
77
|
+
}
|
|
78
|
+
return newWidgetInfo;
|
|
79
|
+
};
|
|
80
|
+
return deepCallback;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const traverseRenderer = function (
|
|
84
|
+
rendererOptions,
|
|
85
|
+
contentCallback: ($FlowFixMe) => void,
|
|
86
|
+
deepWidgetCallback: (
|
|
87
|
+
widgetInfo: $FlowFixMe,
|
|
88
|
+
widgetId: string,
|
|
89
|
+
) => $FlowFixMe,
|
|
90
|
+
optionsCallback: ($FlowFixMe) => void,
|
|
91
|
+
) {
|
|
92
|
+
let newContent = rendererOptions.content;
|
|
93
|
+
if (rendererOptions.content != null) {
|
|
94
|
+
const modifiedContent = contentCallback(rendererOptions.content);
|
|
95
|
+
if (modifiedContent !== undefined) {
|
|
96
|
+
newContent = modifiedContent;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const newWidgets = objective_.mapObject(
|
|
101
|
+
rendererOptions.widgets || {},
|
|
102
|
+
function (widgetInfo, widgetId) {
|
|
103
|
+
// Widgets without info or a type are empty widgets, and
|
|
104
|
+
// should always be renderable. It's also annoying to write
|
|
105
|
+
// checks for this everywhere, so we just filter them out once and
|
|
106
|
+
// for all!
|
|
107
|
+
if (widgetInfo == null || widgetInfo.type == null) {
|
|
108
|
+
return widgetInfo;
|
|
109
|
+
}
|
|
110
|
+
return deepWidgetCallback(widgetInfo, widgetId);
|
|
111
|
+
},
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
const newOptions = _.extend({}, rendererOptions, {
|
|
115
|
+
content: newContent,
|
|
116
|
+
widgets: newWidgets,
|
|
117
|
+
});
|
|
118
|
+
const userOptions = optionsCallback(newOptions);
|
|
119
|
+
if (userOptions !== undefined) {
|
|
120
|
+
return userOptions;
|
|
121
|
+
}
|
|
122
|
+
return newOptions;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export const traverse = function (
|
|
126
|
+
rendererOptions: $FlowFixMe,
|
|
127
|
+
contentCallback?: ?($FlowFixMe) => $FlowFixMe,
|
|
128
|
+
widgetCallback?: ?(widgetInfo: $FlowFixMe, widgetId: string) => $FlowFixMe,
|
|
129
|
+
optionsCallback?: ($FlowFixMe) => void,
|
|
130
|
+
): $FlowFixMe {
|
|
131
|
+
contentCallback = contentCallback || noop;
|
|
132
|
+
widgetCallback = widgetCallback || noop;
|
|
133
|
+
optionsCallback = optionsCallback || noop;
|
|
134
|
+
|
|
135
|
+
return traverseRenderer(
|
|
136
|
+
rendererOptions,
|
|
137
|
+
contentCallback,
|
|
138
|
+
deepCallbackFor(contentCallback, widgetCallback, optionsCallback),
|
|
139
|
+
optionsCallback,
|
|
140
|
+
);
|
|
141
|
+
};
|