@khanacademy/perseus 19.1.5 → 19.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/graph.d.ts +0 -1
- package/dist/components/graphie.d.ts +0 -1
- package/dist/es/index.js +319 -212
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +338 -222
- package/dist/index.js.map +1 -1
- package/dist/interactive2/movable-point.d.ts +195 -1
- package/dist/interactive2/movable.d.ts +1 -1
- package/dist/interactive2/types.d.ts +4 -2
- package/dist/interactive2.d.ts +2 -1
- package/dist/server-item-renderer.d.ts +2 -2
- package/dist/util/graphie.d.ts +12 -2
- package/dist/widgets/expression.d.ts +6 -6
- package/package.json +11 -8
- package/.babelrc.js +0 -8
- package/.eslintrc.js +0 -12
- package/CHANGELOG.md +0 -1432
- package/src/__stories__/article-renderer.stories.tsx +0 -100
- package/src/__stories__/hints-renderer.stories.tsx +0 -55
- package/src/__stories__/server-item-renderer.stories.tsx +0 -44
- package/src/__testdata__/article-renderer.testdata.ts +0 -212
- package/src/__testdata__/graphie.testdata.ts +0 -51
- package/src/__testdata__/renderer.testdata.ts +0 -274
- package/src/__testdata__/server-item-renderer.testdata.ts +0 -171
- package/src/__tests__/__snapshots__/perseus-markdown.test.ts.snap +0 -507
- package/src/__tests__/__snapshots__/renderer.test.tsx.snap +0 -525
- package/src/__tests__/__snapshots__/server-item-renderer.test.tsx.snap +0 -285
- package/src/__tests__/a11y.test.ts +0 -303
- package/src/__tests__/article-renderer.test.tsx +0 -130
- package/src/__tests__/error-boundary.test.tsx +0 -76
- package/src/__tests__/extract-perseus-data.test.ts +0 -1027
- package/src/__tests__/init.test.ts +0 -10
- package/src/__tests__/jipt-paragraphs.test.ts +0 -32
- package/src/__tests__/mock-asset-loading-widget.tsx +0 -53
- package/src/__tests__/mock-widget.tsx +0 -33
- package/src/__tests__/perseus-markdown.test.ts +0 -764
- package/src/__tests__/renderability.test.ts +0 -480
- package/src/__tests__/renderer-api.test.tsx +0 -302
- package/src/__tests__/renderer.test.tsx +0 -1816
- package/src/__tests__/server-item-renderer.test.tsx +0 -582
- package/src/__tests__/test-items/image-item.ts +0 -24
- package/src/__tests__/test-items/input-number-1-item.ts +0 -26
- package/src/__tests__/test-items/input-number-2-item.ts +0 -38
- package/src/__tests__/test-items/table-item.ts +0 -29
- package/src/__tests__/tex-wrangler.test.ts +0 -82
- package/src/__tests__/util.test.ts +0 -40
- package/src/__tests__/widget-container.test.tsx +0 -126
- package/src/__tests__/widgets.test.ts +0 -91
- package/src/a11y.ts +0 -45
- package/src/all-widgets.ts +0 -9
- package/src/article-renderer.tsx +0 -237
- package/src/asset-context.ts +0 -30
- package/src/basic-widgets.ts +0 -16
- package/src/components/__stories__/button-group.stories.tsx +0 -55
- package/src/components/__stories__/fixed-to-responsive.stories.tsx +0 -141
- package/src/components/__stories__/graph.stories.tsx +0 -28
- package/src/components/__stories__/graphie.stories.tsx +0 -33
- package/src/components/__stories__/hud.stories.tsx +0 -35
- package/src/components/__stories__/icon.stories.tsx +0 -63
- package/src/components/__stories__/image-loader.stories.tsx +0 -63
- package/src/components/__stories__/info-tip.stories.tsx +0 -31
- package/src/components/__stories__/inline-icon.stories.tsx +0 -40
- package/src/components/__stories__/input-with-examples.stories.tsx +0 -53
- package/src/components/__stories__/lint.stories.tsx +0 -86
- package/src/components/__stories__/math-input.stories.tsx +0 -43
- package/src/components/__stories__/math-output.stories.tsx +0 -23
- package/src/components/__stories__/multi-button-group.stories.tsx +0 -66
- package/src/components/__stories__/number-input.stories.tsx +0 -41
- package/src/components/__stories__/prop-check-box.stories.tsx +0 -65
- package/src/components/__stories__/range-input.stories.tsx +0 -29
- package/src/components/__stories__/simple-keypad-input.stories.tsx +0 -27
- package/src/components/__stories__/sortable.stories.tsx +0 -77
- package/src/components/__stories__/stub-tag-editor.stories.tsx +0 -45
- package/src/components/__stories__/svg-image.stories.tsx +0 -74
- package/src/components/__stories__/tex.stories.tsx +0 -23
- package/src/components/__stories__/text-input.stories.tsx +0 -33
- package/src/components/__stories__/text-list-editor.stories.tsx +0 -32
- package/src/components/__stories__/tooltip.stories.tsx +0 -52
- package/src/components/__stories__/zoomable-tex.stories.tsx +0 -41
- package/src/components/__stories__/zoomable.stories.tsx +0 -49
- package/src/components/__testdata__/sorter.testdata.ts +0 -19
- package/src/components/__tests__/__snapshots__/sortable.test.tsx.snap +0 -163
- package/src/components/__tests__/__snapshots__/sorter.test.tsx.snap +0 -265
- package/src/components/__tests__/math-input.test.tsx +0 -147
- package/src/components/__tests__/number-input.test.tsx +0 -128
- package/src/components/__tests__/sortable.test.tsx +0 -269
- package/src/components/__tests__/sorter.test.tsx +0 -114
- package/src/components/__tests__/zoomable.test.tsx +0 -399
- package/src/components/button-group.tsx +0 -130
- package/src/components/constants.ts +0 -14
- package/src/components/fixed-to-responsive.tsx +0 -169
- package/src/components/graph.tsx +0 -444
- package/src/components/graphie-classes.ts +0 -153
- package/src/components/graphie-movables.ts +0 -338
- package/src/components/graphie.tsx +0 -400
- package/src/components/highlighting/highlightable-content.tsx +0 -240
- package/src/components/highlighting/highlights.ts +0 -207
- package/src/components/highlighting/ranges.ts +0 -304
- package/src/components/highlighting/types.ts +0 -73
- package/src/components/highlighting/ui/highlight-renderer.tsx +0 -172
- package/src/components/highlighting/ui/highlight-set-renderer.tsx +0 -185
- package/src/components/highlighting/ui/highlight-tooltip.tsx +0 -141
- package/src/components/highlighting/ui/highlighting-ui.tsx +0 -143
- package/src/components/highlighting/ui/selection-tracker.tsx +0 -186
- package/src/components/highlighting/ui/types.ts +0 -21
- package/src/components/highlighting/ui/util.ts +0 -165
- package/src/components/highlighting/word-indexer.tsx +0 -152
- package/src/components/hud.tsx +0 -167
- package/src/components/icon.tsx +0 -141
- package/src/components/image-loader.tsx +0 -177
- package/src/components/info-tip/info-tip.tsx +0 -144
- package/src/components/info-tip.tsx +0 -39
- package/src/components/inline-icon.tsx +0 -60
- package/src/components/input-with-examples.tsx +0 -249
- package/src/components/lint.tsx +0 -459
- package/src/components/math-input.tsx +0 -474
- package/src/components/math-output.tsx +0 -134
- package/src/components/multi-button-group.tsx +0 -135
- package/src/components/number-input.tsx +0 -249
- package/src/components/prop-check-box.tsx +0 -79
- package/src/components/range-input.tsx +0 -60
- package/src/components/simple-keypad-input.tsx +0 -88
- package/src/components/sortable.tsx +0 -958
- package/src/components/stub-tag-editor.tsx +0 -53
- package/src/components/svg-image.tsx +0 -779
- package/src/components/tex.tsx +0 -67
- package/src/components/text-input.tsx +0 -129
- package/src/components/text-list-editor.tsx +0 -166
- package/src/components/tooltip.tsx +0 -410
- package/src/components/visibility-observer/__stories__/visibility-observer.stories.tsx +0 -141
- package/src/components/visibility-observer/create-visibility-observer.ts +0 -108
- package/src/components/visibility-observer/get-scroll-parent.ts +0 -46
- package/src/components/visibility-observer/visibility-observer.tsx +0 -124
- package/src/components/zoomable-tex.tsx +0 -78
- package/src/components/zoomable.tsx +0 -304
- package/src/components.ts +0 -15
- package/src/definition-context.tsx +0 -59
- package/src/dependencies.ts +0 -40
- package/src/error-boundary.tsx +0 -70
- package/src/extra-widgets.ts +0 -75
- package/src/hint-renderer.tsx +0 -151
- package/src/hints-renderer.tsx +0 -372
- package/src/icon-paths.ts +0 -119
- package/src/index.ts +0 -171
- package/src/init.ts +0 -56
- package/src/interaction-tracker.ts +0 -62
- package/src/interactive2/__tests__/movable-mock.ts +0 -55
- package/src/interactive2/__tests__/movable-point.test.ts +0 -144
- package/src/interactive2/interactive-util.test.ts +0 -93
- package/src/interactive2/interactive-util.ts +0 -159
- package/src/interactive2/movable-helper-methods.ts +0 -166
- package/src/interactive2/movable-line-options.ts +0 -419
- package/src/interactive2/movable-line.ts +0 -307
- package/src/interactive2/movable-point-options.ts +0 -224
- package/src/interactive2/movable-point.tsx +0 -585
- package/src/interactive2/movable-polygon-options.ts +0 -389
- package/src/interactive2/movable-polygon.ts +0 -360
- package/src/interactive2/movable.test.ts +0 -249
- package/src/interactive2/movable.ts +0 -437
- package/src/interactive2/objective_.ts +0 -79
- package/src/interactive2/types.ts +0 -17
- package/src/interactive2/wrapped-defaults.ts +0 -87
- package/src/interactive2/wrapped-ellipse.ts +0 -94
- package/src/interactive2/wrapped-line.ts +0 -116
- package/src/interactive2/wrapped-path.ts +0 -51
- package/src/interactive2.ts +0 -70
- package/src/item-version.ts +0 -10
- package/src/jipt-paragraphs.ts +0 -49
- package/src/jquery.mobile.vmouse.js +0 -545
- package/src/loading-context.ts +0 -21
- package/src/logging/log.test.ts +0 -39
- package/src/logging/log.ts +0 -97
- package/src/mixins/__tests__/widget-prop-denylist.test.ts +0 -21
- package/src/mixins/changeable.ts +0 -133
- package/src/mixins/editor-jsonify.ts +0 -13
- package/src/mixins/widget-jsonify-deprecated.ts +0 -23
- package/src/mixins/widget-prop-denylist.ts +0 -48
- package/src/multi-items/__stories__/multi-renderer.stories.tsx +0 -83
- package/src/multi-items/__testdata__/multi-renderer.testdata.ts +0 -172
- package/src/multi-items/__tests__/__snapshots__/multi-renderer.test.tsx.snap +0 -1164
- package/src/multi-items/__tests__/items.test.ts +0 -240
- package/src/multi-items/__tests__/multi-renderer.test.tsx +0 -914
- package/src/multi-items/__tests__/prop-type-builders.test.ts +0 -133
- package/src/multi-items/__tests__/shapes.test.ts +0 -43
- package/src/multi-items/__tests__/trees.test.ts +0 -317
- package/src/multi-items/item-types.ts +0 -56
- package/src/multi-items/items.ts +0 -176
- package/src/multi-items/multi-renderer.tsx +0 -569
- package/src/multi-items/prop-type-builders.ts +0 -106
- package/src/multi-items/shape-types.ts +0 -52
- package/src/multi-items/shapes.ts +0 -52
- package/src/multi-items/tree-types.ts +0 -47
- package/src/multi-items/trees.ts +0 -360
- package/src/multi-items.ts +0 -75
- package/src/perseus-api.tsx +0 -188
- package/src/perseus-env.ts +0 -27
- package/src/perseus-error.ts +0 -17
- package/src/perseus-markdown.tsx +0 -405
- package/src/perseus-types.ts +0 -1366
- package/src/perseus-version.ts +0 -9
- package/src/question-paragraph.tsx +0 -34
- package/src/renderability.ts +0 -109
- package/src/renderer.tsx +0 -2000
- package/src/server-item-renderer.tsx +0 -495
- package/src/sigfigs.ts +0 -490
- package/src/styles/articles.less +0 -749
- package/src/styles/constants.ts +0 -94
- package/src/styles/global-constants.ts +0 -343
- package/src/styles/global-styles.ts +0 -306
- package/src/styles/khan-exercise.css +0 -1468
- package/src/styles/media-queries.ts +0 -47
- package/src/styles/perseus-renderer.less +0 -732
- package/src/styles/shared.ts +0 -130
- package/src/styles/util.less +0 -47
- package/src/styles/variables.boostrap.less +0 -277
- package/src/styles/variables.less +0 -56
- package/src/styles/variables.shared.less +0 -340
- package/src/styles/widgets/categorizer.less +0 -38
- package/src/styles/widgets/dropdown.less +0 -3
- package/src/styles/widgets/expression.less +0 -65
- package/src/styles/widgets/graded-group.less +0 -36
- package/src/styles/widgets/grapher.less +0 -12
- package/src/styles/widgets/group.less +0 -19
- package/src/styles/widgets/image.less +0 -54
- package/src/styles/widgets/interactive-graph.less +0 -64
- package/src/styles/widgets/label-image.less +0 -57
- package/src/styles/widgets/matcher.less +0 -8
- package/src/styles/widgets/matrix.less +0 -126
- package/src/styles/widgets/measurer.less +0 -20
- package/src/styles/widgets/orderer.less +0 -98
- package/src/styles/widgets/passage.less +0 -154
- package/src/styles/widgets/plotter.less +0 -31
- package/src/styles/widgets/radio.less +0 -58
- package/src/styles/widgets/reaction-diagram.less +0 -35
- package/src/styles/widgets/sequence.less +0 -5
- package/src/styles/widgets/sortable.less +0 -113
- package/src/styles/widgets/table.less +0 -57
- package/src/styles/widgets/unit.less +0 -15
- package/src/tex-wrangler.ts +0 -182
- package/src/translation-linter.ts +0 -126
- package/src/traversal.ts +0 -138
- package/src/types.ts +0 -513
- package/src/util/a11y.ts +0 -23
- package/src/util/answer-types.test.ts +0 -114
- package/src/util/answer-types.ts +0 -876
- package/src/util/colors.ts +0 -93
- package/src/util/drawing-transform.test.ts +0 -67
- package/src/util/drawing-transform.ts +0 -102
- package/src/util/extract-perseus-data.ts +0 -539
- package/src/util/fix-passage-refs.ts +0 -121
- package/src/util/geometry.test.ts +0 -75
- package/src/util/geometry.ts +0 -312
- package/src/util/graph-bounds.ts +0 -23
- package/src/util/graph-utils.ts +0 -15
- package/src/util/graphie.test.ts +0 -1277
- package/src/util/graphie.ts +0 -1576
- package/src/util/interactive.ts +0 -4174
- package/src/util/interval.ts +0 -4
- package/src/util/katex-preprocess.ts +0 -14
- package/src/util/math.test.ts +0 -11
- package/src/util/math.ts +0 -294
- package/src/util/mobile-native-utils.test.ts +0 -22
- package/src/util/mobile-native-utils.ts +0 -12
- package/src/util/parse-perseus-json.test.ts +0 -10
- package/src/util/parse-perseus-json.ts +0 -13
- package/src/util/react-render.tsx +0 -27
- package/src/util/register-all-widgets-for-testing.ts +0 -13
- package/src/util/scroll-utils.ts +0 -155
- package/src/util/sizing-utils.ts +0 -46
- package/src/util/tex.ts +0 -73
- package/src/util/url-utils.ts +0 -34
- package/src/util.graphie.test.ts +0 -45
- package/src/util.graphie.ts +0 -59
- package/src/util.ts +0 -966
- package/src/version.ts +0 -10
- package/src/widget-container.tsx +0 -199
- package/src/widgets/__stories__/categorizer.stories.tsx +0 -14
- package/src/widgets/__stories__/cs-program.stories.tsx +0 -14
- package/src/widgets/__stories__/definition.stories.tsx +0 -114
- package/src/widgets/__stories__/dropdown.stories.tsx +0 -14
- package/src/widgets/__stories__/explanation.stories.tsx +0 -18
- package/src/widgets/__stories__/expression.stories.tsx +0 -145
- package/src/widgets/__stories__/graded-group-set.stories.tsx +0 -31
- package/src/widgets/__stories__/graded-group.stories.tsx +0 -31
- package/src/widgets/__stories__/grapher.stories.tsx +0 -46
- package/src/widgets/__stories__/group.stories.tsx +0 -14
- package/src/widgets/__stories__/iframe.stories.tsx +0 -14
- package/src/widgets/__stories__/image.stories.tsx +0 -85
- package/src/widgets/__stories__/input-number.stories.tsx +0 -101
- package/src/widgets/__stories__/interaction.stories.tsx +0 -14
- package/src/widgets/__stories__/interactive-graph.stories.tsx +0 -60
- package/src/widgets/__stories__/label-image.stories.tsx +0 -130
- package/src/widgets/__stories__/matcher.stories.tsx +0 -14
- package/src/widgets/__stories__/matrix.stories.tsx +0 -14
- package/src/widgets/__stories__/number-line.stories.tsx +0 -14
- package/src/widgets/__stories__/numeric-input.stories.tsx +0 -105
- package/src/widgets/__stories__/orderer.stories.tsx +0 -18
- package/src/widgets/__stories__/passage-ref.stories.tsx +0 -33
- package/src/widgets/__stories__/passage.stories.tsx +0 -39
- package/src/widgets/__stories__/plotter.stories.tsx +0 -27
- package/src/widgets/__stories__/radio.stories.tsx +0 -86
- package/src/widgets/__stories__/random-widgets.stories.tsx +0 -59
- package/src/widgets/__stories__/sorter.stories.tsx +0 -14
- package/src/widgets/__stories__/test-keypad-context-wrapper.tsx +0 -66
- package/src/widgets/__stories__/unit.stories.tsx +0 -28
- package/src/widgets/__stories__/video-transcript-link.stories.tsx +0 -23
- package/src/widgets/__stories__/video.stories.tsx +0 -22
- package/src/widgets/__testdata__/base-radio.testdata.ts +0 -21
- package/src/widgets/__testdata__/categorizer.testdata.ts +0 -89
- package/src/widgets/__testdata__/cs-program.testdata.ts +0 -27
- package/src/widgets/__testdata__/dropdown.testdata.ts +0 -71
- package/src/widgets/__testdata__/explanation.testdata.ts +0 -85
- package/src/widgets/__testdata__/expression.testdata.ts +0 -198
- package/src/widgets/__testdata__/graded-group-set.testdata.ts +0 -356
- package/src/widgets/__testdata__/graded-group.testdata.ts +0 -77
- package/src/widgets/__testdata__/grapher.testdata.ts +0 -374
- package/src/widgets/__testdata__/group.testdata.ts +0 -153
- package/src/widgets/__testdata__/iframe.testdata.ts +0 -35
- package/src/widgets/__testdata__/image.testdata.ts +0 -36
- package/src/widgets/__testdata__/input-number.testdata.ts +0 -72
- package/src/widgets/__testdata__/interaction.testdata.ts +0 -262
- package/src/widgets/__testdata__/interactive-graph-random.testdata.ts +0 -269
- package/src/widgets/__testdata__/interactive-graph.testdata.ts +0 -644
- package/src/widgets/__testdata__/label-image.testdata.ts +0 -308
- package/src/widgets/__testdata__/matcher.testdata.ts +0 -33
- package/src/widgets/__testdata__/matrix.testdata.ts +0 -28
- package/src/widgets/__testdata__/number-line.testdata.ts +0 -30
- package/src/widgets/__testdata__/numeric-input.testdata.ts +0 -265
- package/src/widgets/__testdata__/orderer.testdata.ts +0 -123
- package/src/widgets/__testdata__/passage-ref.testdata.ts +0 -101
- package/src/widgets/__testdata__/passage.testdata.ts +0 -95
- package/src/widgets/__testdata__/plotter.testdata.ts +0 -36
- package/src/widgets/__testdata__/radio.testdata.ts +0 -324
- package/src/widgets/__testdata__/randomizers.ts +0 -51
- package/src/widgets/__testdata__/sorter.testdata.ts +0 -19
- package/src/widgets/__testdata__/video.testdata.ts +0 -61
- package/src/widgets/__tests__/__snapshots__/categorizer.test.ts.snap +0 -940
- package/src/widgets/__tests__/__snapshots__/cs-program.test.ts.snap +0 -67
- package/src/widgets/__tests__/__snapshots__/definition.test.ts.snap +0 -97
- package/src/widgets/__tests__/__snapshots__/dropdown.test.ts.snap +0 -133
- package/src/widgets/__tests__/__snapshots__/explanation.test.ts.snap +0 -425
- package/src/widgets/__tests__/__snapshots__/graded-group-set-jipt.test.ts.snap +0 -729
- package/src/widgets/__tests__/__snapshots__/graded-group-set.test.ts.snap +0 -339
- package/src/widgets/__tests__/__snapshots__/graded-group.test.ts.snap +0 -801
- package/src/widgets/__tests__/__snapshots__/grapher.test.ts.snap +0 -2673
- package/src/widgets/__tests__/__snapshots__/group.test.tsx.snap +0 -1211
- package/src/widgets/__tests__/__snapshots__/iframe.test.ts.snap +0 -61
- package/src/widgets/__tests__/__snapshots__/image.test.ts.snap +0 -378
- package/src/widgets/__tests__/__snapshots__/input-number.test.ts.snap +0 -495
- package/src/widgets/__tests__/__snapshots__/interaction.test.ts.snap +0 -292
- package/src/widgets/__tests__/__snapshots__/interactive-graph.test.ts.snap +0 -2889
- package/src/widgets/__tests__/__snapshots__/matcher.test.tsx.snap +0 -883
- package/src/widgets/__tests__/__snapshots__/matrix.test.ts.snap +0 -514
- package/src/widgets/__tests__/__snapshots__/number-line.test.ts.snap +0 -814
- package/src/widgets/__tests__/__snapshots__/numeric-input.test.ts.snap +0 -470
- package/src/widgets/__tests__/__snapshots__/orderer.test.ts.snap +0 -243
- package/src/widgets/__tests__/__snapshots__/passage-ref.test.ts.snap +0 -434
- package/src/widgets/__tests__/__snapshots__/passage.test.tsx.snap +0 -1956
- package/src/widgets/__tests__/__snapshots__/plotter.test.tsx.snap +0 -827
- package/src/widgets/__tests__/__snapshots__/radio.test.ts.snap +0 -4237
- package/src/widgets/__tests__/__snapshots__/unit.test.tsx.snap +0 -20
- package/src/widgets/__tests__/__snapshots__/video.test.ts.snap +0 -153
- package/src/widgets/__tests__/categorizer.test.ts +0 -203
- package/src/widgets/__tests__/cs-program.test.ts +0 -43
- package/src/widgets/__tests__/definition.test.ts +0 -136
- package/src/widgets/__tests__/dropdown.test.ts +0 -105
- package/src/widgets/__tests__/explanation.test.ts +0 -198
- package/src/widgets/__tests__/expression-mobile.test.tsx +0 -363
- package/src/widgets/__tests__/expression.test.tsx +0 -484
- package/src/widgets/__tests__/graded-group-set-jipt.test.ts +0 -30
- package/src/widgets/__tests__/graded-group-set.test.ts +0 -288
- package/src/widgets/__tests__/graded-group.test.ts +0 -232
- package/src/widgets/__tests__/grapher.cypress.ts +0 -576
- package/src/widgets/__tests__/grapher.test.ts +0 -33
- package/src/widgets/__tests__/group.test.tsx +0 -510
- package/src/widgets/__tests__/iframe.test.ts +0 -45
- package/src/widgets/__tests__/image.test.ts +0 -62
- package/src/widgets/__tests__/input-number.test.ts +0 -354
- package/src/widgets/__tests__/interaction.test.ts +0 -31
- package/src/widgets/__tests__/interactive-graph.cypress.ts +0 -815
- package/src/widgets/__tests__/interactive-graph.test.ts +0 -106
- package/src/widgets/__tests__/matcher.test.tsx +0 -176
- package/src/widgets/__tests__/matrix.test.ts +0 -82
- package/src/widgets/__tests__/number-line.test.ts +0 -79
- package/src/widgets/__tests__/numeric-input.test.ts +0 -575
- package/src/widgets/__tests__/orderer.test.ts +0 -73
- package/src/widgets/__tests__/passage-ref.test.ts +0 -168
- package/src/widgets/__tests__/passage.test.tsx +0 -224
- package/src/widgets/__tests__/plotter.test.tsx +0 -69
- package/src/widgets/__tests__/radio/base-radio.test.tsx +0 -470
- package/src/widgets/__tests__/radio/choice-icon.test.tsx +0 -90
- package/src/widgets/__tests__/radio/choice.test.tsx +0 -310
- package/src/widgets/__tests__/radio/focus-ring.test.tsx +0 -22
- package/src/widgets/__tests__/radio/option-status.test.tsx +0 -77
- package/src/widgets/__tests__/radio.test.ts +0 -807
- package/src/widgets/__tests__/randomizers.test.ts +0 -53
- package/src/widgets/__tests__/renderQuestion.tsx +0 -101
- package/src/widgets/__tests__/unit.test.tsx +0 -168
- package/src/widgets/__tests__/video.test.ts +0 -69
- package/src/widgets/categorizer.tsx +0 -344
- package/src/widgets/cs-program.tsx +0 -227
- package/src/widgets/definition.tsx +0 -121
- package/src/widgets/deprecated-standin/__stories__/deprecated-standin.stories.tsx +0 -30
- package/src/widgets/deprecated-standin/__tests__/__snapshots__/deprecated-standin.test.ts.snap +0 -70
- package/src/widgets/deprecated-standin/__tests__/deprecated-standin.test.ts +0 -93
- package/src/widgets/deprecated-standin/index.tsx +0 -58
- package/src/widgets/dropdown.tsx +0 -142
- package/src/widgets/explanation.tsx +0 -317
- package/src/widgets/expression.tsx +0 -707
- package/src/widgets/graded-group-answer-bar.tsx +0 -142
- package/src/widgets/graded-group-set.tsx +0 -338
- package/src/widgets/graded-group.tsx +0 -471
- package/src/widgets/grapher/util.tsx +0 -799
- package/src/widgets/grapher.tsx +0 -660
- package/src/widgets/group.tsx +0 -195
- package/src/widgets/iframe.tsx +0 -195
- package/src/widgets/image.tsx +0 -312
- package/src/widgets/input-number.tsx +0 -412
- package/src/widgets/interaction/arrow-picker.tsx +0 -38
- package/src/widgets/interaction/color-picker.tsx +0 -69
- package/src/widgets/interaction/dash-picker.tsx +0 -45
- package/src/widgets/interaction/element-container.tsx +0 -100
- package/src/widgets/interaction.tsx +0 -826
- package/src/widgets/interactive-graph.tsx +0 -2597
- package/src/widgets/label-image/__stories__/answer-choices.stories.tsx +0 -91
- package/src/widgets/label-image/__stories__/answer-pill.stories.tsx +0 -62
- package/src/widgets/label-image/__stories__/marker.stories.tsx +0 -171
- package/src/widgets/label-image/__tests__/answer-pill.test.tsx +0 -75
- package/src/widgets/label-image/__tests__/hide-answers-toggle.test.tsx +0 -39
- package/src/widgets/label-image/answer-choices.tsx +0 -88
- package/src/widgets/label-image/answer-pill.tsx +0 -103
- package/src/widgets/label-image/hide-answers-toggle.tsx +0 -40
- package/src/widgets/label-image/marker.tsx +0 -268
- package/src/widgets/label-image/strings.ts +0 -5
- package/src/widgets/label-image/types.ts +0 -27
- package/src/widgets/label-image.test.ts +0 -928
- package/src/widgets/label-image.tsx +0 -819
- package/src/widgets/lights-puzzle.tsx +0 -359
- package/src/widgets/matcher.tsx +0 -298
- package/src/widgets/matrix.tsx +0 -634
- package/src/widgets/measurer.tsx +0 -222
- package/src/widgets/molecule/__tests__/layout.test.ts +0 -162
- package/src/widgets/molecule/__tests__/parser.test.ts +0 -155
- package/src/widgets/molecule/molecule-drawing.ts +0 -173
- package/src/widgets/molecule/molecule-layout.ts +0 -362
- package/src/widgets/molecule/smiles-parser.ts +0 -296
- package/src/widgets/molecule.tsx +0 -172
- package/src/widgets/number-line.tsx +0 -862
- package/src/widgets/numeric-input.tsx +0 -576
- package/src/widgets/orderer.tsx +0 -786
- package/src/widgets/passage/__tests__/passage-markdown.test.ts +0 -376
- package/src/widgets/passage/passage-markdown.tsx +0 -475
- package/src/widgets/passage-ref-target.tsx +0 -76
- package/src/widgets/passage-ref.tsx +0 -213
- package/src/widgets/passage.tsx +0 -582
- package/src/widgets/plotter.tsx +0 -1194
- package/src/widgets/radio/__stories__/base-radio.stories.tsx +0 -196
- package/src/widgets/radio/__stories__/choice-icon.stories.tsx +0 -166
- package/src/widgets/radio/__stories__/choice-none-above.stories.tsx +0 -40
- package/src/widgets/radio/__stories__/choice.stories.tsx +0 -137
- package/src/widgets/radio/__stories__/focus-ring.stories.tsx +0 -43
- package/src/widgets/radio/__stories__/option-status.stories.tsx +0 -103
- package/src/widgets/radio/base-radio.tsx +0 -511
- package/src/widgets/radio/choice-a11y-text.ts +0 -61
- package/src/widgets/radio/choice-icon/choice-icon.tsx +0 -218
- package/src/widgets/radio/choice-icon/cross-out-line.tsx +0 -51
- package/src/widgets/radio/choice-icon/shared-styles.ts +0 -15
- package/src/widgets/radio/choice-none-above.tsx +0 -56
- package/src/widgets/radio/choice.jsx.fixture.ts +0 -45
- package/src/widgets/radio/choice.tsx +0 -359
- package/src/widgets/radio/focus-ring.tsx +0 -57
- package/src/widgets/radio/option-status.tsx +0 -98
- package/src/widgets/radio/util.test.ts +0 -18
- package/src/widgets/radio/util.ts +0 -31
- package/src/widgets/radio/widget.tsx +0 -520
- package/src/widgets/radio.ts +0 -157
- package/src/widgets/reaction-diagram.tsx +0 -144
- package/src/widgets/sequence.tsx +0 -142
- package/src/widgets/simulator.tsx +0 -829
- package/src/widgets/sorter.tsx +0 -155
- package/src/widgets/table.tsx +0 -393
- package/src/widgets/unit.tsx +0 -374
- package/src/widgets/video-transcript-link.test.tsx +0 -213
- package/src/widgets/video-transcript-link.tsx +0 -84
- package/src/widgets/video.tsx +0 -135
- package/src/widgets.ts +0 -489
- package/src/zoom.ts +0 -555
- package/tsconfig-build.json +0 -26
- package/tsconfig-build.tsbuildinfo +0 -1
|
@@ -1,569 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
2
|
-
/* eslint-disable react/no-unsafe */
|
|
3
|
-
// TODO(mdr): There are some TypeScript errors in this file, and they're tricky, so
|
|
4
|
-
// I'm skipping TypeScript errors for now.
|
|
5
|
-
/**
|
|
6
|
-
* Main entry point to the MultiRenderer render portion.
|
|
7
|
-
*
|
|
8
|
-
* This file exposes the `MultiRenderer` component which performs
|
|
9
|
-
* multi-rendering. To multi-render a question, pass in the content of the item
|
|
10
|
-
* to the `MultiRenderer` component as a props. Then, pass in a function which
|
|
11
|
-
* takes an object of renderers (in the same structure as the content), and
|
|
12
|
-
* return a render tree. The `MultiRenderer` component will allow you to
|
|
13
|
-
* combine scores, serialized state, etc. without having to manually call on
|
|
14
|
-
* each of the functions. It also handles inter-widgets requests between the
|
|
15
|
-
* different renderers.
|
|
16
|
-
*
|
|
17
|
-
* Example:
|
|
18
|
-
*
|
|
19
|
-
* item = {_multi: {
|
|
20
|
-
* left: <content data>,
|
|
21
|
-
* right: [<content data>, <content data>],
|
|
22
|
-
* }}
|
|
23
|
-
* shape = shapes.shape({
|
|
24
|
-
* left: shapes.content,
|
|
25
|
-
* right: shapes.arrayOf(shapes.content),
|
|
26
|
-
* })
|
|
27
|
-
*
|
|
28
|
-
* <MultiRenderer item={item} shape={shape}>
|
|
29
|
-
* {({renderers}) =>
|
|
30
|
-
* <div>
|
|
31
|
-
* <div id="left">{renderers.left}</div>
|
|
32
|
-
* <ul id="right">
|
|
33
|
-
* {renderers.right.map(r => <li>{r}</li>)}
|
|
34
|
-
* </ul>
|
|
35
|
-
* </div>
|
|
36
|
-
* }
|
|
37
|
-
* </MultiRenderer>
|
|
38
|
-
*/
|
|
39
|
-
import * as i18n from "@khanacademy/wonder-blocks-i18n";
|
|
40
|
-
import {StyleSheet, css} from "aphrodite"; // eslint-disable-line import/no-extraneous-dependencies
|
|
41
|
-
import lens from "hubble"; // eslint-disable-line import/no-extraneous-dependencies
|
|
42
|
-
import * as React from "react";
|
|
43
|
-
|
|
44
|
-
import {DependenciesContext} from "../dependencies";
|
|
45
|
-
import HintsRenderer from "../hints-renderer";
|
|
46
|
-
import {Errors, Log} from "../logging/log";
|
|
47
|
-
import Renderer from "../renderer";
|
|
48
|
-
import Util from "../util";
|
|
49
|
-
|
|
50
|
-
import {itemToTree} from "./items";
|
|
51
|
-
import {buildMapper} from "./trees";
|
|
52
|
-
|
|
53
|
-
import type {Item, ContentNode, HintNode, TagsNode} from "./item-types";
|
|
54
|
-
import type {Shape, ArrayShape} from "./shape-types";
|
|
55
|
-
import type {Tree} from "./tree-types";
|
|
56
|
-
import type {TreeMapper, ContentMapper, HintMapper, Path} from "./trees";
|
|
57
|
-
import type {Widget} from "../renderer";
|
|
58
|
-
import type {
|
|
59
|
-
APIOptions,
|
|
60
|
-
FilterCriterion,
|
|
61
|
-
PerseusDependenciesV2,
|
|
62
|
-
PerseusScore,
|
|
63
|
-
} from "../types";
|
|
64
|
-
import type {PropsFor} from "@khanacademy/wonder-blocks-core";
|
|
65
|
-
|
|
66
|
-
type Hint = any; // TODO(mdr)
|
|
67
|
-
type Score = any; // TODO(mdr)
|
|
68
|
-
type SerializedState = any; // TODO(mdr)
|
|
69
|
-
|
|
70
|
-
type RendererProps = PropsFor<typeof Renderer>;
|
|
71
|
-
|
|
72
|
-
type ContentRendererElement = React.ReactElement<any>;
|
|
73
|
-
type HintRendererElement = React.ReactElement<any>;
|
|
74
|
-
type ContentRendererData = {
|
|
75
|
-
makeRenderer: () => ContentRendererElement;
|
|
76
|
-
ref: Renderer | null | undefined;
|
|
77
|
-
};
|
|
78
|
-
type FindWidgetsFunc = (
|
|
79
|
-
criterion: FilterCriterion,
|
|
80
|
-
) => ReadonlyArray<Widget | null | undefined>;
|
|
81
|
-
type HintRendererData = {
|
|
82
|
-
makeRenderer: () => HintRendererElement;
|
|
83
|
-
findExternalWidgets: FindWidgetsFunc | null | undefined;
|
|
84
|
-
ref: null;
|
|
85
|
-
hint: Hint;
|
|
86
|
-
};
|
|
87
|
-
type RendererData = ContentRendererData | HintRendererData;
|
|
88
|
-
// @ts-expect-error - TS2315 - Type 'Tree' is not generic.
|
|
89
|
-
type RendererDataTree = Tree<ContentRendererData, HintRendererData, null>;
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* TODO(somewhatabstract, JIRA-XXXX):
|
|
93
|
-
* Some usage of this type somewhere is causing TypeScript to believe that these
|
|
94
|
-
* elements should be components. Don't know where that is, to fix it up
|
|
95
|
-
* properly. In reality, these types are just too hard to use and aren't
|
|
96
|
-
* really helping us out as I now have to suppress this rather than
|
|
97
|
-
* get value from the type. :(
|
|
98
|
-
*/
|
|
99
|
-
// @ts-expect-error - TS2315 - Type 'Tree' is not generic.
|
|
100
|
-
type RendererTree = Tree<ContentRendererElement, HintRendererElement, null>;
|
|
101
|
-
// @ts-expect-error - TS2315 - Type 'Tree' is not generic.
|
|
102
|
-
type ScoreTree = Tree<Score, null, null>;
|
|
103
|
-
// @ts-expect-error - TS2315 - Type 'Tree' is not generic.
|
|
104
|
-
type SerializedStateTree = Tree<SerializedState, null, null>;
|
|
105
|
-
|
|
106
|
-
type Props = {
|
|
107
|
-
item: Item;
|
|
108
|
-
shape: Shape;
|
|
109
|
-
children: (tree: {renderers: RendererTree}) => React.ReactElement<any>;
|
|
110
|
-
serializedState?: SerializedStateTree | null | undefined;
|
|
111
|
-
onSerializedStateUpdated?: (state: SerializedStateTree) => void;
|
|
112
|
-
onInteractWithWidget?: (id: string) => void;
|
|
113
|
-
apiOptions?: APIOptions;
|
|
114
|
-
reviewMode?: boolean | null | undefined;
|
|
115
|
-
|
|
116
|
-
dependencies: PerseusDependenciesV2;
|
|
117
|
-
};
|
|
118
|
-
type State = {
|
|
119
|
-
// We cache functions to generate renderers and refs in `rendererDataTree`,
|
|
120
|
-
// and change them every time content changes. This isn't just a performance
|
|
121
|
-
// optimization; see `_makeContentRendererData` for more discussion.
|
|
122
|
-
rendererDataTree: RendererDataTree | null | undefined;
|
|
123
|
-
// But, if traversing the tree fails, we store the Error in `renderError`.
|
|
124
|
-
renderError: Error | null | undefined;
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
class MultiRenderer extends React.Component<Props, State> {
|
|
128
|
-
rendererDataTreeMapper: TreeMapper<
|
|
129
|
-
ContentNode,
|
|
130
|
-
ContentRendererData,
|
|
131
|
-
HintNode,
|
|
132
|
-
HintRendererData,
|
|
133
|
-
TagsNode,
|
|
134
|
-
null
|
|
135
|
-
>;
|
|
136
|
-
getRenderersMapper: TreeMapper<
|
|
137
|
-
ContentRendererData,
|
|
138
|
-
ContentRendererElement,
|
|
139
|
-
HintRendererData,
|
|
140
|
-
HintRendererElement,
|
|
141
|
-
null,
|
|
142
|
-
null
|
|
143
|
-
>;
|
|
144
|
-
|
|
145
|
-
constructor(props: Props) {
|
|
146
|
-
super(props);
|
|
147
|
-
|
|
148
|
-
this.rendererDataTreeMapper = buildMapper()
|
|
149
|
-
// @ts-expect-error - TS2345 - Argument of type 'unknown' is not assignable to parameter of type 'ContentNode'.
|
|
150
|
-
.setContentMapper((c, _, p) => this._makeContentRendererData(c, p))
|
|
151
|
-
// @ts-expect-error - TS2345 - Argument of type 'unknown' is not assignable to parameter of type 'HintNode'.
|
|
152
|
-
.setHintMapper((h) => this._makeHintRendererData(h))
|
|
153
|
-
.setTagsMapper((t) => null);
|
|
154
|
-
|
|
155
|
-
// @ts-expect-error - TS2322 - Type 'TreeMapperForLeavesAndCollections<unknown, any, unknown, any, unknown, unknown>' is not assignable to type 'TreeMapper<ContentRendererData, ContentRendererElement, HintRendererData, HintRendererElement, null, null>'.
|
|
156
|
-
this.getRenderersMapper = buildMapper()
|
|
157
|
-
// @ts-expect-error - TS2571 - Object is of type 'unknown'.
|
|
158
|
-
.setContentMapper((c) => c.makeRenderer())
|
|
159
|
-
// @ts-expect-error - TS2571 - Object is of type 'unknown'.
|
|
160
|
-
.setHintMapper((h) => h.makeRenderer())
|
|
161
|
-
.setArrayMapper((renderers, data, shape) =>
|
|
162
|
-
this._annotateRendererArray(
|
|
163
|
-
renderers as any,
|
|
164
|
-
data as any,
|
|
165
|
-
shape,
|
|
166
|
-
),
|
|
167
|
-
);
|
|
168
|
-
|
|
169
|
-
// Keep state in sync with props.
|
|
170
|
-
this.state = this._tryMakeRendererState(this.props);
|
|
171
|
-
}
|
|
172
|
-
/* eslint-enable react/sort-comp */
|
|
173
|
-
|
|
174
|
-
UNSAFE_componentWillReceiveProps(nextProps: Props) {
|
|
175
|
-
// Keep state in sync with props.
|
|
176
|
-
if (nextProps.item !== this.props.item) {
|
|
177
|
-
this.setState(this._tryMakeRendererState(nextProps));
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Attempt to build a State that includes a renderer tree corresponding to
|
|
183
|
-
* the item provided in props. On error, return a state with `renderError`
|
|
184
|
-
* set instead.
|
|
185
|
-
*/
|
|
186
|
-
_tryMakeRendererState(props: Props): State {
|
|
187
|
-
try {
|
|
188
|
-
return {
|
|
189
|
-
rendererDataTree: this._makeRendererDataTree(
|
|
190
|
-
props.item,
|
|
191
|
-
props.shape,
|
|
192
|
-
),
|
|
193
|
-
renderError: null,
|
|
194
|
-
};
|
|
195
|
-
} catch (e: any) {
|
|
196
|
-
Log.error("Error building tree state", Errors.Internal, {
|
|
197
|
-
cause: e,
|
|
198
|
-
});
|
|
199
|
-
return {
|
|
200
|
-
rendererDataTree: null,
|
|
201
|
-
renderError: e,
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
_handleSerializedStateUpdated: (path: Path, newState?: any) => void = (
|
|
207
|
-
path,
|
|
208
|
-
newState,
|
|
209
|
-
) => {
|
|
210
|
-
const {onSerializedStateUpdated} = this.props;
|
|
211
|
-
|
|
212
|
-
if (onSerializedStateUpdated) {
|
|
213
|
-
const oldState = this._getSerializedState(
|
|
214
|
-
this.props.serializedState,
|
|
215
|
-
);
|
|
216
|
-
onSerializedStateUpdated(
|
|
217
|
-
lens(oldState).set(path, newState).freeze(),
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Props that aren't directly used by the MultiRenderer are delegated to
|
|
224
|
-
* the underlying Renderers.
|
|
225
|
-
*/
|
|
226
|
-
_getRendererProps(): RendererProps {
|
|
227
|
-
// `item`, `children`, and others are unused. I'm
|
|
228
|
-
// explicitly pulling them out of `this.props` so I don't pass them to
|
|
229
|
-
// `<Renderer>`. I'm not sure how else to do this.
|
|
230
|
-
const {
|
|
231
|
-
item: _,
|
|
232
|
-
children: __,
|
|
233
|
-
shape: ___,
|
|
234
|
-
serializedState: ____,
|
|
235
|
-
onSerializedStateUpdated: _____,
|
|
236
|
-
...otherProps
|
|
237
|
-
} = this.props;
|
|
238
|
-
return otherProps;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Construct a Renderer and a ref placeholder for the given ContentNode.
|
|
243
|
-
*/
|
|
244
|
-
_makeContentRendererData(
|
|
245
|
-
content: ContentNode,
|
|
246
|
-
path: Path,
|
|
247
|
-
): ContentRendererData {
|
|
248
|
-
// NOTE(emily): The `findExternalWidgets` function here is computed
|
|
249
|
-
// inline and thus changes each time we run this function. If it
|
|
250
|
-
// were to change every render, it would cause the Renderer to
|
|
251
|
-
// re-render a lot more than is necessary. Don't re-compute this
|
|
252
|
-
// element unless it is necessary!
|
|
253
|
-
// HACK(mdr): TypeScript can't prove that this is a ContentRendererData,
|
|
254
|
-
// because of how we awkwardly construct it in order to obtain a
|
|
255
|
-
// circular reference. But it is, I promise.
|
|
256
|
-
const data: any = {ref: null, makeRenderer: null};
|
|
257
|
-
|
|
258
|
-
const refFunc = (e: any) => (data.ref = e);
|
|
259
|
-
const findExternalWidgets = (criterion: any) =>
|
|
260
|
-
this._findWidgets(data, criterion);
|
|
261
|
-
const handleSerializedState = (state: any) =>
|
|
262
|
-
this._handleSerializedStateUpdated(path, state);
|
|
263
|
-
|
|
264
|
-
data.makeRenderer = () => (
|
|
265
|
-
/**
|
|
266
|
-
* TODO(somewhatabstract, JIRA-XXXX):
|
|
267
|
-
* `content` contains props that Renderer doesn't have. However,
|
|
268
|
-
* since the type for `content` is not exact, it's hard to know
|
|
269
|
-
* if this spread is including undocumented props so mapping
|
|
270
|
-
* one to one could introduce a bug. Need to work out the exact
|
|
271
|
-
* type for ContentNode and then fix this.
|
|
272
|
-
*/ // @ts-expect-error - TS2322 - Type '{ ref: (e: any) => any; findExternalWidgets: (criterion: any) => readonly (Widget | null | undefined)[]; serializedState: any; onSerializedStateUpdated: (state: any) => void; __type: "content" | "item"; ... 9 more ...; reviewMode?: boolean | ... 1 more ... | undefined; }' is not assignable to type 'InexactPartial<Pick<Readonly<Props> & Readonly<{ children?: ReactNode; }>, "content" | "images" | "onRender" | "linterContext" | "widgets" | "alwaysUpdate" | ... 6 more ... | "serializedState">>'.
|
|
273
|
-
<Renderer
|
|
274
|
-
{...this._getRendererProps()}
|
|
275
|
-
{...content}
|
|
276
|
-
ref={refFunc}
|
|
277
|
-
findExternalWidgets={findExternalWidgets}
|
|
278
|
-
serializedState={
|
|
279
|
-
this.props.serializedState
|
|
280
|
-
? lens(this.props.serializedState).get(path)
|
|
281
|
-
: null
|
|
282
|
-
}
|
|
283
|
-
onSerializedStateUpdated={handleSerializedState}
|
|
284
|
-
/>
|
|
285
|
-
);
|
|
286
|
-
return data;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* Construct a Renderer for the given HintNode, and keep track of the hint
|
|
291
|
-
* itself for future use, too.
|
|
292
|
-
*/
|
|
293
|
-
_makeHintRendererData(hint: HintNode): HintRendererData {
|
|
294
|
-
// TODO(mdr): Once HintsRenderer supports inter-widget communication,
|
|
295
|
-
// give it a ref. Until then, leave the ref null forever, to avoid
|
|
296
|
-
// confusing the findWidgets functions.
|
|
297
|
-
//
|
|
298
|
-
// NOTE(davidflanagan): As a partial step toward inter-widget
|
|
299
|
-
// communication we're going to pass a findExternalWidgets function
|
|
300
|
-
// (using a dummy data object). This allows passage-ref widgets in
|
|
301
|
-
// hints to use findWidget() to find the passage widgets they reference.
|
|
302
|
-
// Note that this is one-way only, however. It does not allow
|
|
303
|
-
// widgets in the question to find widgets in the hints, for example.
|
|
304
|
-
const findExternalWidgets = (criterion) =>
|
|
305
|
-
this._findWidgets({} as any, criterion);
|
|
306
|
-
|
|
307
|
-
return {
|
|
308
|
-
hint,
|
|
309
|
-
findExternalWidgets, // _annotateRendererArray() needs this
|
|
310
|
-
ref: null,
|
|
311
|
-
makeRenderer: () => (
|
|
312
|
-
<HintsRenderer
|
|
313
|
-
{...this._getRendererProps()}
|
|
314
|
-
findExternalWidgets={findExternalWidgets}
|
|
315
|
-
hints={[hint]}
|
|
316
|
-
/>
|
|
317
|
-
),
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* Construct a tree of interconnected RendererDatas, corresponding to the
|
|
323
|
-
* given item. Called in `_tryMakeRendererState`, in order to store this
|
|
324
|
-
* tree in the component state.
|
|
325
|
-
*/
|
|
326
|
-
_makeRendererDataTree(item: Item, shape: Shape): RendererDataTree {
|
|
327
|
-
const itemTree = itemToTree(item);
|
|
328
|
-
return this.rendererDataTreeMapper.mapTree(itemTree, shape);
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* Return all widgets that meet the given criterion, from all Renderers
|
|
333
|
-
* except the Renderer that triggered this call.
|
|
334
|
-
*
|
|
335
|
-
* This function is provided to each Renderer's `findExternalWidgets` prop,
|
|
336
|
-
* which enables widgets in different Renderers to discover each other and
|
|
337
|
-
* communicate.
|
|
338
|
-
*/
|
|
339
|
-
_findWidgets(
|
|
340
|
-
callingData: RendererData,
|
|
341
|
-
filterCriterion: FilterCriterion,
|
|
342
|
-
): ReadonlyArray<Widget | null | undefined> {
|
|
343
|
-
const results: Array<Widget | null | undefined> = [];
|
|
344
|
-
|
|
345
|
-
this._mapRenderers((data) => {
|
|
346
|
-
if (callingData !== data && data.ref) {
|
|
347
|
-
results.push(...data.ref.findInternalWidgets(filterCriterion));
|
|
348
|
-
}
|
|
349
|
-
});
|
|
350
|
-
|
|
351
|
-
return results;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
/**
|
|
355
|
-
* Copy the renderer tree, apply the given transformation to the leaf nodes
|
|
356
|
-
* and the optional given transformation to the array nodes, and return the
|
|
357
|
-
* result.
|
|
358
|
-
*
|
|
359
|
-
* Used to provide structured data to the call site (the Renderer tree on
|
|
360
|
-
* `render`, the Score tree on `getScores`, etc.), and to traverse the
|
|
361
|
-
* renderer tree even when we disregard the output (like in
|
|
362
|
-
* `_findWidgets`).
|
|
363
|
-
*/
|
|
364
|
-
_mapRenderers<O>(
|
|
365
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
366
|
-
leafMapper: ContentMapper<RendererData, O> &
|
|
367
|
-
HintMapper<RendererData, O>,
|
|
368
|
-
// @ts-expect-error - TS2315 - Type 'Tree' is not generic.
|
|
369
|
-
): Tree<O, O, null> | null | undefined {
|
|
370
|
-
const {rendererDataTree} = this.state;
|
|
371
|
-
|
|
372
|
-
if (!rendererDataTree) {
|
|
373
|
-
return null;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
const mapper = buildMapper()
|
|
377
|
-
.setContentMapper(leafMapper)
|
|
378
|
-
.setHintMapper(leafMapper);
|
|
379
|
-
return mapper.mapTree(rendererDataTree, this.props.shape);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
_scoreFromRef(ref?: Renderer | null): Score {
|
|
383
|
-
if (!ref) {
|
|
384
|
-
return null;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
const [guess, score] = ref.guessAndScore();
|
|
388
|
-
let state;
|
|
389
|
-
if (ref.getSerializedState) {
|
|
390
|
-
state = ref.getSerializedState();
|
|
391
|
-
}
|
|
392
|
-
return Util.keScoreFromPerseusScore(score, guess, state);
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
/**
|
|
396
|
-
* Return a tree in the shape of the multi-item, with scores at each of
|
|
397
|
-
* the content nodes and `null` at the other leaf nodes.
|
|
398
|
-
*/
|
|
399
|
-
getScores(): ScoreTree {
|
|
400
|
-
return this._mapRenderers((data) => this._scoreFromRef(data.ref));
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
/**
|
|
404
|
-
* Return a single composite score for all rendered content nodes.
|
|
405
|
-
* The `guess` is a tree in the shape of the multi-item, with an individual
|
|
406
|
-
* guess at each content node and `null` at the other leaf nodes.
|
|
407
|
-
*/
|
|
408
|
-
score(): Score {
|
|
409
|
-
const scores: Array<PerseusScore> = [];
|
|
410
|
-
const state: Array<
|
|
411
|
-
| any
|
|
412
|
-
| {
|
|
413
|
-
[id: string]: any;
|
|
414
|
-
}
|
|
415
|
-
> = [];
|
|
416
|
-
const guess = this._mapRenderers((data) => {
|
|
417
|
-
if (!data.ref) {
|
|
418
|
-
return null;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
if (data.ref.getSerializedState) {
|
|
422
|
-
state.push(data.ref.getSerializedState());
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
scores.push(data.ref.score());
|
|
426
|
-
return data.ref?.getUserInput();
|
|
427
|
-
});
|
|
428
|
-
|
|
429
|
-
const combinedScore = scores.reduce(Util.combineScores);
|
|
430
|
-
|
|
431
|
-
return Util.keScoreFromPerseusScore(combinedScore, guess, state);
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
/**
|
|
435
|
-
* Return a tree in the shape of the multi-item, with serialized state at
|
|
436
|
-
* each of the content nodes and `null` at the other leaf nodes.
|
|
437
|
-
*
|
|
438
|
-
* If the lastSerializedState argument is supplied, this function will fill
|
|
439
|
-
* in the state of not-currently-rendered content and hint nodes with the
|
|
440
|
-
* values from the previous serialized state. If no lastSerializedState is
|
|
441
|
-
* supplied, `null` will be returned for not-currently-rendered content and
|
|
442
|
-
* hint nodes.
|
|
443
|
-
*/
|
|
444
|
-
_getSerializedState(
|
|
445
|
-
lastSerializedState?: SerializedStateTree,
|
|
446
|
-
): SerializedStateTree {
|
|
447
|
-
return this._mapRenderers((data, _, path) => {
|
|
448
|
-
if (data.ref) {
|
|
449
|
-
return data.ref.getSerializedState();
|
|
450
|
-
}
|
|
451
|
-
if (lastSerializedState) {
|
|
452
|
-
return lens(lastSerializedState).get(path);
|
|
453
|
-
}
|
|
454
|
-
return null;
|
|
455
|
-
});
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
/**
|
|
459
|
-
* Given a tree in the shape of the multi-item, with serialized state at
|
|
460
|
-
* each of the content nodes, restore each state to the corresponding
|
|
461
|
-
* renderer if currently mounted.
|
|
462
|
-
*/
|
|
463
|
-
restoreSerializedState(
|
|
464
|
-
serializedState: SerializedState,
|
|
465
|
-
callback?: () => any,
|
|
466
|
-
) {
|
|
467
|
-
// We want to call our async callback only once all of the childrens'
|
|
468
|
-
// callbacks have run. We add one to this counter before we call out to
|
|
469
|
-
// each renderer and decrement it when it runs our callback.
|
|
470
|
-
let numCallbacks = 0;
|
|
471
|
-
const countCallback = () => {
|
|
472
|
-
numCallbacks--;
|
|
473
|
-
if (callback && numCallbacks === 0) {
|
|
474
|
-
callback();
|
|
475
|
-
}
|
|
476
|
-
};
|
|
477
|
-
|
|
478
|
-
this._mapRenderers((data, _, path) => {
|
|
479
|
-
if (!data.ref) {
|
|
480
|
-
return;
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
const state = lens(serializedState).get(path);
|
|
484
|
-
if (!state) {
|
|
485
|
-
return;
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
numCallbacks++;
|
|
489
|
-
data.ref?.restoreSerializedState(state, countCallback);
|
|
490
|
-
});
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
/**
|
|
494
|
-
* Given an array of renderers, if it happens to be an array of *hint*
|
|
495
|
-
* renderers, then attach a `firstN` method to the array, which allows the
|
|
496
|
-
* layout to render the hints together in one HintsRenderer.
|
|
497
|
-
*/
|
|
498
|
-
_annotateRendererArray(
|
|
499
|
-
renderers: ReadonlyArray<Renderer>,
|
|
500
|
-
rendererDatas: ReadonlyArray<RendererData>,
|
|
501
|
-
shape: ArrayShape,
|
|
502
|
-
): ReadonlyArray<Renderer> {
|
|
503
|
-
if (shape.elementShape.type === "hint") {
|
|
504
|
-
// The shape says that these are HintRendererDatas, even though
|
|
505
|
-
// it's not provable at compile time, so perform a cast.
|
|
506
|
-
const hintRendererDatas: ReadonlyArray<HintRendererData> =
|
|
507
|
-
rendererDatas as any;
|
|
508
|
-
|
|
509
|
-
renderers = [...renderers];
|
|
510
|
-
(renderers as any).firstN = (n: any) => (
|
|
511
|
-
<HintsRenderer
|
|
512
|
-
{...this._getRendererProps()}
|
|
513
|
-
findExternalWidgets={
|
|
514
|
-
hintRendererDatas[0]
|
|
515
|
-
? hintRendererDatas[0].findExternalWidgets
|
|
516
|
-
: undefined
|
|
517
|
-
}
|
|
518
|
-
hints={hintRendererDatas.map((d) => d.hint)}
|
|
519
|
-
hintsVisible={n}
|
|
520
|
-
/>
|
|
521
|
-
);
|
|
522
|
-
}
|
|
523
|
-
return renderers;
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
/**
|
|
527
|
-
* Return a tree in the shape of the multi-item, with a Renderer at each
|
|
528
|
-
* content node and a HintRenderer at each hint node.
|
|
529
|
-
*
|
|
530
|
-
* This is generated by running each of the `makeRenderer` functions at the
|
|
531
|
-
* leaf nodes.
|
|
532
|
-
*/
|
|
533
|
-
_getRenderers(): RendererTree {
|
|
534
|
-
return this.getRenderersMapper.mapTree(
|
|
535
|
-
this.state.rendererDataTree,
|
|
536
|
-
this.props.shape,
|
|
537
|
-
);
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
render(): React.ReactNode {
|
|
541
|
-
if (this.state.renderError) {
|
|
542
|
-
return (
|
|
543
|
-
<div className={css(styles.error)}>
|
|
544
|
-
{i18n.$_("Error rendering: %(error)s", {
|
|
545
|
-
error: String(this.state.renderError),
|
|
546
|
-
})}
|
|
547
|
-
</div>
|
|
548
|
-
);
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
// Pass the renderer tree to the `children` function, which will
|
|
552
|
-
// determine the actual content of this component.
|
|
553
|
-
return (
|
|
554
|
-
<DependenciesContext.Provider value={this.props.dependencies}>
|
|
555
|
-
{this.props.children({
|
|
556
|
-
renderers: this._getRenderers(),
|
|
557
|
-
})}
|
|
558
|
-
</DependenciesContext.Provider>
|
|
559
|
-
);
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
const styles = StyleSheet.create({
|
|
564
|
-
error: {
|
|
565
|
-
color: "red",
|
|
566
|
-
},
|
|
567
|
-
});
|
|
568
|
-
|
|
569
|
-
export default MultiRenderer;
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Utility functions to build React PropTypes for multi-items and shapes.
|
|
3
|
-
*
|
|
4
|
-
* If you're writing new components, though, consider using the Item and Shape
|
|
5
|
-
* types instead.
|
|
6
|
-
*/
|
|
7
|
-
/* instanbul ignore file */
|
|
8
|
-
|
|
9
|
-
import PropTypes from "prop-types";
|
|
10
|
-
|
|
11
|
-
import {Errors} from "../logging/log";
|
|
12
|
-
import {PerseusError} from "../perseus-error";
|
|
13
|
-
|
|
14
|
-
import type {Shape} from "./shape-types";
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* A recursive PropType that accepts Shape objects, and rejects other objects.
|
|
18
|
-
*
|
|
19
|
-
* Usage: `propTypes: {shape: shapePropType}`.
|
|
20
|
-
*/
|
|
21
|
-
export function shapePropType(...args: ReadonlyArray<any>): any {
|
|
22
|
-
const itemShape = PropTypes.oneOfType([
|
|
23
|
-
PropTypes.shape({
|
|
24
|
-
type: PropTypes.oneOf(["content"]).isRequired,
|
|
25
|
-
}).isRequired,
|
|
26
|
-
PropTypes.shape({
|
|
27
|
-
type: PropTypes.oneOf(["hint"]).isRequired,
|
|
28
|
-
}).isRequired,
|
|
29
|
-
PropTypes.shape({
|
|
30
|
-
type: PropTypes.oneOf(["tags"]).isRequired,
|
|
31
|
-
}).isRequired,
|
|
32
|
-
PropTypes.shape({
|
|
33
|
-
type: PropTypes.oneOf(["object"]).isRequired,
|
|
34
|
-
shape: PropTypes.objectOf(shapePropType),
|
|
35
|
-
}).isRequired,
|
|
36
|
-
PropTypes.shape({
|
|
37
|
-
type: PropTypes.oneOf(["array"]).isRequired,
|
|
38
|
-
elementShape: shapePropType,
|
|
39
|
-
}).isRequired,
|
|
40
|
-
]);
|
|
41
|
-
|
|
42
|
-
// @ts-expect-error - TS2556 - A spread argument must either have a tuple type or be passed to a rest parameter.
|
|
43
|
-
return itemShape(...args);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Return a PropType that accepts Items of the given shape, and rejects other
|
|
48
|
-
* objects.
|
|
49
|
-
*
|
|
50
|
-
* Usage: `propTypes: {item: buildPropTypeForShape(myShape)}`
|
|
51
|
-
*/
|
|
52
|
-
export function buildPropTypeForShape(shape: Shape): any {
|
|
53
|
-
return PropTypes.oneOfType([
|
|
54
|
-
PropTypes.shape({
|
|
55
|
-
_multi: buildTreePropTypeForShape(shape),
|
|
56
|
-
}),
|
|
57
|
-
PropTypes.oneOf([null, undefined]),
|
|
58
|
-
]);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Return a PropType that accepts ItemTrees of the given shape, and rejects
|
|
63
|
-
* other objects.
|
|
64
|
-
*/
|
|
65
|
-
function buildTreePropTypeForShape(shape: Shape): any {
|
|
66
|
-
if (shape.type === "content") {
|
|
67
|
-
return PropTypes.shape({
|
|
68
|
-
// TODO(mdr): Remove #LegacyContentNode support.
|
|
69
|
-
__type: PropTypes.oneOf(["content", "item"]).isRequired,
|
|
70
|
-
content: PropTypes.string,
|
|
71
|
-
images: PropTypes.objectOf(PropTypes.any),
|
|
72
|
-
widgets: PropTypes.objectOf(PropTypes.any),
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
if (shape.type === "hint") {
|
|
76
|
-
return PropTypes.shape({
|
|
77
|
-
__type: PropTypes.oneOf(["hint"]).isRequired,
|
|
78
|
-
content: PropTypes.string,
|
|
79
|
-
images: PropTypes.objectOf(PropTypes.any),
|
|
80
|
-
widgets: PropTypes.objectOf(PropTypes.any),
|
|
81
|
-
replace: PropTypes.bool,
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
if (shape.type === "tags") {
|
|
85
|
-
return PropTypes.arrayOf(PropTypes.string.isRequired);
|
|
86
|
-
}
|
|
87
|
-
if (shape.type === "array") {
|
|
88
|
-
const elementPropType = buildTreePropTypeForShape(shape.elementShape);
|
|
89
|
-
return PropTypes.arrayOf(elementPropType.isRequired);
|
|
90
|
-
}
|
|
91
|
-
if (shape.type === "object") {
|
|
92
|
-
const valueShapes = shape.shape;
|
|
93
|
-
const propTypeShape: Record<string, any> = {};
|
|
94
|
-
Object.keys(valueShapes).forEach((key) => {
|
|
95
|
-
propTypeShape[key] = buildTreePropTypeForShape(
|
|
96
|
-
valueShapes[key],
|
|
97
|
-
).isRequired;
|
|
98
|
-
});
|
|
99
|
-
return PropTypes.shape(propTypeShape);
|
|
100
|
-
}
|
|
101
|
-
throw new PerseusError(
|
|
102
|
-
// @ts-expect-error - TS2339 - Property 'type' does not exist on type 'never'.
|
|
103
|
-
`unexpected shape type ${shape.type}`,
|
|
104
|
-
Errors.InvalidInput,
|
|
105
|
-
);
|
|
106
|
-
}
|