@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
package/src/widgets/video.tsx
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This is a video widget for embedding videos in articles.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import {View} from "@khanacademy/wonder-blocks-core";
|
|
6
|
-
import * as i18n from "@khanacademy/wonder-blocks-i18n";
|
|
7
|
-
import * as React from "react";
|
|
8
|
-
import _ from "underscore";
|
|
9
|
-
|
|
10
|
-
import FixedToResponsive from "../components/fixed-to-responsive";
|
|
11
|
-
import {getDependencies} from "../dependencies";
|
|
12
|
-
import * as Changeable from "../mixins/changeable";
|
|
13
|
-
import a11y from "../util/a11y";
|
|
14
|
-
|
|
15
|
-
import VideoTranscriptLink from "./video-transcript-link";
|
|
16
|
-
|
|
17
|
-
import type {PerseusVideoWidgetOptions} from "../perseus-types";
|
|
18
|
-
import type {PerseusScore, WidgetExports, WidgetProps} from "../types";
|
|
19
|
-
|
|
20
|
-
// Current default is 720p, based on the typical videos we upload currently
|
|
21
|
-
const DEFAULT_WIDTH = 1280;
|
|
22
|
-
const DEFAULT_HEIGHT = 720;
|
|
23
|
-
|
|
24
|
-
const KA_EMBED = "{host}/embed_video?slug={slug}" + "&internal_video_only=1";
|
|
25
|
-
const IS_URL = /^https?:\/\//;
|
|
26
|
-
const IS_KA_SITE = /(khanacademy\.org|localhost)/;
|
|
27
|
-
const IS_VIMEO = /(vimeo\.com)/;
|
|
28
|
-
|
|
29
|
-
type UserInput = null;
|
|
30
|
-
type Rubric = PerseusVideoWidgetOptions;
|
|
31
|
-
type RenderProps = PerseusVideoWidgetOptions; // exports has no 'transform'
|
|
32
|
-
type Props = WidgetProps<RenderProps, Rubric> & {
|
|
33
|
-
alignment: string; // Where does this get set?
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Video renderer.
|
|
38
|
-
*/
|
|
39
|
-
class Video extends React.Component<Props> {
|
|
40
|
-
/**
|
|
41
|
-
* This is the widget's grading function.
|
|
42
|
-
* Points for videos are tallied by the embedded video itself, in the case
|
|
43
|
-
* of Khan Academy videos.
|
|
44
|
-
*/
|
|
45
|
-
static validate(userInput: UserInput, rubric: Rubric): PerseusScore {
|
|
46
|
-
return {
|
|
47
|
-
type: "points",
|
|
48
|
-
earned: 0,
|
|
49
|
-
total: 0,
|
|
50
|
-
message: null,
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
getUserInput: () => undefined | null | undefined = () => {
|
|
55
|
-
return null;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
simpleValidate: (arg1: Rubric) => PerseusScore = (rubric) => {
|
|
59
|
-
return Video.validate(null, rubric);
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
change: (...args: ReadonlyArray<unknown>) => any = (...args) => {
|
|
63
|
-
// @ts-expect-error - TS2345 - Argument of type 'readonly unknown[]' is not assignable to parameter of type 'any[]'.
|
|
64
|
-
return Changeable.change.apply(this, args);
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
render(): React.ReactNode {
|
|
68
|
-
const {InitialRequestUrl} = getDependencies();
|
|
69
|
-
|
|
70
|
-
const location = this.props.location;
|
|
71
|
-
if (!location) {
|
|
72
|
-
return <div />;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
let url;
|
|
76
|
-
|
|
77
|
-
if (IS_URL.test(location)) {
|
|
78
|
-
url = location;
|
|
79
|
-
if (IS_VIMEO.test(url)) {
|
|
80
|
-
// If this is a vimeo video, we need to add the query string
|
|
81
|
-
// parameter "dnt" so that analytics/tracking cookies aren't set.
|
|
82
|
-
// https://help.vimeo.com/hc/en-us/articles/12426260232977-Player-parameters-overview
|
|
83
|
-
if (url.indexOf("?") === -1) {
|
|
84
|
-
url += "?dnt=1";
|
|
85
|
-
} else {
|
|
86
|
-
url += "&dnt=1";
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
} else {
|
|
90
|
-
url = KA_EMBED.replace("{slug}", location);
|
|
91
|
-
let embedHostname = "https://www.khanacademy.org";
|
|
92
|
-
if (IS_KA_SITE.test(InitialRequestUrl.host)) {
|
|
93
|
-
embedHostname = InitialRequestUrl.origin;
|
|
94
|
-
}
|
|
95
|
-
url = url.replace("{host}", embedHostname);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return (
|
|
99
|
-
<View>
|
|
100
|
-
<FixedToResponsive
|
|
101
|
-
width={DEFAULT_WIDTH}
|
|
102
|
-
height={DEFAULT_HEIGHT}
|
|
103
|
-
// The key is here for the benefit of the editor, to ensure that
|
|
104
|
-
// any changes cause a re-rendering of the frame.
|
|
105
|
-
key={location + this.props.alignment}
|
|
106
|
-
>
|
|
107
|
-
<View style={a11y.srOnly}>
|
|
108
|
-
{i18n._("Khan Academy video wrapper")}
|
|
109
|
-
</View>
|
|
110
|
-
|
|
111
|
-
<iframe
|
|
112
|
-
// TODO(joshuan): Consider not using iframes when we're
|
|
113
|
-
// loading this from webapp. This iframe is problematic
|
|
114
|
-
// for screenreaders.
|
|
115
|
-
className="perseus-video-widget"
|
|
116
|
-
sandbox="allow-same-origin allow-scripts"
|
|
117
|
-
width={DEFAULT_WIDTH}
|
|
118
|
-
height={DEFAULT_HEIGHT}
|
|
119
|
-
src={url}
|
|
120
|
-
allowFullScreen={true}
|
|
121
|
-
/>
|
|
122
|
-
</FixedToResponsive>
|
|
123
|
-
<VideoTranscriptLink location={location} />
|
|
124
|
-
</View>
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export default {
|
|
130
|
-
name: "video",
|
|
131
|
-
displayName: "Video",
|
|
132
|
-
defaultAlignment: "block",
|
|
133
|
-
supportedAlignments: ["block", "float-left", "float-right", "full-width"],
|
|
134
|
-
widget: Video,
|
|
135
|
-
} as WidgetExports<typeof Video>;
|
package/src/widgets.ts
DELETED
|
@@ -1,489 +0,0 @@
|
|
|
1
|
-
import _ from "underscore";
|
|
2
|
-
|
|
3
|
-
import {Errors, Log} from "./logging/log";
|
|
4
|
-
import {PerseusError} from "./perseus-error";
|
|
5
|
-
|
|
6
|
-
import type {PerseusWidget} from "./perseus-types";
|
|
7
|
-
import type {
|
|
8
|
-
Alignment,
|
|
9
|
-
Tracking,
|
|
10
|
-
Version,
|
|
11
|
-
WidgetExports,
|
|
12
|
-
WidgetTransform,
|
|
13
|
-
} from "./types";
|
|
14
|
-
import type * as React from "react";
|
|
15
|
-
|
|
16
|
-
const DEFAULT_ALIGNMENT = "block";
|
|
17
|
-
// NOTE(kevinb): "default" is not one in `validAlignments`.
|
|
18
|
-
const DEFAULT_SUPPORTED_ALIGNMENTS = ["default"];
|
|
19
|
-
const DEFAULT_STATIC = false;
|
|
20
|
-
const DEFAULT_TRACKING = "";
|
|
21
|
-
const DEFAULT_LINTABLE = false;
|
|
22
|
-
|
|
23
|
-
type Editor = any;
|
|
24
|
-
|
|
25
|
-
const widgets: {
|
|
26
|
-
[key: string]: WidgetExports;
|
|
27
|
-
} = {};
|
|
28
|
-
const editors: Record<string, any> = {};
|
|
29
|
-
|
|
30
|
-
// Widgets must be registered to avoid circular dependencies with the
|
|
31
|
-
// core Editor and Renderer components.
|
|
32
|
-
// TODO(jeremy): The widget name is already embedded in the WidgetExports type
|
|
33
|
-
// so could we drop the `name` parameter here?
|
|
34
|
-
export const registerWidget = (name: string, widget: WidgetExports) => {
|
|
35
|
-
widgets[name] = widget;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export const registerWidgets = (widgets: ReadonlyArray<WidgetExports>) => {
|
|
39
|
-
widgets.forEach((widget) => {
|
|
40
|
-
registerWidget(widget.name, widget);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
validateAlignments();
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
*
|
|
48
|
-
* @param name - the widget that you are trying to replace
|
|
49
|
-
* @param replacementName - the name of the widget that takes its place
|
|
50
|
-
*
|
|
51
|
-
* e.g. replaceWidget("transformer", "deprecated-standin") will make it so the
|
|
52
|
-
* transformer widget is replaced by the always correct widget
|
|
53
|
-
*/
|
|
54
|
-
export const replaceWidget = (name: string, replacementName: string) => {
|
|
55
|
-
const substituteWidget = widgets[replacementName];
|
|
56
|
-
|
|
57
|
-
// If the replacement widget isn't found, we need to throw. Otherwise after
|
|
58
|
-
// removing the deprecated widget, we'll have data asking for a widget type
|
|
59
|
-
// that doesn't exist at all.
|
|
60
|
-
if (!substituteWidget) {
|
|
61
|
-
const errorMsg = `Failed to replace ${name} with ${replacementName}`;
|
|
62
|
-
throw new PerseusError(errorMsg, Errors.Internal);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
registerWidget(name, substituteWidget);
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export const registerEditors = (editorsToRegister: ReadonlyArray<Editor>) => {
|
|
69
|
-
editorsToRegister.forEach((editor) => {
|
|
70
|
-
if (!editor.widgetName) {
|
|
71
|
-
throw new PerseusError(
|
|
72
|
-
`Editor ${editor.displayName} doesn't have a widgetName property`,
|
|
73
|
-
Errors.Internal,
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
editors[editor.widgetName] = editor;
|
|
77
|
-
});
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
*
|
|
82
|
-
* @param name - the widget that you are trying to replace
|
|
83
|
-
* @param replacementName - the name of the widget that takes its place
|
|
84
|
-
*
|
|
85
|
-
* e.g. replaceEditor("transformer", "always-correct") will make it so the
|
|
86
|
-
* transformer widget is replaced by the always correct widget
|
|
87
|
-
*/
|
|
88
|
-
export const replaceEditor = (name: string, replacementName: string) => {
|
|
89
|
-
const substituteEditor = editors[replacementName];
|
|
90
|
-
|
|
91
|
-
if (!substituteEditor && Log) {
|
|
92
|
-
const errorMsg = `Failed to replace editor ${name} with ${replacementName}`;
|
|
93
|
-
Log.error(errorMsg, Errors.Internal);
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
editors[name] = substituteEditor;
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
export const getWidget = (
|
|
101
|
-
name: string,
|
|
102
|
-
): React.ComponentType<any> | null | undefined => {
|
|
103
|
-
// TODO(alex): Consider referring to these as renderers to avoid
|
|
104
|
-
// overloading "widget"
|
|
105
|
-
if (!_.has(widgets, name)) {
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Allow widgets to specify a widget directly or via a function
|
|
110
|
-
if (widgets[name].getWidget) {
|
|
111
|
-
// @ts-expect-error - TS2722 - Cannot invoke an object which is possibly 'undefined'.
|
|
112
|
-
return widgets[name].getWidget();
|
|
113
|
-
}
|
|
114
|
-
return widgets[name].widget;
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
export const getEditor = (name: string): Editor | null | undefined => {
|
|
118
|
-
return _.has(editors, name) ? editors[name] : null;
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
export const getTransform = (
|
|
122
|
-
name: string,
|
|
123
|
-
): WidgetTransform | null | undefined => {
|
|
124
|
-
return _.has(widgets, name) ? widgets[name].transform || _.identity : null;
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
export const getVersion = (name: string): Version | undefined => {
|
|
128
|
-
const widgetInfo = widgets[name];
|
|
129
|
-
if (widgetInfo) {
|
|
130
|
-
return widgets[name].version || {major: 0, minor: 0};
|
|
131
|
-
}
|
|
132
|
-
return;
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
export const getVersionVector = (): {
|
|
136
|
-
[key: string]: Version;
|
|
137
|
-
} => {
|
|
138
|
-
const version: Record<string, any> = {};
|
|
139
|
-
_.each(_.keys(widgets), function (name) {
|
|
140
|
-
version[name] = getVersion(name);
|
|
141
|
-
});
|
|
142
|
-
return version;
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
export const getPublicWidgets = (): ReadonlyArray<WidgetExports> => {
|
|
146
|
-
// TODO(alex): Update underscore.js so that _.pick can take a function.
|
|
147
|
-
// @ts-expect-error - TS2740 - Type 'Pick<{ [key: string]: Readonly<{ name: string; displayName: string; getWidget?: (() => ComponentType<any>) | undefined; accessible?: boolean | ((props: any) => boolean) | undefined; hidden?: boolean | undefined; ... 10 more ...; widget: ComponentType<...>; }>; }, string>' is missing the following properties from type 'readonly Readonly<{ name: string; displayName: string; getWidget?: (() => ComponentType<any>) | undefined; accessible?: boolean | ((props: any) => boolean) | undefined; hidden?: boolean | undefined; ... 10 more ...; widget: ComponentType<...>; }>[]': length, concat, join, slice, and 18 more.
|
|
148
|
-
return _.pick(
|
|
149
|
-
widgets,
|
|
150
|
-
// @ts-expect-error - TS2345 - Argument of type '(name: string) => boolean | undefined' is not assignable to parameter of type 'Iteratee<string[], boolean, string>'.
|
|
151
|
-
_.reject(_.keys(widgets), function (name) {
|
|
152
|
-
return widgets[name].hidden;
|
|
153
|
-
}),
|
|
154
|
-
);
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
export const isAccessible = (widgetInfo: PerseusWidget): boolean => {
|
|
158
|
-
const accessible = widgets[widgetInfo.type].accessible;
|
|
159
|
-
if (typeof accessible === "function") {
|
|
160
|
-
return accessible(widgetInfo.options);
|
|
161
|
-
}
|
|
162
|
-
return !!accessible;
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
export const getAllWidgetTypes = (): ReadonlyArray<string> => {
|
|
166
|
-
return _.keys(widgets);
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
export const upgradeWidgetInfoToLatestVersion = (
|
|
170
|
-
oldWidgetInfo: PerseusWidget,
|
|
171
|
-
): PerseusWidget => {
|
|
172
|
-
const type = oldWidgetInfo.type;
|
|
173
|
-
// NOTE(jeremy): This looks like it could be replaced by fixing types so
|
|
174
|
-
// that `type` is non-optional. But we're seeing this in Sentry today so I
|
|
175
|
-
// suspect we have legacy data (potentially unpublished) and we should
|
|
176
|
-
// figure that out before depending solely on types.
|
|
177
|
-
if (!_.isString(type)) {
|
|
178
|
-
throw new PerseusError(
|
|
179
|
-
"widget type must be a string, but was: " + type,
|
|
180
|
-
Errors.Internal,
|
|
181
|
-
);
|
|
182
|
-
}
|
|
183
|
-
const widgetExports = widgets[type];
|
|
184
|
-
|
|
185
|
-
if (widgetExports == null) {
|
|
186
|
-
// If we have a widget that isn't registered, we can't upgrade it
|
|
187
|
-
// TODO(aria): Figure out what the best thing to do here would be
|
|
188
|
-
return oldWidgetInfo;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// Unversioned widgets (pre-July 2014) are all implicitly 0.0
|
|
192
|
-
const initialVersion = oldWidgetInfo.version || {major: 0, minor: 0};
|
|
193
|
-
const latestVersion = widgetExports.version || {major: 0, minor: 0};
|
|
194
|
-
|
|
195
|
-
// If the widget version is later than what we understand (major
|
|
196
|
-
// version is higher than latest, or major versions are equal and minor
|
|
197
|
-
// version is higher than latest), don't perform any upgrades.
|
|
198
|
-
if (
|
|
199
|
-
initialVersion.major > latestVersion.major ||
|
|
200
|
-
(initialVersion.major === latestVersion.major &&
|
|
201
|
-
initialVersion.minor > latestVersion.minor)
|
|
202
|
-
) {
|
|
203
|
-
return oldWidgetInfo;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// We do a clone here so that it's safe to mutate the input parameter
|
|
207
|
-
// in propUpgrades functions (which I will probably accidentally do at
|
|
208
|
-
// some point, and we would like to not break when that happens).
|
|
209
|
-
let newEditorProps = _.clone(oldWidgetInfo.options) || {};
|
|
210
|
-
|
|
211
|
-
const upgradePropsMap = widgetExports.propUpgrades || {};
|
|
212
|
-
|
|
213
|
-
// Empty props usually mean a newly created widget by the editor,
|
|
214
|
-
// and are always considerered up-to-date.
|
|
215
|
-
// Mostly, we'd rather not run upgrade functions on props that are
|
|
216
|
-
// not complete.
|
|
217
|
-
if (_.keys(newEditorProps).length !== 0) {
|
|
218
|
-
// We loop through all the versions after the current version of
|
|
219
|
-
// the loaded widget, up to and including the latest version of the
|
|
220
|
-
// loaded widget, and run the upgrade function to bring our loaded
|
|
221
|
-
// widget's props up to that version.
|
|
222
|
-
// There is a little subtlety here in that we call
|
|
223
|
-
// upgradePropsMap[1] to upgrade *to* version 1,
|
|
224
|
-
// (not from version 1).
|
|
225
|
-
for (
|
|
226
|
-
let nextVersion = initialVersion.major + 1;
|
|
227
|
-
nextVersion <= latestVersion.major;
|
|
228
|
-
nextVersion++
|
|
229
|
-
) {
|
|
230
|
-
if (upgradePropsMap[String(nextVersion)]) {
|
|
231
|
-
newEditorProps =
|
|
232
|
-
upgradePropsMap[String(nextVersion)](newEditorProps);
|
|
233
|
-
} else {
|
|
234
|
-
// This is a Log.error because it is unlikely to be hit in
|
|
235
|
-
// local testing, and a Log.error is slightly less scary in
|
|
236
|
-
// prod than a `throw new Error`
|
|
237
|
-
Log.error(
|
|
238
|
-
"No upgrade found for widget. Cannot render.",
|
|
239
|
-
Errors.Internal,
|
|
240
|
-
{
|
|
241
|
-
loggedMetadata: {
|
|
242
|
-
type,
|
|
243
|
-
fromMajorVersion: nextVersion - 1,
|
|
244
|
-
toMajorVersion: nextVersion,
|
|
245
|
-
},
|
|
246
|
-
},
|
|
247
|
-
);
|
|
248
|
-
// But try to keep going anyways (yolo!)
|
|
249
|
-
// (Throwing an error here would just break the page
|
|
250
|
-
// silently anyways, so that doesn't seem much better
|
|
251
|
-
// than a halfhearted attempt to continue, however
|
|
252
|
-
// shallow...)
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// Minor version upgrades (eg. new optional props) don't have
|
|
258
|
-
// transform functions. Instead, we fill in the new props with their
|
|
259
|
-
// defaults.
|
|
260
|
-
const defaultProps = type in editors ? editors[type].defaultProps : {};
|
|
261
|
-
newEditorProps = {
|
|
262
|
-
...defaultProps,
|
|
263
|
-
...newEditorProps,
|
|
264
|
-
};
|
|
265
|
-
|
|
266
|
-
let alignment = oldWidgetInfo.alignment;
|
|
267
|
-
|
|
268
|
-
// Widgets that support multiple alignments will "lock in" the
|
|
269
|
-
// alignment to the alignment that would be listed first in the
|
|
270
|
-
// select box. If the widget only supports one alignment, the
|
|
271
|
-
// alignment value will likely just end up as "default".
|
|
272
|
-
if (alignment == null || alignment === "default") {
|
|
273
|
-
alignment = getSupportedAlignments(type)[0];
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
let widgetStatic = oldWidgetInfo.static;
|
|
277
|
-
|
|
278
|
-
if (widgetStatic == null) {
|
|
279
|
-
widgetStatic = DEFAULT_STATIC;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
return _.extend({}, oldWidgetInfo, {
|
|
283
|
-
// maintain other info, like type
|
|
284
|
-
// After upgrading we guarantee that the version is up-to-date
|
|
285
|
-
version: latestVersion,
|
|
286
|
-
// Default graded to true (so null/undefined becomes true):
|
|
287
|
-
graded: oldWidgetInfo.graded != null ? oldWidgetInfo.graded : true,
|
|
288
|
-
alignment: alignment,
|
|
289
|
-
static: widgetStatic,
|
|
290
|
-
options: newEditorProps,
|
|
291
|
-
});
|
|
292
|
-
};
|
|
293
|
-
|
|
294
|
-
export const getRendererPropsForWidgetInfo = (
|
|
295
|
-
widgetInfo: PerseusWidget,
|
|
296
|
-
problemNum?: number,
|
|
297
|
-
): PerseusWidget => {
|
|
298
|
-
const type = widgetInfo.type;
|
|
299
|
-
const widgetExports = widgets[type];
|
|
300
|
-
if (widgetExports == null) {
|
|
301
|
-
// The widget is not a registered widget
|
|
302
|
-
// It shouldn't matter what we return here, but for consistency
|
|
303
|
-
// we return the untransformed options, as if the widget did
|
|
304
|
-
// not have a transform defined.
|
|
305
|
-
return widgetInfo.options;
|
|
306
|
-
}
|
|
307
|
-
let transform;
|
|
308
|
-
if (widgetInfo.static) {
|
|
309
|
-
// There aren't a lot of real places where we'll have to default to
|
|
310
|
-
// _.identity, but it's theoretically possible if someone changes
|
|
311
|
-
// the JSON manually / we have to back out static support for a
|
|
312
|
-
// widget.
|
|
313
|
-
transform = getStaticTransform(type) || _.identity;
|
|
314
|
-
} else {
|
|
315
|
-
transform = widgetExports.transform || _.identity;
|
|
316
|
-
}
|
|
317
|
-
// widgetInfo.options are the widgetEditor's props:
|
|
318
|
-
return transform(widgetInfo.options, problemNum);
|
|
319
|
-
};
|
|
320
|
-
|
|
321
|
-
export const traverseChildWidgets = (
|
|
322
|
-
widgetInfo: PerseusWidget,
|
|
323
|
-
traverseRenderer: any,
|
|
324
|
-
): PerseusWidget => {
|
|
325
|
-
if (!traverseRenderer) {
|
|
326
|
-
throw new PerseusError(
|
|
327
|
-
"traverseRenderer must be provided, but was not",
|
|
328
|
-
Errors.Internal,
|
|
329
|
-
);
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
if (!widgetInfo || !widgetInfo.type || !widgets[widgetInfo.type]) {
|
|
333
|
-
return widgetInfo;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
const widgetExports = widgets[widgetInfo.type];
|
|
337
|
-
const props = widgetInfo.options;
|
|
338
|
-
|
|
339
|
-
if (widgetExports.traverseChildWidgets && props) {
|
|
340
|
-
const newProps = widgetExports.traverseChildWidgets(
|
|
341
|
-
props,
|
|
342
|
-
traverseRenderer,
|
|
343
|
-
);
|
|
344
|
-
return _.extend({}, widgetInfo, {options: newProps});
|
|
345
|
-
}
|
|
346
|
-
return widgetInfo;
|
|
347
|
-
};
|
|
348
|
-
|
|
349
|
-
/**
|
|
350
|
-
* Handling for the optional alignments for widgets
|
|
351
|
-
* See widget-container.jsx for details on how alignments are implemented.
|
|
352
|
-
*/
|
|
353
|
-
|
|
354
|
-
/**
|
|
355
|
-
* Returns the list of supported alignments for the given (string) widget
|
|
356
|
-
* type. This is used primarily at editing time to display the choices
|
|
357
|
-
* for the user.
|
|
358
|
-
*
|
|
359
|
-
* Supported alignments are given as an array of strings in the exports of
|
|
360
|
-
* a widget's module.
|
|
361
|
-
*/
|
|
362
|
-
export const getSupportedAlignments = (
|
|
363
|
-
type: string,
|
|
364
|
-
): ReadonlyArray<Alignment> => {
|
|
365
|
-
const widgetExport = widgets[type];
|
|
366
|
-
// @ts-expect-error - TS2322 - Type 'string[] | readonly Alignment[]' is not assignable to type 'readonly Alignment[]'.
|
|
367
|
-
return (
|
|
368
|
-
(widgetExport && widgetExport.supportedAlignments) ||
|
|
369
|
-
DEFAULT_SUPPORTED_ALIGNMENTS
|
|
370
|
-
);
|
|
371
|
-
};
|
|
372
|
-
|
|
373
|
-
/**
|
|
374
|
-
* For the given (string) widget type, determine the default alignment for
|
|
375
|
-
* the widget. This is used at rendering time to go from "default" alignment
|
|
376
|
-
* to the actual alignment displayed on the screen.
|
|
377
|
-
*
|
|
378
|
-
* The default alignment is given either as a string (called
|
|
379
|
-
* `defaultAlignment`) or a function (called `getDefaultAlignment`) on
|
|
380
|
-
* the exports of a widget's module.
|
|
381
|
-
*/
|
|
382
|
-
export const getDefaultAlignment = (type: string): Alignment => {
|
|
383
|
-
const widgetExports = widgets[type];
|
|
384
|
-
let alignment;
|
|
385
|
-
if (!widgetExports) {
|
|
386
|
-
return DEFAULT_ALIGNMENT;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
if (widgetExports.getDefaultAlignment) {
|
|
390
|
-
alignment = widgetExports.getDefaultAlignment();
|
|
391
|
-
} else {
|
|
392
|
-
alignment = widgetExports.defaultAlignment;
|
|
393
|
-
}
|
|
394
|
-
return alignment || DEFAULT_ALIGNMENT;
|
|
395
|
-
};
|
|
396
|
-
|
|
397
|
-
const validAlignments: ReadonlyArray<Alignment> = [
|
|
398
|
-
"block",
|
|
399
|
-
"inline-block",
|
|
400
|
-
"inline",
|
|
401
|
-
"float-left",
|
|
402
|
-
"float-right",
|
|
403
|
-
"full-width",
|
|
404
|
-
];
|
|
405
|
-
|
|
406
|
-
/**
|
|
407
|
-
* Used at startup to fail fast if an alignment given by a widget is
|
|
408
|
-
* invalid.
|
|
409
|
-
*/
|
|
410
|
-
// TODO(alex): Change this to run as a testcase (vs. being run at runtime)
|
|
411
|
-
// TODO(LP-10707): I think this can be completely removed because our TypeScript types
|
|
412
|
-
// enforce this!
|
|
413
|
-
export const validateAlignments = () => {
|
|
414
|
-
_.each(widgets, function (widgetInfo) {
|
|
415
|
-
if (
|
|
416
|
-
widgetInfo.defaultAlignment &&
|
|
417
|
-
!_.contains(validAlignments, widgetInfo.defaultAlignment)
|
|
418
|
-
) {
|
|
419
|
-
throw new PerseusError(
|
|
420
|
-
"Widget '" +
|
|
421
|
-
widgetInfo.displayName +
|
|
422
|
-
"' has an invalid defaultAlignment value: " +
|
|
423
|
-
widgetInfo.defaultAlignment,
|
|
424
|
-
Errors.InvalidInput,
|
|
425
|
-
);
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
if (widgetInfo.supportedAlignments) {
|
|
429
|
-
const unknownAlignments = _.difference(
|
|
430
|
-
widgetInfo.supportedAlignments,
|
|
431
|
-
validAlignments,
|
|
432
|
-
);
|
|
433
|
-
|
|
434
|
-
if (unknownAlignments.length) {
|
|
435
|
-
throw new PerseusError(
|
|
436
|
-
"Widget '" +
|
|
437
|
-
widgetInfo.displayName +
|
|
438
|
-
"' has an invalid value for supportedAlignments: " +
|
|
439
|
-
unknownAlignments.join(" "),
|
|
440
|
-
Errors.InvalidInput,
|
|
441
|
-
);
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
});
|
|
445
|
-
};
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* Handling for static mode for widgets that support it.
|
|
449
|
-
*/
|
|
450
|
-
|
|
451
|
-
/**
|
|
452
|
-
* Returns true iff the widget supports static mode.
|
|
453
|
-
* A widget implicitly supports static mode if it exports a
|
|
454
|
-
* staticTransform function.
|
|
455
|
-
*/
|
|
456
|
-
export const supportsStaticMode = (type: string): boolean => {
|
|
457
|
-
const widgetInfo = widgets[type];
|
|
458
|
-
return widgetInfo && widgetInfo.staticTransform != null;
|
|
459
|
-
};
|
|
460
|
-
|
|
461
|
-
/**
|
|
462
|
-
* Return the staticTransform function used to convert the editorProps to
|
|
463
|
-
* the rendered widget state.
|
|
464
|
-
*/
|
|
465
|
-
export const getStaticTransform = (
|
|
466
|
-
type: string,
|
|
467
|
-
): WidgetTransform | null | undefined => {
|
|
468
|
-
const widgetInfo = widgets[type];
|
|
469
|
-
return widgetInfo && widgetInfo.staticTransform;
|
|
470
|
-
};
|
|
471
|
-
|
|
472
|
-
/**
|
|
473
|
-
* Returns the tracking option for the widget. The default is "",
|
|
474
|
-
* which means simply to track interactions once. The other available
|
|
475
|
-
* option is "all" which means to track all interactions.
|
|
476
|
-
*/
|
|
477
|
-
export const getTracking = (type: string): Tracking => {
|
|
478
|
-
const widgetExport = widgets[type];
|
|
479
|
-
return (widgetExport && widgetExport.tracking) || DEFAULT_TRACKING;
|
|
480
|
-
};
|
|
481
|
-
|
|
482
|
-
/**
|
|
483
|
-
* Returns true if this widget can include lintable markdown text
|
|
484
|
-
* and supports a highlightLint prop, or false otherwise.
|
|
485
|
-
*/
|
|
486
|
-
export const isLintable = (type: string): boolean => {
|
|
487
|
-
const widgetExports = widgets[type];
|
|
488
|
-
return (widgetExports && widgetExports.isLintable) || DEFAULT_LINTABLE;
|
|
489
|
-
};
|