@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
|
@@ -1,392 +0,0 @@
|
|
|
1
|
-
import $ from "jquery";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
import ReactDOM from "react-dom";
|
|
4
|
-
import _ from "underscore";
|
|
5
|
-
|
|
6
|
-
import InteractiveUtil from "../interactive2/interactive-util";
|
|
7
|
-
import {Errors, Log} from "../logging/log";
|
|
8
|
-
import Util from "../util";
|
|
9
|
-
import GraphUtils from "../util/graph-utils";
|
|
10
|
-
import {Graphie as GraphieDrawingContext} from "../util/graphie";
|
|
11
|
-
|
|
12
|
-
import GraphieClasses from "./graphie-classes";
|
|
13
|
-
import Movables from "./graphie-movables";
|
|
14
|
-
|
|
15
|
-
import type {Coord} from "../interactive2/types";
|
|
16
|
-
import type {Range, Size} from "../perseus-types";
|
|
17
|
-
|
|
18
|
-
const GraphieMovable = GraphieClasses.GraphieMovable;
|
|
19
|
-
|
|
20
|
-
const createGraphie = GraphUtils.createGraphie;
|
|
21
|
-
const {deepEq, nestedMap} = Util;
|
|
22
|
-
const {assert} = InteractiveUtil;
|
|
23
|
-
|
|
24
|
-
type Props = {
|
|
25
|
-
addMouseLayer?: boolean;
|
|
26
|
-
box: Size;
|
|
27
|
-
range: [Coord, Coord];
|
|
28
|
-
ranges?: [Range, Range];
|
|
29
|
-
gridStep?: [number, number];
|
|
30
|
-
step?: [number, number];
|
|
31
|
-
scale?: [number, number];
|
|
32
|
-
|
|
33
|
-
isMobile?: boolean;
|
|
34
|
-
responsive?: boolean;
|
|
35
|
-
|
|
36
|
-
children?: React.ReactNode;
|
|
37
|
-
|
|
38
|
-
// TODO(LC-772) - type this prop!
|
|
39
|
-
options: any;
|
|
40
|
-
|
|
41
|
-
setDrawingAreaAvailable?: (boolean) => void;
|
|
42
|
-
setup: (
|
|
43
|
-
graphie: any,
|
|
44
|
-
options: {
|
|
45
|
-
range: [Coord, Coord];
|
|
46
|
-
scale: [number, number];
|
|
47
|
-
},
|
|
48
|
-
) => void;
|
|
49
|
-
|
|
50
|
-
onClick?: (at: Coord) => void;
|
|
51
|
-
onMouseDown?: (at: Coord) => void;
|
|
52
|
-
onMouseMove?: (at: Coord) => void;
|
|
53
|
-
onMouseUp?: (at: Coord) => void;
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
type DefaultProps = {
|
|
57
|
-
range: Props["range"];
|
|
58
|
-
options: Props["options"];
|
|
59
|
-
responsive: Props["responsive"];
|
|
60
|
-
addMouseLayer: Props["addMouseLayer"];
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
interface Movable {
|
|
64
|
-
remove(): void;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
class Graphie extends React.Component<Props> {
|
|
68
|
-
graphieDivRef = React.createRef<HTMLDivElement>();
|
|
69
|
-
_graphie: GraphieDrawingContext = new GraphieDrawingContext(
|
|
70
|
-
document.createElement("div"),
|
|
71
|
-
);
|
|
72
|
-
_movables: Record<string, Movable> = {};
|
|
73
|
-
movables: Record<string, Movable> = {};
|
|
74
|
-
|
|
75
|
-
static defaultProps: DefaultProps = {
|
|
76
|
-
range: [
|
|
77
|
-
[-10, 10],
|
|
78
|
-
[-10, 10],
|
|
79
|
-
],
|
|
80
|
-
options: {},
|
|
81
|
-
responsive: false,
|
|
82
|
-
addMouseLayer: true,
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
componentDidMount() {
|
|
86
|
-
this._setupGraphie();
|
|
87
|
-
this._updateMovables();
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
shouldComponentUpdate(nextProps: Props): boolean {
|
|
91
|
-
// NOTE(jeresig): Prior to the React 16 upgrade this was using deepEq
|
|
92
|
-
// However it started to throw errors. I switched to use Underscore's
|
|
93
|
-
// isEqual method instead, hopefully having a similar effect.
|
|
94
|
-
return !_.isEqual(this.props, nextProps);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
componentDidUpdate(prevProps: Props) {
|
|
98
|
-
// If someone changes the setup function passed in, we should
|
|
99
|
-
// technically setup graphie again. But that's definitely an
|
|
100
|
-
// anti-pattern, since it is most-likely caused by passing in an
|
|
101
|
-
// anonymous function rather than a "real" change, and re-rendering
|
|
102
|
-
// in that case would cause us to constantly re-setup graphie, which
|
|
103
|
-
// would have horrible performance implications. In order to avoid
|
|
104
|
-
// those, we just warn here.
|
|
105
|
-
if (this.props.setup !== prevProps.setup) {
|
|
106
|
-
Log.error(
|
|
107
|
-
"<Graphie> was given a new setup function. " +
|
|
108
|
-
"This is a bad idea; please refactor your code to give " +
|
|
109
|
-
"the same setup function reference to <Graphie> on " +
|
|
110
|
-
"every render.",
|
|
111
|
-
Errors.Internal,
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
if (
|
|
115
|
-
!deepEq(this.props.options, prevProps.options) ||
|
|
116
|
-
!deepEq(this.props.box, prevProps.box) ||
|
|
117
|
-
!deepEq(this.props.range, prevProps.range)
|
|
118
|
-
) {
|
|
119
|
-
this._setupGraphie();
|
|
120
|
-
}
|
|
121
|
-
this._updateMovables();
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Allow parents of the <Graphie> component to grab a reference to the
|
|
126
|
-
* underlying graphie object using
|
|
127
|
-
* `this.refs.graphieComponent.getGraphie()`
|
|
128
|
-
*
|
|
129
|
-
* This shouldn't be necessary for 90% of cases, but the power is there.
|
|
130
|
-
* Use it for good and not evil.
|
|
131
|
-
*/
|
|
132
|
-
getGraphie: () => any = () => {
|
|
133
|
-
return this._graphie;
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
// bounds-checked range
|
|
137
|
-
_range: () => [Coord, Coord] = () => {
|
|
138
|
-
const boundsCheckRange = (range: Coord): Coord => {
|
|
139
|
-
if (range[0] >= range[1]) {
|
|
140
|
-
return [-10, 10];
|
|
141
|
-
}
|
|
142
|
-
return range;
|
|
143
|
-
};
|
|
144
|
-
return [
|
|
145
|
-
boundsCheckRange(this.props.range[0]),
|
|
146
|
-
boundsCheckRange(this.props.range[1]),
|
|
147
|
-
];
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
_box: () => Size = () => {
|
|
151
|
-
const ensureMinSize = (pixelDim: number): number => {
|
|
152
|
-
// 340 = default size in the editor. exact value
|
|
153
|
-
// is arbitrary; this is just a safety check.
|
|
154
|
-
return pixelDim > 0 ? pixelDim : 340;
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
return [
|
|
158
|
-
ensureMinSize(this.props.box[0]),
|
|
159
|
-
ensureMinSize(this.props.box[1]),
|
|
160
|
-
];
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
// @ts-expect-error - TS2322: Type '() => number[]' is not assignable to type '() => Coord'.
|
|
164
|
-
_scale: () => Coord = () => {
|
|
165
|
-
const box = this._box();
|
|
166
|
-
const range = this._range();
|
|
167
|
-
return box.map((pixelDim, i) => {
|
|
168
|
-
const unitDim = range[i][1] - range[i][0];
|
|
169
|
-
return pixelDim / unitDim;
|
|
170
|
-
});
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
_setupGraphie: () => void = () => {
|
|
174
|
-
this._removeMovables();
|
|
175
|
-
|
|
176
|
-
const graphieDiv = ReactDOM.findDOMNode(this.graphieDivRef.current);
|
|
177
|
-
if (graphieDiv == null || graphieDiv instanceof Text) {
|
|
178
|
-
throw new Error("No graphie container div found");
|
|
179
|
-
}
|
|
180
|
-
graphieDiv.innerHTML = "";
|
|
181
|
-
const graphie = (this._graphie = createGraphie(graphieDiv));
|
|
182
|
-
|
|
183
|
-
// This has to be called before addMouseLayer. You can re-init
|
|
184
|
-
// with graphInit later if you prefer
|
|
185
|
-
graphie.init({
|
|
186
|
-
range: this._range(),
|
|
187
|
-
scale: this._scale(),
|
|
188
|
-
isMobile: this.props.isMobile,
|
|
189
|
-
});
|
|
190
|
-
// Only add the mouselayer if we actually want one.
|
|
191
|
-
if (this.props.addMouseLayer) {
|
|
192
|
-
// @ts-expect-error - TS2339: Property 'addMouseLayer' does not exist on type 'Graphie'.
|
|
193
|
-
graphie.addMouseLayer({
|
|
194
|
-
onClick: this.props.onClick,
|
|
195
|
-
onMouseDown: this.props.onMouseDown,
|
|
196
|
-
onMouseUp: this.props.onMouseUp,
|
|
197
|
-
onMouseMove: this.props.onMouseMove,
|
|
198
|
-
setDrawingAreaAvailable: this.props.setDrawingAreaAvailable,
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// @ts-expect-error - TS2339: Property 'snap' does not exist on type 'Graphie'.
|
|
203
|
-
graphie.snap = this.props.options.snapStep || [1, 1];
|
|
204
|
-
|
|
205
|
-
if (this.props.responsive) {
|
|
206
|
-
// Overwrite fixed styles set in init()
|
|
207
|
-
// TODO(alex): Either make this component always responsive by
|
|
208
|
-
// itself, or always wrap it in other components so that it is.
|
|
209
|
-
$(graphieDiv).css({width: "100%", height: "100%"});
|
|
210
|
-
graphie.raphael.setSize("100%", "100%");
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
this.props.setup(
|
|
214
|
-
graphie,
|
|
215
|
-
_.extend(
|
|
216
|
-
{
|
|
217
|
-
range: this._range(),
|
|
218
|
-
scale: this._scale(),
|
|
219
|
-
},
|
|
220
|
-
this.props.options,
|
|
221
|
-
),
|
|
222
|
-
);
|
|
223
|
-
};
|
|
224
|
-
|
|
225
|
-
_removeMovables: () => void = () => {
|
|
226
|
-
// _.invoke works even when this._movables is undefined
|
|
227
|
-
_.invoke(this._movables, "remove");
|
|
228
|
-
this._movables = {};
|
|
229
|
-
};
|
|
230
|
-
|
|
231
|
-
// @ts-expect-error - TS2322 - Type '(children: readonly any[], options: any) => ReactElement<any, string | JSXElementConstructor<any>> | readonly ReactElement<any, string | JSXElementConstructor<any>>[]' is not assignable to type '(children: readonly any[], arg2: any) => ReactElement<any, string | JSXElementConstructor<any>>'.
|
|
232
|
-
_renderMovables: (
|
|
233
|
-
children: ReadonlyArray<any>,
|
|
234
|
-
arg2: any,
|
|
235
|
-
) => React.ReactElement = (children, options) => {
|
|
236
|
-
// Each leaf of `children` is a movable descriptor created by a call to
|
|
237
|
-
// some `GraphieMovable`, such as `MovablePoint`.
|
|
238
|
-
//
|
|
239
|
-
// This function takes these descriptors and renders them into
|
|
240
|
-
// on-screen movables, or updates on-screen movables for
|
|
241
|
-
// descriptors when possible.
|
|
242
|
-
//
|
|
243
|
-
// If there is no movable with that key already, this descriptor is
|
|
244
|
-
// stored in this._movables and promoted to an on-screen movable by
|
|
245
|
-
// calling `child.add(graphie)`.
|
|
246
|
-
//
|
|
247
|
-
// If a movable of the same type with the same key exists already,
|
|
248
|
-
// we take `child.props` and give them to the already-existing
|
|
249
|
-
// on-screen movable, and call `movable.modify()`
|
|
250
|
-
|
|
251
|
-
const graphie = options.graphie;
|
|
252
|
-
const oldMovables = options.oldMovables;
|
|
253
|
-
const newMovables = options.newMovables; /* output parameter */
|
|
254
|
-
|
|
255
|
-
const renderChildren = (elem: any) => {
|
|
256
|
-
_.each(elem.movableProps, (prop) => {
|
|
257
|
-
// Render the children, and save the results of that
|
|
258
|
-
// render to the appropriate props
|
|
259
|
-
elem.props[prop] = this._renderMovables(
|
|
260
|
-
elem.props[prop],
|
|
261
|
-
options,
|
|
262
|
-
);
|
|
263
|
-
});
|
|
264
|
-
};
|
|
265
|
-
|
|
266
|
-
// Add/modify movables
|
|
267
|
-
|
|
268
|
-
// We want to keep track of whether we have added a new svg element,
|
|
269
|
-
// because if we have, then we need to call .toFront() on any svg
|
|
270
|
-
// elements occurring afterwards. If this happens, we set
|
|
271
|
-
// `areMovablesOutOfOrder` to true:
|
|
272
|
-
let areMovablesOutOfOrder = false;
|
|
273
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 2.
|
|
274
|
-
return nestedMap(children, (childDescriptor) => {
|
|
275
|
-
if (!childDescriptor) {
|
|
276
|
-
// Still increment the key to avoid cascading key changes
|
|
277
|
-
// on hiding/unhiding children, i.e. by using
|
|
278
|
-
// {someBoolean && <MovablePoint />}
|
|
279
|
-
options.nextKey++;
|
|
280
|
-
// preserve the null/undefined in the resulting array
|
|
281
|
-
return childDescriptor;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// Instantiate the descriptor to turn it into a real Movable
|
|
285
|
-
const child = new childDescriptor.type(childDescriptor.props);
|
|
286
|
-
assert(
|
|
287
|
-
child instanceof GraphieMovable,
|
|
288
|
-
"All children of a Graphie component must be Graphie " +
|
|
289
|
-
"movables",
|
|
290
|
-
);
|
|
291
|
-
|
|
292
|
-
// Give each child a key
|
|
293
|
-
const keyProp = childDescriptor.key;
|
|
294
|
-
const key = keyProp == null ? "_no_id_" + options.nextKey : keyProp;
|
|
295
|
-
options.nextKey++;
|
|
296
|
-
const ref = childDescriptor.ref;
|
|
297
|
-
|
|
298
|
-
// We render our children first. This allows us to replace any
|
|
299
|
-
// `movableProps` on our child with the on-screen movables
|
|
300
|
-
// corresponding with those descriptors.
|
|
301
|
-
renderChildren(child);
|
|
302
|
-
|
|
303
|
-
const prevMovable = oldMovables[key];
|
|
304
|
-
if (!prevMovable) {
|
|
305
|
-
// We're creating a new child
|
|
306
|
-
child.add(graphie);
|
|
307
|
-
areMovablesOutOfOrder = true;
|
|
308
|
-
|
|
309
|
-
newMovables[key] = child;
|
|
310
|
-
} else if (child.constructor === prevMovable.constructor) {
|
|
311
|
-
// We're updating an old child
|
|
312
|
-
prevMovable.props = child.props;
|
|
313
|
-
const modifyResult = prevMovable.modify(graphie);
|
|
314
|
-
if (modifyResult === "reordered") {
|
|
315
|
-
areMovablesOutOfOrder = true;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
newMovables[key] = prevMovable;
|
|
319
|
-
} else {
|
|
320
|
-
// We're destroying an old child and replacing it
|
|
321
|
-
// with a new child of a different type
|
|
322
|
-
|
|
323
|
-
// This generally is a bad idea, so warn about it if this
|
|
324
|
-
// is being caused by implicit keys
|
|
325
|
-
if (keyProp == null) {
|
|
326
|
-
Log.error(
|
|
327
|
-
"Replacing a <Graphie> child with a " +
|
|
328
|
-
"child of a different type. Please add keys " +
|
|
329
|
-
"to your <Graphie> children",
|
|
330
|
-
Errors.Internal,
|
|
331
|
-
);
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
prevMovable.remove();
|
|
335
|
-
child.add(graphie);
|
|
336
|
-
areMovablesOutOfOrder = true;
|
|
337
|
-
|
|
338
|
-
newMovables[key] = child;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
if (areMovablesOutOfOrder) {
|
|
342
|
-
newMovables[key].toFront();
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
if (ref) {
|
|
346
|
-
this.movables[ref] = newMovables[key];
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
return newMovables[key];
|
|
350
|
-
});
|
|
351
|
-
};
|
|
352
|
-
|
|
353
|
-
// Sort of like react diffing, but for movables
|
|
354
|
-
_updateMovables: () => void = () => {
|
|
355
|
-
const graphie = this._graphie;
|
|
356
|
-
|
|
357
|
-
const oldMovables = this._movables;
|
|
358
|
-
const newMovables: Record<string, any> = {};
|
|
359
|
-
this._movables = newMovables;
|
|
360
|
-
this.movables = {};
|
|
361
|
-
|
|
362
|
-
// @ts-expect-error - TS2345 - Argument of type 'ReactNode' is not assignable to parameter of type 'readonly any[]'.
|
|
363
|
-
this._renderMovables(this.props.children, {
|
|
364
|
-
nextKey: 1,
|
|
365
|
-
graphie: graphie,
|
|
366
|
-
oldMovables: oldMovables,
|
|
367
|
-
newMovables: newMovables,
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
// Remove any movables that no longer exist in the child array
|
|
371
|
-
_.each(oldMovables, (oldMovable, key) => {
|
|
372
|
-
if (!newMovables[key]) {
|
|
373
|
-
oldMovable.remove();
|
|
374
|
-
}
|
|
375
|
-
});
|
|
376
|
-
};
|
|
377
|
-
|
|
378
|
-
render(): React.ReactNode {
|
|
379
|
-
return (
|
|
380
|
-
<div className="graphie-container">
|
|
381
|
-
<div className="graphie" ref={this.graphieDivRef} />
|
|
382
|
-
</div>
|
|
383
|
-
);
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
// Attach Graphie.createClass and Graphie.createSimpleClass
|
|
388
|
-
_.extend(Graphie, GraphieClasses);
|
|
389
|
-
// Attach the Movable react components for easy reference
|
|
390
|
-
_.extend(Graphie, Movables);
|
|
391
|
-
|
|
392
|
-
export default Graphie;
|
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The entry point for highlighting!
|
|
3
|
-
*
|
|
4
|
-
* Given a content node and a set of serialized highlights, this component
|
|
5
|
-
* renders the content with the given highlights applied. The content's DOM is
|
|
6
|
-
* not modified by this process, so any content should be safe to pass to this
|
|
7
|
-
* component.
|
|
8
|
-
*
|
|
9
|
-
* This component also renders controls for the user to add/remove/update
|
|
10
|
-
* highlights. When the user does so, this component will update the full set
|
|
11
|
-
* of highlights, serialize them, and call `onSerializedHighlightsUpdate` with
|
|
12
|
-
* new set of serialized highlights, which you can then persist and send back
|
|
13
|
-
* down to this component. Easy peasy!
|
|
14
|
-
*/
|
|
15
|
-
import {StyleSheet, css} from "aphrodite";
|
|
16
|
-
import * as React from "react";
|
|
17
|
-
|
|
18
|
-
import {
|
|
19
|
-
addHighlight,
|
|
20
|
-
buildHighlight,
|
|
21
|
-
deserializeHighlight,
|
|
22
|
-
serializeHighlight,
|
|
23
|
-
} from "./highlights";
|
|
24
|
-
import HighlightingUI from "./ui/highlighting-ui";
|
|
25
|
-
import WordIndexer from "./word-indexer";
|
|
26
|
-
|
|
27
|
-
import type {
|
|
28
|
-
DOMHighlight,
|
|
29
|
-
DOMHighlightSet,
|
|
30
|
-
SerializedHighlightSet,
|
|
31
|
-
DOMRange,
|
|
32
|
-
} from "./types";
|
|
33
|
-
|
|
34
|
-
type Props = {
|
|
35
|
-
// The highlightable content itself. Highlights will be defined relative to
|
|
36
|
-
// the content specified here.
|
|
37
|
-
children?: React.ReactElement<any>;
|
|
38
|
-
// Whether the highlights are user-editable. If false, highlights are
|
|
39
|
-
// read-only.
|
|
40
|
-
editable: boolean;
|
|
41
|
-
// Whether highlighting is currently enabled. If false, highlights are not
|
|
42
|
-
// visible and are read-only (regardless of the `editable` prop), and this
|
|
43
|
-
// component is effectively a no-op.
|
|
44
|
-
//
|
|
45
|
-
// NOTE(mdr): The purpose of the `enabled` prop, as opposed to, say, just
|
|
46
|
-
// *not* wrapping the content, is to enable quick toggles between
|
|
47
|
-
// enabled/disabled while maintaining the same component structure.
|
|
48
|
-
// Forcing React to rebuild the entire component tree is not kind!
|
|
49
|
-
enabled: boolean;
|
|
50
|
-
// When the user attempts to add/remove/update a highlight, this callback
|
|
51
|
-
// will be called with a newly-updated full set of highlights that reflects
|
|
52
|
-
// the user's intent.
|
|
53
|
-
onSerializedHighlightsUpdate: (
|
|
54
|
-
serializedHighlights: SerializedHighlightSet,
|
|
55
|
-
) => unknown;
|
|
56
|
-
// The set of highlights to apply to the given content.
|
|
57
|
-
serializedHighlights: SerializedHighlightSet;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
type State = {
|
|
61
|
-
// A cached list of DOMRanges, each representing one of the content's
|
|
62
|
-
// semantic words. Sorted in document order.
|
|
63
|
-
wordRanges: ReadonlyArray<DOMRange>;
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
class HighlightableContent extends React.PureComponent<Props, State> {
|
|
67
|
-
// References to the mounted container and content divs.
|
|
68
|
-
_container: HTMLElement | null | undefined;
|
|
69
|
-
_content: HTMLElement | null | undefined;
|
|
70
|
-
|
|
71
|
-
state: State = {
|
|
72
|
-
wordRanges: [],
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
_buildHighlight(highlightRange: DOMRange): DOMHighlight | null | undefined {
|
|
76
|
-
// TODO(mdr): If _buildHighlight starts getting called more often, we
|
|
77
|
-
// might want to cache the DOMHighlightSet instead of recomputing
|
|
78
|
-
// it here.
|
|
79
|
-
return buildHighlight(
|
|
80
|
-
this._getDOMHighlights(),
|
|
81
|
-
this.state.wordRanges,
|
|
82
|
-
highlightRange,
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Take the highlights from props, and deserialize them into DOMHighlights,
|
|
88
|
-
* according to the latest cache of word ranges.
|
|
89
|
-
*/
|
|
90
|
-
_getDOMHighlights(): DOMHighlightSet {
|
|
91
|
-
const {serializedHighlights} = this.props;
|
|
92
|
-
const {wordRanges} = this.state;
|
|
93
|
-
|
|
94
|
-
const domHighlights: Record<string, any> = {};
|
|
95
|
-
for (const key of Object.keys(serializedHighlights)) {
|
|
96
|
-
domHighlights[key] = deserializeHighlight(
|
|
97
|
-
serializedHighlights[key],
|
|
98
|
-
wordRanges,
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
return domHighlights;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Add the given DOMHighlight to the current set.
|
|
106
|
-
*/
|
|
107
|
-
_handleAddHighlight: (highlight: DOMHighlight) => void = (
|
|
108
|
-
highlight: DOMHighlight,
|
|
109
|
-
) => {
|
|
110
|
-
const newDomHighlights = addHighlight(
|
|
111
|
-
this._getDOMHighlights(),
|
|
112
|
-
highlight,
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
const newSerializedHighlights: Record<string, any> = {};
|
|
116
|
-
for (const key of Object.keys(newDomHighlights)) {
|
|
117
|
-
newSerializedHighlights[key] = serializeHighlight(
|
|
118
|
-
newDomHighlights[key],
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
this.props.onSerializedHighlightsUpdate(newSerializedHighlights);
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Remove the given highlight from the list, and call our callback with the
|
|
127
|
-
* new set of highlights.
|
|
128
|
-
*/
|
|
129
|
-
_handleRemoveHighlight: (keyToRemove: string) => void = (
|
|
130
|
-
keyToRemove: string,
|
|
131
|
-
) => {
|
|
132
|
-
const {serializedHighlights} = this.props;
|
|
133
|
-
const newSerializedHighlights = {...serializedHighlights} as const;
|
|
134
|
-
// @ts-expect-error - TS2542 - Index signature in type '{ readonly [x: string]: SerializedHighlight; }' only permits reading.
|
|
135
|
-
delete newSerializedHighlights[keyToRemove];
|
|
136
|
-
this.props.onSerializedHighlightsUpdate(newSerializedHighlights);
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* When our WordIndexer sends us a new cache of word ranges, store it in
|
|
141
|
-
* our component state.
|
|
142
|
-
*/
|
|
143
|
-
_handleWordsUpdate: (wordRanges: ReadonlyArray<DOMRange>) => void = (
|
|
144
|
-
wordRanges: ReadonlyArray<DOMRange>,
|
|
145
|
-
) => {
|
|
146
|
-
this.setState({wordRanges});
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
render(): React.ReactNode {
|
|
150
|
-
const highlights = this._getDOMHighlights();
|
|
151
|
-
|
|
152
|
-
// NOTE(mdr): This lambda is rebuilt every time this component updates,
|
|
153
|
-
// so every update to HighlightableContent triggers an update in
|
|
154
|
-
// the child HighlightingUI and SelectionTracker, even if the
|
|
155
|
-
// behavior hasn't changed.
|
|
156
|
-
//
|
|
157
|
-
// Over-updating is preferable to under-updating here, because some
|
|
158
|
-
// updates in this component's props/state *do* affect
|
|
159
|
-
// `buildHighlight`'s behavior, and *should* trigger an update.
|
|
160
|
-
//
|
|
161
|
-
// A more performant approach would be to cache this function
|
|
162
|
-
// object until its implicitly-bound inputs change. If profiling
|
|
163
|
-
// leads us to implement such caching, this draft might be a good
|
|
164
|
-
// starting point: https://phabricator.khanacademy.org/D35623?id=170698
|
|
165
|
-
const buildHighlight = (r: DOMRange) => this._buildHighlight(r);
|
|
166
|
-
|
|
167
|
-
return (
|
|
168
|
-
<div
|
|
169
|
-
className={css(styles.container)}
|
|
170
|
-
ref={(container) => (this._container = container)}
|
|
171
|
-
>
|
|
172
|
-
<div>
|
|
173
|
-
{this.props.enabled && this._container && this._content && (
|
|
174
|
-
<HighlightingUI
|
|
175
|
-
buildHighlight={buildHighlight}
|
|
176
|
-
contentNode={this._content}
|
|
177
|
-
editable={this.props.editable}
|
|
178
|
-
highlights={highlights}
|
|
179
|
-
offsetParent={this._container}
|
|
180
|
-
zIndexes={{
|
|
181
|
-
// The content has a z-index of 1, so, to
|
|
182
|
-
// be below the content, use z-index of 0.
|
|
183
|
-
//
|
|
184
|
-
// TODO(mdr): Is this way of passing around
|
|
185
|
-
// `z-index: 0` actually worth the
|
|
186
|
-
// trouble? We used to have more, but
|
|
187
|
-
// now we don't need them...
|
|
188
|
-
belowContent: 0,
|
|
189
|
-
}}
|
|
190
|
-
onAddHighlight={this._handleAddHighlight}
|
|
191
|
-
onRemoveHighlight={this._handleRemoveHighlight}
|
|
192
|
-
/>
|
|
193
|
-
)}
|
|
194
|
-
</div>
|
|
195
|
-
<div
|
|
196
|
-
className={css(styles.content)}
|
|
197
|
-
ref={(content) => (this._content = content)}
|
|
198
|
-
>
|
|
199
|
-
<WordIndexer onWordsUpdate={this._handleWordsUpdate}>
|
|
200
|
-
{this.props.children}
|
|
201
|
-
</WordIndexer>
|
|
202
|
-
</div>
|
|
203
|
-
</div>
|
|
204
|
-
);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const styles = StyleSheet.create({
|
|
209
|
-
// We render content with z-index 1, and highlights with z-index 0, so that
|
|
210
|
-
// content will receive the browser's native pointer events. (Highlights
|
|
211
|
-
// have their own magic code to manage hover detection, despite being
|
|
212
|
-
// behind the content.)
|
|
213
|
-
|
|
214
|
-
container: {
|
|
215
|
-
// Position the container and give it a z-index, to scope the z-indexes
|
|
216
|
-
// inside by creating a stacking context.
|
|
217
|
-
// https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
|
|
218
|
-
//
|
|
219
|
-
// This way, content's z-index of 1, and highlights' z-index of 0, and
|
|
220
|
-
// tooltips' z-index of 2 don't interact with anything external;
|
|
221
|
-
// external UI will see `HighlightableContent` as a single flat layer
|
|
222
|
-
// with a z-index of 0. This removes the need for us to coordinate our
|
|
223
|
-
// choices of z-index with external UI.
|
|
224
|
-
position: "relative",
|
|
225
|
-
zIndex: 0,
|
|
226
|
-
},
|
|
227
|
-
|
|
228
|
-
content: {
|
|
229
|
-
// NOTE(mdr): Creating a stacking context for content of z-index 1 may
|
|
230
|
-
// be problematic if the content and external page want to
|
|
231
|
-
// interleave layers between each other, e.g., if the application UI
|
|
232
|
-
// wants to render something above some parts of our content, but
|
|
233
|
-
// below other parts. It's not relevant for the current Passage-only
|
|
234
|
-
// call site, but could be relevant someday…
|
|
235
|
-
position: "relative",
|
|
236
|
-
zIndex: 1,
|
|
237
|
-
},
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
export default HighlightableContent;
|