@khanacademy/perseus 19.1.4 → 19.1.6
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/graphie.d.ts +9 -1
- package/dist/es/index.js +255 -122
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +261 -126
- package/dist/index.js.map +1 -1
- package/dist/interactive2/interactive-util.d.ts +1 -1
- package/dist/interactive2/movable-point-options.d.ts +5 -4
- package/dist/interactive2/movable.d.ts +90 -13
- package/dist/interactive2/types.d.ts +6 -0
- package/dist/util/graphie.d.ts +5 -0
- package/dist/widgets/expression.d.ts +4 -4
- package/package.json +11 -8
- package/.babelrc.js +0 -8
- package/.eslintrc.js +0 -12
- package/CHANGELOG.md +0 -1422
- 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 -392
- 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 -43
- package/src/interactive2/__tests__/movable-point.test.ts +0 -144
- package/src/interactive2/__tests__/movable.test.ts +0 -157
- 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 -212
- 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.ts +0 -279
- package/src/interactive2/objective_.ts +0 -79
- package/src/interactive2/types.ts +0 -2
- 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 -1566
- package/src/util/interactive.ts +0 -4172
- 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
package/src/widgets/group.tsx
DELETED
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
import {linterContextDefault} from "@khanacademy/perseus-linter";
|
|
2
|
-
import classNames from "classnames";
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
|
|
5
|
-
import * as Changeable from "../mixins/changeable";
|
|
6
|
-
import {ApiOptions} from "../perseus-api";
|
|
7
|
-
import Renderer from "../renderer";
|
|
8
|
-
|
|
9
|
-
import type {PerseusGroupWidgetOptions} from "../perseus-types";
|
|
10
|
-
import type {Widget} from "../renderer";
|
|
11
|
-
import type {
|
|
12
|
-
APIOptions,
|
|
13
|
-
ChangeFn,
|
|
14
|
-
FocusPath,
|
|
15
|
-
PerseusScore,
|
|
16
|
-
WidgetExports,
|
|
17
|
-
WidgetProps,
|
|
18
|
-
} from "../types";
|
|
19
|
-
|
|
20
|
-
type Rubric = PerseusGroupWidgetOptions;
|
|
21
|
-
type RenderProps = PerseusGroupWidgetOptions; // exports has no 'transform'
|
|
22
|
-
type Props = WidgetProps<RenderProps, Rubric>;
|
|
23
|
-
type DefaultProps = {
|
|
24
|
-
content: Props["content"];
|
|
25
|
-
widgets: Props["widgets"];
|
|
26
|
-
images: Props["images"];
|
|
27
|
-
linterContext: Props["linterContext"];
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
class Group extends React.Component<Props> {
|
|
31
|
-
rendererRef: Renderer | null | undefined;
|
|
32
|
-
|
|
33
|
-
static defaultProps: DefaultProps = {
|
|
34
|
-
content: "",
|
|
35
|
-
widgets: {},
|
|
36
|
-
images: {},
|
|
37
|
-
linterContext: linterContextDefault,
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
componentDidMount() {
|
|
41
|
-
// TODO(marcia): See comment in render method about our cyclical
|
|
42
|
-
// numbering scheme. We force another render so that we can annotate
|
|
43
|
-
// the group with the correct number.
|
|
44
|
-
this.forceUpdate();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
change: ChangeFn = (...args) => {
|
|
48
|
-
return Changeable.change.apply(this, args);
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
getUserInput: () => any = () => {
|
|
52
|
-
return this.rendererRef?.getUserInput();
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
getSerializedState: () => any = () => {
|
|
56
|
-
return this.rendererRef?.getSerializedState();
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
restoreSerializedState: (arg1: any, arg2: any) => null = (
|
|
60
|
-
state,
|
|
61
|
-
callback,
|
|
62
|
-
) => {
|
|
63
|
-
this.rendererRef?.restoreSerializedState(state, callback);
|
|
64
|
-
// Tell our renderer that we have no props to change
|
|
65
|
-
// (all our changes were in state):
|
|
66
|
-
return null;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
simpleValidate: (arg1: Rubric) => PerseusScore | null | undefined = (
|
|
70
|
-
rubric,
|
|
71
|
-
) => {
|
|
72
|
-
return this.rendererRef?.score();
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
// Mobile API:
|
|
76
|
-
getInputPaths: () => ReadonlyArray<FocusPath> | null | undefined = () => {
|
|
77
|
-
return this.rendererRef?.getInputPaths();
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
setInputValue: (
|
|
81
|
-
arg1: FocusPath,
|
|
82
|
-
arg2: string,
|
|
83
|
-
arg3: () => unknown,
|
|
84
|
-
) => void = (path, newValue, callback) => {
|
|
85
|
-
return this.rendererRef?.setInputValue(path, newValue, callback);
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
focus: () => boolean | null | undefined = () => {
|
|
89
|
-
return this.rendererRef?.focus();
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
focusInputPath: (arg1: FocusPath) => void = (path) => {
|
|
93
|
-
this.rendererRef?.focusPath(path);
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
blurInputPath: (arg1: FocusPath) => void = (path) => {
|
|
97
|
-
this.rendererRef?.blurPath(path);
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
showRationalesForCurrentlySelectedChoices: () => void = () => {
|
|
101
|
-
this.rendererRef?.showRationalesForCurrentlySelectedChoices();
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
render(): React.ReactNode {
|
|
105
|
-
const apiOptions: APIOptions = {
|
|
106
|
-
...ApiOptions.defaults,
|
|
107
|
-
...this.props.apiOptions,
|
|
108
|
-
// Api Rewriting to support correct onFocus/onBlur
|
|
109
|
-
// events for the mobile API
|
|
110
|
-
onFocusChange: (newFocus, oldFocus) => {
|
|
111
|
-
if (oldFocus) {
|
|
112
|
-
this.props.onBlur(oldFocus);
|
|
113
|
-
}
|
|
114
|
-
if (newFocus) {
|
|
115
|
-
this.props.onFocus(newFocus);
|
|
116
|
-
}
|
|
117
|
-
},
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
// Allow a problem number annotation to be added.
|
|
121
|
-
// This is cyclical and should probably be reconsidered. In order to
|
|
122
|
-
// render the annotation ("Question 3 of 10"), we call findWidgets to
|
|
123
|
-
// figure out our index in the list of all fellow group widgets. On
|
|
124
|
-
// first render, though, we don't exist yet in this list, and so we
|
|
125
|
-
// give ourselves number -1. To combat this, we forceUpdate in
|
|
126
|
-
// componentDidMount so that we can number ourselves properly. But,
|
|
127
|
-
// really we should have a more unidirectional flow. TODO(marcia): fix.
|
|
128
|
-
const groupWidgets: ReadonlyArray<Widget> =
|
|
129
|
-
this.props.findWidgets("group");
|
|
130
|
-
// @ts-expect-error - TS2345 - Argument of type 'this' is not assignable to parameter of type 'Widget'.
|
|
131
|
-
const number: number = groupWidgets.indexOf(this);
|
|
132
|
-
const problemNumComponent = this.props.apiOptions.groupAnnotator(
|
|
133
|
-
number,
|
|
134
|
-
this.props.widgetId,
|
|
135
|
-
);
|
|
136
|
-
|
|
137
|
-
// This is a little strange because the id of the widget that actually
|
|
138
|
-
// changed is going to be lost in favor of the group widget's id. The
|
|
139
|
-
// widgets prop also wasn't actually changed, and this only serves to
|
|
140
|
-
// alert our renderer (our parent) of the fact that some interaction
|
|
141
|
-
// has occurred.
|
|
142
|
-
const onInteractWithWidget = (id) => {
|
|
143
|
-
if (this.rendererRef) {
|
|
144
|
-
this.change("widgets", this.rendererRef.props.widgets);
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
const score = this.rendererRef?.score();
|
|
149
|
-
const isValid = score && score.type !== "invalid";
|
|
150
|
-
const isInvalid = score && score.type === "invalid";
|
|
151
|
-
|
|
152
|
-
// TODO(mdr): Widgets inside this Renderer are not discoverable through
|
|
153
|
-
// the parent Renderer's `findWidgets` function.
|
|
154
|
-
return (
|
|
155
|
-
<div
|
|
156
|
-
className={classNames({
|
|
157
|
-
"perseus-group": true,
|
|
158
|
-
"perseus-group-valid-answer": isValid,
|
|
159
|
-
"perseus-group-invalid-answer": isInvalid,
|
|
160
|
-
})}
|
|
161
|
-
>
|
|
162
|
-
{problemNumComponent}
|
|
163
|
-
<Renderer
|
|
164
|
-
content={this.props.content}
|
|
165
|
-
widgets={this.props.widgets}
|
|
166
|
-
images={this.props.images}
|
|
167
|
-
ref={(ref) => (this.rendererRef = ref)}
|
|
168
|
-
apiOptions={apiOptions}
|
|
169
|
-
findExternalWidgets={this.props.findWidgets}
|
|
170
|
-
reviewMode={!!this.props.reviewModeRubric}
|
|
171
|
-
onInteractWithWidget={onInteractWithWidget}
|
|
172
|
-
linterContext={this.props.linterContext}
|
|
173
|
-
/>
|
|
174
|
-
{/* @ts-expect-error - TS2339 - Property 'icon' does not exist on type 'Readonly<Props> & Readonly<{ children?: ReactNode; }>'. */}
|
|
175
|
-
{this.props.icon && (
|
|
176
|
-
// @ts-expect-error - TS2339 - Property 'icon' does not exist on type 'Readonly<Props> & Readonly<{ children?: ReactNode; }>'.
|
|
177
|
-
<div className="group-icon">{this.props.icon}</div>
|
|
178
|
-
)}
|
|
179
|
-
</div>
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const traverseChildWidgets = function (props: any, traverseRenderer: any): any {
|
|
185
|
-
return {...props, ...traverseRenderer(props)};
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
export default {
|
|
189
|
-
name: "group",
|
|
190
|
-
displayName: "Group (SAT only)",
|
|
191
|
-
widget: Group,
|
|
192
|
-
traverseChildWidgets: traverseChildWidgets,
|
|
193
|
-
hidden: false,
|
|
194
|
-
isLintable: true,
|
|
195
|
-
} as WidgetExports<typeof Group>;
|
package/src/widgets/iframe.tsx
DELETED
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
/* eslint-disable react/forbid-prop-types, react/sort-comp */
|
|
2
|
-
/**
|
|
3
|
-
* This is an iframe widget. It is used for rendering an iframe that
|
|
4
|
-
* then communicates its state via window.postMessage
|
|
5
|
-
* This is useful for embedding arbitrary visualizations/simulations with
|
|
6
|
-
* completed conditions, such as the mazes and games in Algorithms.
|
|
7
|
-
* It's particularly well suited for embedding our ProcessingJS programs,
|
|
8
|
-
* but could also be used for embedding viz's hosted elsewhere.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import $ from "jquery";
|
|
12
|
-
import PropTypes from "prop-types";
|
|
13
|
-
import * as React from "react";
|
|
14
|
-
import _ from "underscore";
|
|
15
|
-
|
|
16
|
-
import {getDependencies} from "../dependencies";
|
|
17
|
-
import * as Changeable from "../mixins/changeable";
|
|
18
|
-
import WidgetJsonifyDeprecated from "../mixins/widget-jsonify-deprecated";
|
|
19
|
-
import Util from "../util";
|
|
20
|
-
|
|
21
|
-
import type {WidgetExports} from "../types";
|
|
22
|
-
|
|
23
|
-
const {updateQueryString} = Util;
|
|
24
|
-
|
|
25
|
-
/* This renders the iframe and handles validation via window.postMessage */
|
|
26
|
-
class Iframe extends React.Component<any> {
|
|
27
|
-
static propTypes = {
|
|
28
|
-
...Changeable.propTypes,
|
|
29
|
-
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
30
|
-
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
31
|
-
url: PropTypes.string,
|
|
32
|
-
settings: PropTypes.array,
|
|
33
|
-
status: PropTypes.oneOf(["incomplete", "incorrect", "correct"]),
|
|
34
|
-
message: PropTypes.string,
|
|
35
|
-
allowFullScreen: PropTypes.bool,
|
|
36
|
-
allowTopNavigation: PropTypes.bool,
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
static defaultProps: any = {
|
|
40
|
-
status: "incomplete",
|
|
41
|
-
// optional message
|
|
42
|
-
message: null,
|
|
43
|
-
allowFullScreen: false,
|
|
44
|
-
allowTopNavigation: false,
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
getUserInput: () => any = () => {
|
|
48
|
-
return WidgetJsonifyDeprecated.getUserInput.call(this);
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
handleMessageEvent: (arg1: any) => void = (e) => {
|
|
52
|
-
// We receive data from the iframe that contains {passed: true/false}
|
|
53
|
-
// and use that to set the status
|
|
54
|
-
// It could also contain an optional message
|
|
55
|
-
let data: Record<string, any> = {};
|
|
56
|
-
try {
|
|
57
|
-
data = JSON.parse(e.originalEvent.data);
|
|
58
|
-
} catch (err: any) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (_.isUndefined(data.testsPassed)) {
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const status = data.testsPassed ? "correct" : "incorrect";
|
|
67
|
-
this.change({
|
|
68
|
-
status: status,
|
|
69
|
-
message: data.message,
|
|
70
|
-
});
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
componentDidMount() {
|
|
74
|
-
$(window).on("message", this.handleMessageEvent);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
componentWillUnmount() {
|
|
78
|
-
$(window).off("message", this.handleMessageEvent);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
render(): React.ReactNode {
|
|
82
|
-
const style = {
|
|
83
|
-
width: String(this.props.width),
|
|
84
|
-
height: String(this.props.height),
|
|
85
|
-
} as const;
|
|
86
|
-
|
|
87
|
-
const {InitialRequestUrl} = getDependencies();
|
|
88
|
-
|
|
89
|
-
// Add "px" to unitless numbers
|
|
90
|
-
Object.entries(style).forEach(([key, value]: [any, any]) => {
|
|
91
|
-
if (!value.endsWith("%") && !value.endsWith("px")) {
|
|
92
|
-
style[key] = value + "px";
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
let url = this.props.url;
|
|
97
|
-
|
|
98
|
-
// If the URL doesnt start with http, it must be a program ID
|
|
99
|
-
if (url && url.length && url.indexOf("http") !== 0) {
|
|
100
|
-
url =
|
|
101
|
-
"https://www.khanacademy.org/computer-programming/program/" +
|
|
102
|
-
url +
|
|
103
|
-
"/embedded?buttons=no&embed=yes&editor=no&author=no";
|
|
104
|
-
url = updateQueryString(url, "width", this.props.width);
|
|
105
|
-
url = updateQueryString(url, "height", this.props.height);
|
|
106
|
-
// Origin is used by output.js in deciding to send messages
|
|
107
|
-
url = updateQueryString(url, "origin", InitialRequestUrl.origin);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Turn array of [{name: "", value: ""}] into object
|
|
111
|
-
if (this.props.settings) {
|
|
112
|
-
const settings: Record<string, any> = {};
|
|
113
|
-
_.each(this.props.settings, function (setting) {
|
|
114
|
-
if (setting.name && setting.value) {
|
|
115
|
-
settings[setting.name] = setting.value;
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
// This becomes available to programs as Program.settings()
|
|
119
|
-
url = updateQueryString(url, "settings", JSON.stringify(settings));
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
let sandboxProperties = "allow-same-origin allow-scripts";
|
|
123
|
-
// TODO(scottgrant): This line is an intentional hack to retain the
|
|
124
|
-
// allow-top-navigation sandbox property. Once our LearnStorm articles
|
|
125
|
-
// have this value checked and published, this line should be removed
|
|
126
|
-
// and replaced with the conditional check below that is commented out.
|
|
127
|
-
// We don't want to break LearnStorm badges, so this will be a two-part
|
|
128
|
-
// deploy.
|
|
129
|
-
sandboxProperties += " allow-top-navigation";
|
|
130
|
-
// if (this.props.allowTopNavigation === true) {
|
|
131
|
-
// sandboxProperties += " allow-top-navigation";
|
|
132
|
-
// }
|
|
133
|
-
|
|
134
|
-
// We sandbox the iframe so that we allowlist only the functionality
|
|
135
|
-
// that we need. This makes it a bit safer in case some content
|
|
136
|
-
// creator "went wild".
|
|
137
|
-
// http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/
|
|
138
|
-
return (
|
|
139
|
-
<iframe
|
|
140
|
-
sandbox={sandboxProperties}
|
|
141
|
-
style={style}
|
|
142
|
-
src={url}
|
|
143
|
-
allowFullScreen={this.props.allowFullScreen}
|
|
144
|
-
/>
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
change: (...args: ReadonlyArray<unknown>) => any = (...args) => {
|
|
149
|
-
// @ts-expect-error - TS2345 - Argument of type 'readonly unknown[]' is not assignable to parameter of type 'any[]'.
|
|
150
|
-
return Changeable.change.apply(this, args);
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
simpleValidate: (arg1: any) => any = (rubric) => {
|
|
154
|
-
// @ts-expect-error - TS2339 - Property 'validate' does not exist on type 'typeof Iframe'.
|
|
155
|
-
return Iframe.validate(this.getUserInput(), rubric);
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* This is the widget's grading function
|
|
161
|
-
*/
|
|
162
|
-
_.extend(Iframe, {
|
|
163
|
-
validate: function (state, rubric) {
|
|
164
|
-
// The iframe can tell us whether it's correct or incorrect,
|
|
165
|
-
// and pass an optional message
|
|
166
|
-
if (state.status === "correct") {
|
|
167
|
-
return {
|
|
168
|
-
type: "points",
|
|
169
|
-
earned: 1,
|
|
170
|
-
total: 1,
|
|
171
|
-
message: state.message || null,
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
if (state.status === "incorrect") {
|
|
175
|
-
return {
|
|
176
|
-
type: "points",
|
|
177
|
-
earned: 0,
|
|
178
|
-
total: 1,
|
|
179
|
-
message: state.message || null,
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
return {
|
|
183
|
-
type: "invalid",
|
|
184
|
-
message: "Keep going, you're not there yet!",
|
|
185
|
-
};
|
|
186
|
-
},
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
export default {
|
|
190
|
-
name: "iframe",
|
|
191
|
-
displayName: "Iframe (deprecated)",
|
|
192
|
-
widget: Iframe,
|
|
193
|
-
// Let's not expose it to all content creators yet
|
|
194
|
-
hidden: true,
|
|
195
|
-
} as WidgetExports<typeof Iframe>;
|
package/src/widgets/image.tsx
DELETED
|
@@ -1,312 +0,0 @@
|
|
|
1
|
-
/* eslint-disable react/sort-comp */
|
|
2
|
-
import {linterContextDefault} from "@khanacademy/perseus-linter";
|
|
3
|
-
import classNames from "classnames";
|
|
4
|
-
import * as React from "react";
|
|
5
|
-
import _ from "underscore";
|
|
6
|
-
|
|
7
|
-
import AssetContext from "../asset-context";
|
|
8
|
-
import SvgImage from "../components/svg-image";
|
|
9
|
-
import * as Changeable from "../mixins/changeable";
|
|
10
|
-
import Renderer from "../renderer";
|
|
11
|
-
|
|
12
|
-
import type {Range, PerseusImageWidgetOptions} from "../perseus-types";
|
|
13
|
-
import type {
|
|
14
|
-
ChangeFn,
|
|
15
|
-
PerseusScore,
|
|
16
|
-
WidgetExports,
|
|
17
|
-
WidgetProps,
|
|
18
|
-
} from "../types";
|
|
19
|
-
|
|
20
|
-
const defaultBoxSize = 400;
|
|
21
|
-
const defaultRange: Range = [0, 10];
|
|
22
|
-
const defaultBackgroundImage = {
|
|
23
|
-
url: null,
|
|
24
|
-
width: 0,
|
|
25
|
-
height: 0,
|
|
26
|
-
} as const;
|
|
27
|
-
|
|
28
|
-
const editorAlignments = ["block", "full-width"];
|
|
29
|
-
|
|
30
|
-
const DEFAULT_ALIGNMENT = "block";
|
|
31
|
-
|
|
32
|
-
type RenderProps = PerseusImageWidgetOptions; // there is no transform as part of exports
|
|
33
|
-
type Rubric = PerseusImageWidgetOptions;
|
|
34
|
-
type UserInput = null;
|
|
35
|
-
|
|
36
|
-
type ExternalProps = WidgetProps<RenderProps, Rubric>;
|
|
37
|
-
|
|
38
|
-
type Props = ExternalProps & {
|
|
39
|
-
alignment: NonNullable<ExternalProps["alignment"]>;
|
|
40
|
-
title: NonNullable<ExternalProps["title"]>;
|
|
41
|
-
range: NonNullable<ExternalProps["range"]>;
|
|
42
|
-
box: NonNullable<ExternalProps["box"]>;
|
|
43
|
-
backgroundImage: NonNullable<ExternalProps["backgroundImage"]>;
|
|
44
|
-
labels: NonNullable<ExternalProps["labels"]>;
|
|
45
|
-
alt: NonNullable<ExternalProps["alt"]>;
|
|
46
|
-
caption: NonNullable<ExternalProps["caption"]>;
|
|
47
|
-
linterContext: NonNullable<ExternalProps["linterContext"]>;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
type DefaultProps = {
|
|
51
|
-
alignment: Props["alignment"];
|
|
52
|
-
title: Props["title"];
|
|
53
|
-
range: Props["range"];
|
|
54
|
-
box: Props["box"];
|
|
55
|
-
backgroundImage: Props["backgroundImage"];
|
|
56
|
-
labels: Props["labels"];
|
|
57
|
-
alt: Props["alt"];
|
|
58
|
-
caption: Props["caption"];
|
|
59
|
-
linterContext: Props["linterContext"];
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
class ImageWidget extends React.Component<Props> {
|
|
63
|
-
static defaultProps: DefaultProps = {
|
|
64
|
-
alignment: DEFAULT_ALIGNMENT,
|
|
65
|
-
title: "",
|
|
66
|
-
range: [defaultRange, defaultRange],
|
|
67
|
-
box: [defaultBoxSize, defaultBoxSize],
|
|
68
|
-
backgroundImage: defaultBackgroundImage,
|
|
69
|
-
labels: [],
|
|
70
|
-
alt: "",
|
|
71
|
-
caption: "",
|
|
72
|
-
linterContext: linterContextDefault,
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
change: ChangeFn = (...args) => {
|
|
76
|
-
return Changeable.change.apply(this, args);
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
getUserInput: () => UserInput = () => {
|
|
80
|
-
return null;
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
simpleValidate: (arg1: Rubric) => PerseusScore = (rubric) => {
|
|
84
|
-
return ImageWidget.validate(this.getUserInput(), rubric);
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
focus: () => void = () => {}; // no-op
|
|
88
|
-
|
|
89
|
-
render(): React.ReactNode {
|
|
90
|
-
let image;
|
|
91
|
-
let alt;
|
|
92
|
-
const {apiOptions} = this.props;
|
|
93
|
-
|
|
94
|
-
const backgroundImage = this.props.backgroundImage;
|
|
95
|
-
|
|
96
|
-
if (backgroundImage.url) {
|
|
97
|
-
const url = backgroundImage.url;
|
|
98
|
-
image = (
|
|
99
|
-
<AssetContext.Consumer>
|
|
100
|
-
{({setAssetStatus}) => (
|
|
101
|
-
<SvgImage
|
|
102
|
-
src={url}
|
|
103
|
-
alt={
|
|
104
|
-
/* alt text is formatted in a sr-only
|
|
105
|
-
div next to the image in addition to
|
|
106
|
-
the alt attribute.
|
|
107
|
-
If there is no alt text at all,
|
|
108
|
-
we don't put an alt attribute on
|
|
109
|
-
the image, so that screen readers
|
|
110
|
-
know there's something they can't
|
|
111
|
-
read there :(.
|
|
112
|
-
NOTE: React <=0.13 (maybe later)
|
|
113
|
-
has a bug where it won't ever
|
|
114
|
-
remove an attribute, so if this
|
|
115
|
-
alt node is ever defined it's
|
|
116
|
-
not removed. This is sort of
|
|
117
|
-
dangerous, but we usually re-key
|
|
118
|
-
new renderers so that they're
|
|
119
|
-
rendered from scratch anyways,
|
|
120
|
-
so this shouldn't be a problem
|
|
121
|
-
in practice right now, although
|
|
122
|
-
it will exhibit weird behaviour
|
|
123
|
-
while editing. */
|
|
124
|
-
this.props.alt
|
|
125
|
-
}
|
|
126
|
-
overrideAriaHidden={true}
|
|
127
|
-
width={backgroundImage.width}
|
|
128
|
-
height={backgroundImage.height}
|
|
129
|
-
preloader={apiOptions.imagePreloader}
|
|
130
|
-
extraGraphie={{
|
|
131
|
-
box: this.props.box,
|
|
132
|
-
range: this.props.range,
|
|
133
|
-
labels: this.props.labels,
|
|
134
|
-
}}
|
|
135
|
-
trackInteraction={this.props.trackInteraction}
|
|
136
|
-
zoomToFullSizeOnMobile={apiOptions.isMobile}
|
|
137
|
-
constrainHeight={apiOptions.isMobile}
|
|
138
|
-
allowFullBleed={apiOptions.isMobile}
|
|
139
|
-
setAssetStatus={setAssetStatus}
|
|
140
|
-
/>
|
|
141
|
-
)}
|
|
142
|
-
</AssetContext.Consumer>
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (this.props.alt) {
|
|
147
|
-
alt = (
|
|
148
|
-
<span className="perseus-sr-only">
|
|
149
|
-
<Renderer
|
|
150
|
-
content={this.props.alt}
|
|
151
|
-
apiOptions={apiOptions}
|
|
152
|
-
linterContext={this.props.linterContext}
|
|
153
|
-
/>
|
|
154
|
-
</span>
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// For mobile we combine an image's title and caption.
|
|
159
|
-
if (apiOptions.isMobile) {
|
|
160
|
-
let titleAndCaption;
|
|
161
|
-
|
|
162
|
-
if (this.props.title || this.props.caption) {
|
|
163
|
-
let title = this.props.title;
|
|
164
|
-
|
|
165
|
-
// Bold the title, and make it the first sentence of the
|
|
166
|
-
// caption.
|
|
167
|
-
if (title) {
|
|
168
|
-
// We add a period to separate the title from the caption
|
|
169
|
-
// (if it exists), unless the title already ends with a
|
|
170
|
-
// punctuation symbol (whitespace ignored). Copied from
|
|
171
|
-
// webapp: https://github.com/Khan/webapp/blob/6e930637edb65696d0749ea0f7558214aee32b4e/javascript/tutorial-shared-package/components/content-description.jsx#L80
|
|
172
|
-
// TODO(charlie): Internationalize this check, and the
|
|
173
|
-
// delimiter that is being inserted.
|
|
174
|
-
if (this.props.caption && !/[.?!"']\s*$/.test(title)) {
|
|
175
|
-
title += ".";
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
title = `**${title}** `;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
const className = classNames({
|
|
182
|
-
"perseus-image-caption": true,
|
|
183
|
-
"has-title": !!title,
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
// Caption is left-aligned within a container that's centered
|
|
187
|
-
// below the image, with these width constraints:
|
|
188
|
-
//
|
|
189
|
-
// 1. Size caption to width of the image on-screen.
|
|
190
|
-
// 2. ... but constrain its width to a range based on the
|
|
191
|
-
// device to optimize readability - e.g. [320px, 450px] for
|
|
192
|
-
// phones.
|
|
193
|
-
// 3. ... unless the image is floated, in which case we don't
|
|
194
|
-
// want the caption to overflow the image size.
|
|
195
|
-
//
|
|
196
|
-
// TODO(david): If caption is only 1 line long, center-align
|
|
197
|
-
// the text.
|
|
198
|
-
const alignment = this.props.alignment;
|
|
199
|
-
const isImageFullWidth =
|
|
200
|
-
alignment === "block" || alignment === "full-width";
|
|
201
|
-
|
|
202
|
-
// This minWidth takes precedence over minWidth applied via
|
|
203
|
-
// Aphrodite.
|
|
204
|
-
const minWidth = isImageFullWidth ? null : "0 !important";
|
|
205
|
-
|
|
206
|
-
titleAndCaption = (
|
|
207
|
-
<figcaption
|
|
208
|
-
className={className}
|
|
209
|
-
style={{
|
|
210
|
-
maxWidth: backgroundImage.width,
|
|
211
|
-
}}
|
|
212
|
-
>
|
|
213
|
-
<div
|
|
214
|
-
style={{
|
|
215
|
-
// @ts-expect-error - TS2322 - Type 'string | null' is not assignable to type 'MinWidth<string | number> | undefined'.
|
|
216
|
-
minWidth: minWidth,
|
|
217
|
-
}}
|
|
218
|
-
>
|
|
219
|
-
<Renderer
|
|
220
|
-
content={title + this.props.caption}
|
|
221
|
-
apiOptions={apiOptions}
|
|
222
|
-
linterContext={this.props.linterContext}
|
|
223
|
-
/>
|
|
224
|
-
</div>
|
|
225
|
-
</figcaption>
|
|
226
|
-
);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
return (
|
|
230
|
-
<figure
|
|
231
|
-
className="perseus-image-widget"
|
|
232
|
-
style={{
|
|
233
|
-
maxWidth: backgroundImage.width,
|
|
234
|
-
}}
|
|
235
|
-
>
|
|
236
|
-
{image}
|
|
237
|
-
{alt}
|
|
238
|
-
{titleAndCaption}
|
|
239
|
-
</figure>
|
|
240
|
-
);
|
|
241
|
-
}
|
|
242
|
-
let title;
|
|
243
|
-
let caption;
|
|
244
|
-
|
|
245
|
-
if (this.props.title) {
|
|
246
|
-
title = (
|
|
247
|
-
<div className="perseus-image-title">
|
|
248
|
-
<Renderer
|
|
249
|
-
content={this.props.title}
|
|
250
|
-
apiOptions={apiOptions}
|
|
251
|
-
linterContext={this.props.linterContext}
|
|
252
|
-
/>
|
|
253
|
-
</div>
|
|
254
|
-
);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
if (this.props.caption) {
|
|
258
|
-
caption = (
|
|
259
|
-
<figcaption
|
|
260
|
-
className="perseus-image-caption"
|
|
261
|
-
style={{
|
|
262
|
-
maxWidth: backgroundImage.width,
|
|
263
|
-
}}
|
|
264
|
-
>
|
|
265
|
-
<Renderer
|
|
266
|
-
content={this.props.caption}
|
|
267
|
-
apiOptions={apiOptions}
|
|
268
|
-
linterContext={this.props.linterContext}
|
|
269
|
-
/>
|
|
270
|
-
</figcaption>
|
|
271
|
-
);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
return (
|
|
275
|
-
<figure
|
|
276
|
-
className="perseus-image-widget"
|
|
277
|
-
style={{
|
|
278
|
-
maxWidth: backgroundImage.width,
|
|
279
|
-
}}
|
|
280
|
-
>
|
|
281
|
-
{title}
|
|
282
|
-
{image}
|
|
283
|
-
{alt}
|
|
284
|
-
{caption}
|
|
285
|
-
</figure>
|
|
286
|
-
);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
static validate(userInput: UserInput, rubric: Rubric): PerseusScore {
|
|
290
|
-
return {
|
|
291
|
-
type: "points",
|
|
292
|
-
earned: 0,
|
|
293
|
-
total: 0,
|
|
294
|
-
message: null,
|
|
295
|
-
};
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
export default {
|
|
300
|
-
name: "image",
|
|
301
|
-
// This widget's accessibility depends on its contents: if the image has
|
|
302
|
-
// has a background but no alt text, it is not accessible
|
|
303
|
-
accessible: (widgetOptions: PerseusImageWidgetOptions): boolean => {
|
|
304
|
-
const bgImage = widgetOptions.backgroundImage;
|
|
305
|
-
return !(bgImage && bgImage.url && !widgetOptions.alt);
|
|
306
|
-
},
|
|
307
|
-
defaultAlignment: DEFAULT_ALIGNMENT,
|
|
308
|
-
supportedAlignments: editorAlignments,
|
|
309
|
-
displayName: "Image",
|
|
310
|
-
widget: ImageWidget,
|
|
311
|
-
isLintable: true,
|
|
312
|
-
} as WidgetExports<typeof ImageWidget>;
|