@khanacademy/perseus 1.3.6 → 1.4.0
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/CHANGELOG.md +24 -0
- package/dist/es/index.css +3 -2
- package/dist/es/index.js +80 -59
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +3 -2
- package/dist/index.js +76 -49
- package/dist/index.js.map +1 -1
- package/package.json +33 -33
- package/src/components/__stories__/tex.stories.jsx +8 -2
- package/src/index.js +1 -1
- package/src/interactive2/movable-point.jsx +2 -4
- package/src/item-renderer.jsx +3 -6
- package/src/mixins/__tests__/{widget-prop-blacklist_test.js → widget-prop-denylist_test.js} +1 -1
- package/src/mixins/changeable.jsx +2 -2
- package/src/mixins/editor-jsonify.jsx +2 -2
- package/src/mixins/provide-keypad.jsx +3 -3
- package/src/mixins/widget-jsonify-deprecated.jsx +3 -3
- package/src/mixins/{widget-prop-blacklist.js → widget-prop-denylist.js} +2 -3
- package/src/multi-items/__tests__/__snapshots__/multi-renderer_test.js.snap +0 -10
- package/src/styles/perseus-renderer.less +0 -3
- package/src/styles/widgets/radio.less +4 -0
- package/src/types.js +1 -7
- package/src/util/react-render.js +27 -0
- package/src/util.js +1 -1
- package/src/widget-container.jsx +1 -1
- package/src/widgets/__stories__/on-screen-keypad.stories.jsx +118 -0
- package/src/widgets/__tests__/__snapshots__/categorizer_test.jsx.snap +6 -6
- package/src/widgets/__tests__/__snapshots__/definition_test.js.snap +0 -2
- package/src/widgets/__tests__/__snapshots__/graded-group-set-jipt_test.jsx.snap +3 -6
- package/src/widgets/__tests__/__snapshots__/graded-group-set_test.jsx.snap +15 -13
- package/src/widgets/__tests__/__snapshots__/graded-group_test.jsx.snap +6 -7
- package/src/widgets/__tests__/__snapshots__/group_test.jsx.snap +0 -10
- package/src/widgets/__tests__/__snapshots__/radio_test.jsx.snap +0 -104
- package/src/widgets/__tests__/__snapshots__/video_test.jsx.snap +2 -4
- package/src/widgets/__tests__/graded-group-set_test.jsx +29 -9
- package/src/widgets/categorizer.jsx +6 -1
- package/src/widgets/cs-program.jsx +1 -1
- package/src/widgets/graded-group-set.jsx +43 -39
- package/src/widgets/graded-group.jsx +3 -3
- package/src/widgets/iframe.jsx +1 -1
- package/src/widgets/passage-ref.jsx +2 -2
- package/src/widgets/radio/widget.jsx +7 -6
- package/src/widgets/radio.jsx +2 -2
package/dist/index.css
CHANGED
|
@@ -2310,8 +2310,6 @@ img.zoom-img {
|
|
|
2310
2310
|
font-size: 14px;
|
|
2311
2311
|
line-height: 19.6px;
|
|
2312
2312
|
padding-left: 35px;
|
|
2313
|
-
}
|
|
2314
|
-
.framework-perseus .paragraph ul:not(.perseus-widget-radio) li {
|
|
2315
2313
|
list-style-type: disc;
|
|
2316
2314
|
}
|
|
2317
2315
|
.framework-perseus .paragraph ol {
|
|
@@ -3190,6 +3188,9 @@ body.sat-section .perseus-widget-passage {
|
|
|
3190
3188
|
.perseus-widget-radio li table {
|
|
3191
3189
|
border: 1px solid #ccc;
|
|
3192
3190
|
}
|
|
3191
|
+
.perseus-widget-radio-fieldset .instructions {
|
|
3192
|
+
font-family: "Lato", sans-serif;
|
|
3193
|
+
}
|
|
3193
3194
|
.reaction {
|
|
3194
3195
|
display: table-row;
|
|
3195
3196
|
}
|
package/dist/index.js
CHANGED
|
@@ -15,6 +15,7 @@ var ReactDOM = require('react-dom');
|
|
|
15
15
|
var wonderBlocksProgressSpinner = require('@khanacademy/wonder-blocks-progress-spinner');
|
|
16
16
|
var kmath = require('@khanacademy/kmath');
|
|
17
17
|
var createReactClass = require('create-react-class');
|
|
18
|
+
var wonderBlocksCore = require('@khanacademy/wonder-blocks-core');
|
|
18
19
|
var SimpleMarkdown = require('@khanacademy/simple-markdown');
|
|
19
20
|
var pureMarkdown = require('@khanacademy/pure-markdown');
|
|
20
21
|
var aphrodite = require('aphrodite');
|
|
@@ -25,7 +26,6 @@ var Tooltip$1 = require('@khanacademy/wonder-blocks-tooltip');
|
|
|
25
26
|
var Button = require('@khanacademy/wonder-blocks-button');
|
|
26
27
|
var Clickable = require('@khanacademy/wonder-blocks-clickable');
|
|
27
28
|
var Color = require('@khanacademy/wonder-blocks-color');
|
|
28
|
-
var wonderBlocksCore = require('@khanacademy/wonder-blocks-core');
|
|
29
29
|
var wonderBlocksLayout = require('@khanacademy/wonder-blocks-layout');
|
|
30
30
|
var wonderBlocksPopover = require('@khanacademy/wonder-blocks-popover');
|
|
31
31
|
var wonderBlocksDropdown = require('@khanacademy/wonder-blocks-dropdown');
|
|
@@ -2185,7 +2185,7 @@ function widgetShouldHighlight(widget) {
|
|
|
2185
2185
|
|
|
2186
2186
|
switch (widget.type) {
|
|
2187
2187
|
/**
|
|
2188
|
-
* Highlight bar
|
|
2188
|
+
* Highlight bar denylist
|
|
2189
2189
|
*/
|
|
2190
2190
|
case "measurer":
|
|
2191
2191
|
case "protractor":
|
|
@@ -14539,6 +14539,26 @@ var iconPaths = /*#__PURE__*/Object.freeze({
|
|
|
14539
14539
|
iconMinus: iconMinus
|
|
14540
14540
|
});
|
|
14541
14541
|
|
|
14542
|
+
function render(element, container, callback) {
|
|
14543
|
+
// TODO(LP-11406): Replace this, or callers, with React Portal
|
|
14544
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
14545
|
+
return ReactDOM__default["default"].render(
|
|
14546
|
+
/*#__PURE__*/
|
|
14547
|
+
|
|
14548
|
+
/**
|
|
14549
|
+
* `RenderStateRoot` is responsible for tracking whether it's
|
|
14550
|
+
* the initial render or subsequent renders. It's used by
|
|
14551
|
+
* `useUniqueId` and will be used by `UniqueIDProvider` and
|
|
14552
|
+
* `WithSSRPlaceholder` in the future. We're placing it as
|
|
14553
|
+
* high up in the render tree as possible to ensure that any
|
|
14554
|
+
* components using that hook or those components will function
|
|
14555
|
+
* correctly.
|
|
14556
|
+
*/
|
|
14557
|
+
React__namespace.createElement(wonderBlocksCore.RenderStateRoot, {
|
|
14558
|
+
throwIfNested: false
|
|
14559
|
+
}, element), container, callback);
|
|
14560
|
+
}
|
|
14561
|
+
|
|
14542
14562
|
/* eslint-disable @babel/no-invalid-this */
|
|
14543
14563
|
const add$1 = {
|
|
14544
14564
|
constrain: function () {
|
|
@@ -14866,9 +14886,7 @@ ___default["default"].extend(MovablePoint$5.prototype, {
|
|
|
14866
14886
|
|
|
14867
14887
|
const showTrashTooltip = () => {
|
|
14868
14888
|
this._showTooltip(container => {
|
|
14869
|
-
|
|
14870
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
14871
|
-
ReactDOM__namespace.render( /*#__PURE__*/React__namespace.createElement("span", {
|
|
14889
|
+
render( /*#__PURE__*/React__namespace.createElement("span", {
|
|
14872
14890
|
style: {
|
|
14873
14891
|
fontSize: "2em"
|
|
14874
14892
|
}
|
|
@@ -19201,7 +19219,7 @@ class WidgetContainer extends React__namespace.Component {
|
|
|
19201
19219
|
highlightLint: false
|
|
19202
19220
|
}; // Note: if you add more props here, please consider whether or not
|
|
19203
19221
|
// it should be auto-serialized (e.g. used in scoreInput()). See
|
|
19204
|
-
// widget-jsonify-deprecated.jsx and widget-prop-
|
|
19222
|
+
// widget-jsonify-deprecated.jsx and widget-prop-denylist.jsx
|
|
19205
19223
|
// We default to an empty object for style instead of null
|
|
19206
19224
|
// because of a strange bug where the static styles aren't applied
|
|
19207
19225
|
// after toggling static mode.
|
|
@@ -22156,9 +22174,7 @@ _defineProperty(InputWithExamples, "defaultProps", {
|
|
|
22156
22174
|
* automatically serializing schemaless list of attributes causes issues (e.g.
|
|
22157
22175
|
* circular JSON structures sometimes).
|
|
22158
22176
|
*
|
|
22159
|
-
* This
|
|
22160
|
-
*
|
|
22161
|
-
* TODO(TB): Go through and update usage of BLACKLIST to DENYLIST: https://khanacademy.atlassian.net/browse/LP-13149?atlOrigin=eyJpIjoiNTI0Y2UwNzQ0MzA4NDYzOGI1YWRmNjEwY2E5YzZlZWUiLCJwIjoiaiJ9
|
|
22177
|
+
* This blocks things that we know don't need to be serialized.
|
|
22162
22178
|
*/
|
|
22163
22179
|
const denylist = [// standard props "added" by react
|
|
22164
22180
|
// (technically the renderer still adds them)
|
|
@@ -26209,7 +26225,7 @@ class PassageRef extends React__namespace.Component {
|
|
|
26209
26225
|
|
|
26210
26226
|
shouldComponentUpdate(nextProps, nextState) {
|
|
26211
26227
|
return !___default["default"].isEqual(this.props, nextProps) || !___default["default"].isEqual(this.state, nextState);
|
|
26212
|
-
} // TODO(
|
|
26228
|
+
} // TODO(tamarab): getUserInput needs to be updated to only return
|
|
26213
26229
|
// props input by the user. Currently returns all the widget's props.
|
|
26214
26230
|
|
|
26215
26231
|
|
|
@@ -28530,7 +28546,9 @@ class Categorizer extends React__namespace.Component {
|
|
|
28530
28546
|
|
|
28531
28547
|
const table = /*#__PURE__*/React__namespace.createElement("table", {
|
|
28532
28548
|
className: "categorizer-table " + aphrodite.css(styles$m.mobileTable)
|
|
28533
|
-
}, /*#__PURE__*/React__namespace.createElement("thead", null, /*#__PURE__*/React__namespace.createElement("tr", null, /*#__PURE__*/React__namespace.createElement("
|
|
28549
|
+
}, /*#__PURE__*/React__namespace.createElement("thead", null, /*#__PURE__*/React__namespace.createElement("tr", null, /*#__PURE__*/React__namespace.createElement("td", {
|
|
28550
|
+
className: aphrodite.css(styles$m.emptyHeaderCell)
|
|
28551
|
+
}), this.props.categories.map((category, i) => {
|
|
28534
28552
|
// Array index is the correct key here, as that's
|
|
28535
28553
|
// how category grading actually works -- no way
|
|
28536
28554
|
// to add or remove categories or items in the
|
|
@@ -28658,6 +28676,10 @@ const styles$m = aphrodite.StyleSheet.create({
|
|
|
28658
28676
|
color: "#ccc",
|
|
28659
28677
|
verticalAlign: "middle"
|
|
28660
28678
|
},
|
|
28679
|
+
emptyHeaderCell: {
|
|
28680
|
+
backgroundColor: "inherit",
|
|
28681
|
+
borderBottom: "2px solid #ccc"
|
|
28682
|
+
},
|
|
28661
28683
|
radioSpan: {
|
|
28662
28684
|
fontSize: 30,
|
|
28663
28685
|
paddingRight: 3,
|
|
@@ -28893,7 +28915,7 @@ class CSProgram extends React__namespace.Component {
|
|
|
28893
28915
|
url = updateQueryString$1(url, "settings", JSON.stringify(settings));
|
|
28894
28916
|
}
|
|
28895
28917
|
|
|
28896
|
-
const sandboxOptions = ["allow-popups", "allow-same-origin", "allow-scripts", "allow-top-navigation"].join(" "); // We sandbox the iframe so that we
|
|
28918
|
+
const sandboxOptions = ["allow-popups", "allow-same-origin", "allow-scripts", "allow-top-navigation"].join(" "); // We sandbox the iframe so that we allowlist only the functionality
|
|
28897
28919
|
// that we need. This makes it a bit safer in case some content
|
|
28898
28920
|
// creator "went wild".
|
|
28899
28921
|
// http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/
|
|
@@ -29771,7 +29793,7 @@ const styles$h = aphrodite.StyleSheet.create({
|
|
|
29771
29793
|
padding: 0,
|
|
29772
29794
|
border: "none",
|
|
29773
29795
|
marginTop: 20,
|
|
29774
|
-
color:
|
|
29796
|
+
color: Color__default["default"].blue,
|
|
29775
29797
|
cursor: "pointer",
|
|
29776
29798
|
display: "block",
|
|
29777
29799
|
clear: "both"
|
|
@@ -29779,7 +29801,7 @@ const styles$h = aphrodite.StyleSheet.create({
|
|
|
29779
29801
|
explanationTitle: {
|
|
29780
29802
|
backgroundColor: "unset",
|
|
29781
29803
|
marginTop: 20,
|
|
29782
|
-
color:
|
|
29804
|
+
color: Color__default["default"].blue,
|
|
29783
29805
|
marginBottom: 10,
|
|
29784
29806
|
cursor: "pointer",
|
|
29785
29807
|
fontSize: 14,
|
|
@@ -29809,29 +29831,38 @@ var GradedGroup$2 = {
|
|
|
29809
29831
|
|
|
29810
29832
|
const GradedGroup = GradedGroup$2.widget;
|
|
29811
29833
|
|
|
29812
|
-
// TODO(jeremy): This indicator panel is not accessible for keyboard
|
|
29813
|
-
// navigation. Add in keyboard handling and tab indexes to make accessible.
|
|
29814
29834
|
class Indicators extends React__namespace.Component {
|
|
29815
|
-
|
|
29816
|
-
|
|
29835
|
+
constructor() {
|
|
29836
|
+
super(...arguments);
|
|
29837
|
+
|
|
29838
|
+
_defineProperty(this, "handleKeyDown", (e, i) => {
|
|
29839
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
29840
|
+
this.props.onChangeCurrentGroup(i);
|
|
29841
|
+
}
|
|
29842
|
+
});
|
|
29843
|
+
}
|
|
29817
29844
|
|
|
29818
|
-
|
|
29819
|
-
|
|
29845
|
+
render() {
|
|
29846
|
+
return /*#__PURE__*/React__namespace.createElement("ul", {
|
|
29847
|
+
className: aphrodite.css(styles$g.indicatorContainer)
|
|
29848
|
+
}, this.props.gradedGroups.map((_ref, i) => {
|
|
29849
|
+
let {
|
|
29850
|
+
title
|
|
29851
|
+
} = _ref;
|
|
29852
|
+
return /*#__PURE__*/React__namespace.createElement("li", {
|
|
29820
29853
|
role: "button",
|
|
29821
29854
|
"aria-label": i18n__namespace._("Skip to %(title)s", {
|
|
29822
|
-
title
|
|
29855
|
+
title
|
|
29823
29856
|
}),
|
|
29824
|
-
key:
|
|
29857
|
+
key: title,
|
|
29825
29858
|
className: aphrodite.css(styles$g.indicator, i === this.props.currentGroup && styles$g.selectedIndicator),
|
|
29826
|
-
|
|
29859
|
+
tabIndex: 0,
|
|
29860
|
+
onClick: () => this.props.onChangeCurrentGroup(i),
|
|
29861
|
+
onKeyDown: e => this.handleKeyDown(e, i)
|
|
29827
29862
|
}, i === this.props.currentGroup && /*#__PURE__*/React__namespace.createElement("span", {
|
|
29828
29863
|
className: aphrodite.css(a11y.srOnly)
|
|
29829
|
-
}, i18n__namespace._("Current")))
|
|
29830
|
-
}
|
|
29831
|
-
|
|
29832
|
-
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
29833
|
-
className: aphrodite.css(styles$g.indicatorContainer)
|
|
29834
|
-
}, items);
|
|
29864
|
+
}, i18n__namespace._("Current")));
|
|
29865
|
+
}));
|
|
29835
29866
|
}
|
|
29836
29867
|
|
|
29837
29868
|
}
|
|
@@ -29945,9 +29976,8 @@ class GradedGroupSet extends React__namespace.Component {
|
|
|
29945
29976
|
}, currentGroup.title), /*#__PURE__*/React__namespace.createElement("div", {
|
|
29946
29977
|
className: aphrodite.css(styles$g.spacer)
|
|
29947
29978
|
}), /*#__PURE__*/React__namespace.createElement(Indicators, {
|
|
29948
|
-
numGroups: numGroups,
|
|
29949
29979
|
currentGroup: this.state.currentGroup,
|
|
29950
|
-
|
|
29980
|
+
gradedGroups: this.props.gradedGroups,
|
|
29951
29981
|
onChangeCurrentGroup: currentGroup => this.setState({
|
|
29952
29982
|
currentGroup
|
|
29953
29983
|
})
|
|
@@ -30000,25 +30030,28 @@ const styles$g = aphrodite.StyleSheet.create({
|
|
|
30000
30030
|
},
|
|
30001
30031
|
title: {
|
|
30002
30032
|
fontSize: 12,
|
|
30003
|
-
color:
|
|
30033
|
+
color: Color__default["default"].offBlack64,
|
|
30004
30034
|
textTransform: "uppercase",
|
|
30005
30035
|
marginBottom: 11,
|
|
30006
30036
|
letterSpacing: 0.8
|
|
30007
30037
|
},
|
|
30008
30038
|
indicatorContainer: {
|
|
30009
30039
|
display: "flex",
|
|
30010
|
-
flexDirection: "row"
|
|
30040
|
+
flexDirection: "row",
|
|
30041
|
+
listStyle: "none",
|
|
30042
|
+
margin: "unset"
|
|
30011
30043
|
},
|
|
30012
30044
|
indicator: {
|
|
30013
30045
|
width: 10,
|
|
30014
30046
|
height: 10,
|
|
30015
|
-
borderRadius:
|
|
30016
|
-
|
|
30047
|
+
borderRadius: "100%",
|
|
30048
|
+
border: "3px solid",
|
|
30049
|
+
borderColor: Color__default["default"].blue,
|
|
30017
30050
|
marginLeft: 5,
|
|
30018
30051
|
cursor: "pointer"
|
|
30019
30052
|
},
|
|
30020
30053
|
selectedIndicator: {
|
|
30021
|
-
backgroundColor:
|
|
30054
|
+
backgroundColor: Color__default["default"].blue
|
|
30022
30055
|
},
|
|
30023
30056
|
container: {
|
|
30024
30057
|
borderTop: "1px solid ".concat(gray76),
|
|
@@ -31492,7 +31525,7 @@ class Iframe extends React__namespace.Component {
|
|
|
31492
31525
|
sandboxProperties += " allow-top-navigation"; // if (this.props.allowTopNavigation === true) {
|
|
31493
31526
|
// sandboxProperties += " allow-top-navigation";
|
|
31494
31527
|
// }
|
|
31495
|
-
// We sandbox the iframe so that we
|
|
31528
|
+
// We sandbox the iframe so that we allowlist only the functionality
|
|
31496
31529
|
// that we need. This makes it a bit safer in case some content
|
|
31497
31530
|
// creator "went wild".
|
|
31498
31531
|
// http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/
|
|
@@ -48287,10 +48320,8 @@ const ProvideKeypad = {
|
|
|
48287
48320
|
// React tree. We may also want to add this keypad asynchronously
|
|
48288
48321
|
// or on-demand in the future.
|
|
48289
48322
|
_this._keypadContainer = document.createElement("div");
|
|
48290
|
-
(_document$body = document.body) === null || _document$body === void 0 ? void 0 : _document$body.appendChild(_this._keypadContainer);
|
|
48291
|
-
|
|
48292
|
-
|
|
48293
|
-
ReactDOM__default["default"].render( /*#__PURE__*/React__namespace.createElement(mathInput.Keypad, {
|
|
48323
|
+
(_document$body = document.body) === null || _document$body === void 0 ? void 0 : _document$body.appendChild(_this._keypadContainer);
|
|
48324
|
+
render( /*#__PURE__*/React__namespace.createElement(mathInput.Keypad, {
|
|
48294
48325
|
onElementMounted: element => {
|
|
48295
48326
|
// NOTE(kevinb): The reason why this setState works is
|
|
48296
48327
|
// b/c we're calling it manually from item-renderer.jsx
|
|
@@ -48986,11 +49017,9 @@ class ItemRenderer extends React__namespace.Component {
|
|
|
48986
49017
|
// that have completely different places in the DOM, we have to do this
|
|
48987
49018
|
// strangeness instead of relying on React's normal render() method.
|
|
48988
49019
|
// TODO(alpert): Figure out how to clean this up somehow
|
|
48989
|
-
// TODO(LP-11406): Replace with React Portal
|
|
48990
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
48991
49020
|
|
|
48992
49021
|
|
|
48993
|
-
|
|
49022
|
+
render(
|
|
48994
49023
|
/*#__PURE__*/
|
|
48995
49024
|
// metadata (from item.question, aka PerseusRenderer)
|
|
48996
49025
|
// replace (also item.question, aka PerseusRenderer)
|
|
@@ -49025,10 +49054,8 @@ class ItemRenderer extends React__namespace.Component {
|
|
|
49025
49054
|
linterContext: PerseusLinter__namespace.pushContextStack(this.props.linterContext, "question")
|
|
49026
49055
|
}, this.props.item.question, {
|
|
49027
49056
|
legacyPerseusLint: this.props.legacyPerseusLint
|
|
49028
|
-
})), workArea);
|
|
49029
|
-
|
|
49030
|
-
|
|
49031
|
-
ReactDOM__namespace.render( /*#__PURE__*/React__namespace.createElement(HintsRenderer, {
|
|
49057
|
+
})), workArea);
|
|
49058
|
+
render( /*#__PURE__*/React__namespace.createElement(HintsRenderer, {
|
|
49032
49059
|
ref: node => this.hintsRenderer = node,
|
|
49033
49060
|
hints: this.props.item.hints,
|
|
49034
49061
|
hintsVisible: this.state.hintsVisible,
|
|
@@ -51378,7 +51405,7 @@ exports.SizingUtils = sizingUtils;
|
|
|
51378
51405
|
exports.TableWidget = Table$1;
|
|
51379
51406
|
exports.TransformerWidget = Transformer$1;
|
|
51380
51407
|
exports.Util = Util;
|
|
51381
|
-
exports.
|
|
51408
|
+
exports.WIDGET_PROP_DENYLIST = denylist;
|
|
51382
51409
|
exports.WidgetJsonifyDeprecated = WidgetJsonifyDeprecated;
|
|
51383
51410
|
exports.Widgets = widgets$1;
|
|
51384
51411
|
exports.apiVersion = apiVersion;
|