@khanacademy/perseus-editor 2.16.2 → 3.0.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/components/widget-editor.d.ts +4 -4
- package/dist/editor.d.ts +5 -5
- package/dist/es/index.js +42 -38
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +29 -25
- package/dist/index.js.map +1 -1
- package/dist/widgets/deprecated-standin-editor.d.ts +10 -0
- package/package.json +2 -2
- package/src/__tests__/editor.test.tsx +120 -98
- package/src/__tests__/hint-editor.test.tsx +83 -0
- package/src/all-editors.ts +2 -0
- package/src/components/widget-editor.tsx +10 -22
- package/src/editor.tsx +35 -31
- package/src/hint-editor.tsx +5 -0
- package/src/index.ts +4 -0
- package/src/util/register-all-widgets-and-editors-for-testing.ts +4 -0
- package/src/widgets/deprecated-standin-editor.tsx +29 -0
- package/tsconfig-build.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @khanacademy/perseus-editor
|
|
2
2
|
|
|
3
|
+
## 3.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [#933](https://github.com/Khan/perseus/pull/933) [`851c2cb8`](https://github.com/Khan/perseus/commit/851c2cb8cd6f6c0d6a62343f9232cc618476b85e) Thanks [@handeyeco](https://github.com/handeyeco)! - Update external and internal facing Perseus types
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [[`851c2cb8`](https://github.com/Khan/perseus/commit/851c2cb8cd6f6c0d6a62343f9232cc618476b85e), [`f7ac2929`](https://github.com/Khan/perseus/commit/f7ac2929ac18e6fd18b1e6c460350d5119762b42), [`87bfcc6f`](https://github.com/Khan/perseus/commit/87bfcc6f4a59a95027d76018625802726aa0d309), [`738aa661`](https://github.com/Khan/perseus/commit/738aa6613fdf752b8a4348c43690666fb5f0531f), [`d95e7044`](https://github.com/Khan/perseus/commit/d95e70444e2d038460a3b3fbe4e3c5aa4f4bd41d), [`6c3b6afe`](https://github.com/Khan/perseus/commit/6c3b6afea87f95bc3dc1da78cc0ddd29418d14dc), [`1e179194`](https://github.com/Khan/perseus/commit/1e179194e9674b267be11c280f80faa5cc671d91), [`4c2c2abc`](https://github.com/Khan/perseus/commit/4c2c2abc9c8dbe57a0036ff7873926ef5ecdd6e6), [`544ca540`](https://github.com/Khan/perseus/commit/544ca540469b2d0b34a8d00de256872d32648fda), [`76ebdc76`](https://github.com/Khan/perseus/commit/76ebdc7620a2f1ffe28524f95a99a13393162951), [`237593b8`](https://github.com/Khan/perseus/commit/237593b8d5bd36148cb5adabf51a796acf8f81a4)]:
|
|
12
|
+
- @khanacademy/perseus@18.0.0
|
|
13
|
+
|
|
14
|
+
## 2.17.0
|
|
15
|
+
|
|
16
|
+
### Minor Changes
|
|
17
|
+
|
|
18
|
+
- [#894](https://github.com/Khan/perseus/pull/894) [`49d5c821`](https://github.com/Khan/perseus/commit/49d5c821a2ad07aadf31f09f2814859de2c0f157) Thanks [@jeremywiebe](https://github.com/jeremywiebe)! - Add a confirmation before deleting a configured widget in the Exercise Editor
|
|
19
|
+
|
|
20
|
+
* [#896](https://github.com/Khan/perseus/pull/896) [`04981063`](https://github.com/Khan/perseus/commit/049810636968afac5672f790896768338319810a) Thanks [@jeremywiebe](https://github.com/jeremywiebe)! - Add a confirmation before deleting a hint in the Exercise Editor
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- Updated dependencies [[`a5479339`](https://github.com/Khan/perseus/commit/a547933946b8be33b388fa4654d87289734848f0)]:
|
|
25
|
+
- @khanacademy/perseus@17.8.0
|
|
26
|
+
|
|
3
27
|
## 2.16.2
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import type {
|
|
2
|
+
import type { PerseusWidget } from "@khanacademy/perseus";
|
|
3
3
|
type WidgetEditorProps = {
|
|
4
4
|
id: string;
|
|
5
|
-
onChange: (widgetInfo:
|
|
5
|
+
onChange: (widgetInfo: PerseusWidget, cb?: () => unknown, silent?: boolean) => unknown;
|
|
6
6
|
onRemove: () => unknown;
|
|
7
7
|
apiOptions: any;
|
|
8
|
-
} &
|
|
8
|
+
} & PerseusWidget;
|
|
9
9
|
type WidgetEditorState = {
|
|
10
10
|
showWidget: boolean;
|
|
11
|
-
widgetInfo:
|
|
11
|
+
widgetInfo: PerseusWidget;
|
|
12
12
|
};
|
|
13
13
|
declare class WidgetEditor extends React.Component<WidgetEditorProps, WidgetEditorState> {
|
|
14
14
|
constructor(props: WidgetEditorProps);
|
package/dist/editor.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "./katex-mhchem";
|
|
2
2
|
import * as React from "react";
|
|
3
|
-
import type { ChangeHandler,
|
|
3
|
+
import type { ChangeHandler, PerseusWidget } from "@khanacademy/perseus";
|
|
4
4
|
type Props = Readonly<{
|
|
5
5
|
apiOptions: any;
|
|
6
6
|
className?: string;
|
|
@@ -8,7 +8,7 @@ type Props = Readonly<{
|
|
|
8
8
|
replace?: any;
|
|
9
9
|
placeholder: string;
|
|
10
10
|
widgets: {
|
|
11
|
-
[name: string]:
|
|
11
|
+
[name: string]: PerseusWidget;
|
|
12
12
|
};
|
|
13
13
|
images: any;
|
|
14
14
|
disabled: boolean;
|
|
@@ -31,7 +31,7 @@ type DefaultProps = {
|
|
|
31
31
|
warnNoWidgets: boolean;
|
|
32
32
|
widgetEnabled: boolean;
|
|
33
33
|
widgets: {
|
|
34
|
-
[name: string]:
|
|
34
|
+
[name: string]: PerseusWidget;
|
|
35
35
|
};
|
|
36
36
|
};
|
|
37
37
|
type State = {
|
|
@@ -49,8 +49,8 @@ declare class Editor extends React.Component<Props, State> {
|
|
|
49
49
|
UNSAFE_componentWillReceiveProps(nextProps: Props): void;
|
|
50
50
|
componentDidUpdate(prevProps: Props): void;
|
|
51
51
|
componentWillUnmount(): void;
|
|
52
|
-
getWidgetEditor
|
|
53
|
-
_handleWidgetEditorChange: (id: string, newWidgetInfo:
|
|
52
|
+
getWidgetEditor(id: string, type: PerseusWidget["type"]): undefined | React.ReactNode;
|
|
53
|
+
_handleWidgetEditorChange: (id: string, newWidgetInfo: PerseusWidget, cb?: () => unknown, silent?: boolean) => void;
|
|
54
54
|
_handleWidgetEditorRemove: (id: string) => void;
|
|
55
55
|
/**
|
|
56
56
|
* Calculate the size of all the images in props.content, and send
|
package/dist/es/index.js
CHANGED
|
@@ -25,7 +25,7 @@ import * as i18n$1 from '@khanacademy/wonder-blocks-i18n';
|
|
|
25
25
|
|
|
26
26
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
27
27
|
const libName = "@khanacademy/perseus-editor";
|
|
28
|
-
const libVersion = "
|
|
28
|
+
const libVersion = "3.0.0";
|
|
29
29
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
30
30
|
|
|
31
31
|
function _extends() {
|
|
@@ -20550,8 +20550,7 @@ const DragTarget = createReactClass({
|
|
|
20550
20550
|
});
|
|
20551
20551
|
|
|
20552
20552
|
const {
|
|
20553
|
-
InlineIcon: InlineIcon$b
|
|
20554
|
-
PropCheckBox: PropCheckBox$e
|
|
20553
|
+
InlineIcon: InlineIcon$b
|
|
20555
20554
|
} = components;
|
|
20556
20555
|
const {
|
|
20557
20556
|
iconChevronDown: iconChevronDown$1,
|
|
@@ -20562,7 +20561,7 @@ const _upgradeWidgetInfo = props => {
|
|
|
20562
20561
|
// We can't call serialize here because this.refs.widget
|
|
20563
20562
|
// doesn't exist before this component is mounted.
|
|
20564
20563
|
const filteredProps = _.omit(props, WIDGET_PROP_DENYLIST);
|
|
20565
|
-
// @ts-expect-error
|
|
20564
|
+
// @ts-expect-error TS(2345) Type '"categorizer" | undefined' is not assignable to type '"deprecated-standin"'.
|
|
20566
20565
|
return Widgets.upgradeWidgetInfoToLatestVersion(filteredProps);
|
|
20567
20566
|
};
|
|
20568
20567
|
|
|
@@ -20625,14 +20624,12 @@ class WidgetEditor extends React.Component {
|
|
|
20625
20624
|
};
|
|
20626
20625
|
this.state = {
|
|
20627
20626
|
showWidget: false,
|
|
20628
|
-
// @ts-expect-error - TS2322 - Type 'ReactElement<any, any> | null' is not assignable to type 'PerseusWidget'.
|
|
20629
20627
|
widgetInfo: _upgradeWidgetInfo(props)
|
|
20630
20628
|
};
|
|
20631
20629
|
}
|
|
20632
20630
|
|
|
20633
20631
|
// eslint-disable-next-line react/no-unsafe
|
|
20634
20632
|
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
20635
|
-
// @ts-expect-error - TS2322 - Type 'ReactElement<any, any> | null' is not assignable to type 'PerseusWidget'.
|
|
20636
20633
|
this.setState({
|
|
20637
20634
|
widgetInfo: _upgradeWidgetInfo(nextProps)
|
|
20638
20635
|
});
|
|
@@ -20648,12 +20645,6 @@ class WidgetEditor extends React.Component {
|
|
|
20648
20645
|
supportedAlignments = ["default"];
|
|
20649
20646
|
}
|
|
20650
20647
|
const supportsStaticMode = Widgets.supportsStaticMode(widgetInfo.type);
|
|
20651
|
-
const isUngradedEnabled = widgetInfo.type === "transformer";
|
|
20652
|
-
const gradedPropBox = /*#__PURE__*/React.createElement(PropCheckBox$e, {
|
|
20653
|
-
label: "Graded:",
|
|
20654
|
-
graded: widgetInfo.graded,
|
|
20655
|
-
onChange: this.props.onChange
|
|
20656
|
-
});
|
|
20657
20648
|
return /*#__PURE__*/React.createElement("div", {
|
|
20658
20649
|
className: "perseus-widget-editor"
|
|
20659
20650
|
}, /*#__PURE__*/React.createElement("div", {
|
|
@@ -20683,7 +20674,7 @@ class WidgetEditor extends React.Component {
|
|
|
20683
20674
|
title: "Remove image widget"
|
|
20684
20675
|
})), /*#__PURE__*/React.createElement("div", {
|
|
20685
20676
|
className: "perseus-widget-editor-content " + (this.state.showWidget ? "enter" : "leave")
|
|
20686
|
-
},
|
|
20677
|
+
}, Ed && /*#__PURE__*/React.createElement(Ed
|
|
20687
20678
|
// eslint-disable-next-line react/no-string-refs
|
|
20688
20679
|
, _extends({
|
|
20689
20680
|
ref: "widget",
|
|
@@ -20893,28 +20884,6 @@ class Editor extends React.Component {
|
|
|
20893
20884
|
this.state = {
|
|
20894
20885
|
textAreaValue: this.props.content
|
|
20895
20886
|
};
|
|
20896
|
-
this.getWidgetEditor = (id, type) => {
|
|
20897
|
-
if (!Widgets.getEditor(type)) {
|
|
20898
|
-
return;
|
|
20899
|
-
}
|
|
20900
|
-
return /*#__PURE__*/React.createElement(WidgetEditor
|
|
20901
|
-
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'number | undefined'.
|
|
20902
|
-
, _extends({
|
|
20903
|
-
key: id,
|
|
20904
|
-
ref: id,
|
|
20905
|
-
id: id
|
|
20906
|
-
// @ts-expect-error - TS2783 - 'type' is specified more than once, so this usage will be overwritten.
|
|
20907
|
-
,
|
|
20908
|
-
type: type
|
|
20909
|
-
// eslint-disable-next-line react/jsx-no-bind
|
|
20910
|
-
,
|
|
20911
|
-
onChange: this._handleWidgetEditorChange.bind(this, id)
|
|
20912
|
-
// eslint-disable-next-line react/jsx-no-bind
|
|
20913
|
-
,
|
|
20914
|
-
onRemove: this._handleWidgetEditorRemove.bind(this, id),
|
|
20915
|
-
apiOptions: this.props.apiOptions
|
|
20916
|
-
}, this.props.widgets[id]));
|
|
20917
|
-
};
|
|
20918
20887
|
this._handleWidgetEditorChange = (id, newWidgetInfo, cb, silent) => {
|
|
20919
20888
|
const widgets = Object.assign({}, this.props.widgets);
|
|
20920
20889
|
widgets[id] = Object.assign({}, widgets[id], newWidgetInfo);
|
|
@@ -20923,6 +20892,10 @@ class Editor extends React.Component {
|
|
|
20923
20892
|
}, cb, silent);
|
|
20924
20893
|
};
|
|
20925
20894
|
this._handleWidgetEditorRemove = id => {
|
|
20895
|
+
// eslint-disable-next-line no-alert
|
|
20896
|
+
if (!confirm("Are you sure you want to delete this item?")) {
|
|
20897
|
+
return;
|
|
20898
|
+
}
|
|
20926
20899
|
const textarea = this.textarea.current;
|
|
20927
20900
|
const re = new RegExp(widgetRegExp.replace("{id}", id), "gm");
|
|
20928
20901
|
this.props.onChange({
|
|
@@ -21240,14 +21213,13 @@ class Editor extends React.Component {
|
|
|
21240
21213
|
const newPostlude = isBlock ? makeStartWithAParagraphAlways(postlude) : postlude;
|
|
21241
21214
|
const newContent = newPrelude + widgetContent + newPostlude;
|
|
21242
21215
|
const newWidgets = _.clone(this.props.widgets);
|
|
21216
|
+
// @ts-expect-error TS(2345) Type '"categorizer" | undefined' is not assignable to type '"deprecated-standin"'.
|
|
21243
21217
|
newWidgets[id] = {
|
|
21244
21218
|
options: (_Widgets$getEditor = Widgets.getEditor(widgetType)) == null ? void 0 : _Widgets$getEditor.defaultProps,
|
|
21245
|
-
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type '"video" | "image" | "iframe" | "table" | "radio" | "definition" | "group" | "matrix" | "categorizer" | "cs-program" | "dropdown" | "example-graphie-widget" | "example-widget" | ... 26 more ... | "unit-input"'.
|
|
21246
21219
|
type: widgetType,
|
|
21247
21220
|
// Track widget version on creation, so that a widget editor
|
|
21248
21221
|
// without a valid version prop can only possibly refer to a
|
|
21249
21222
|
// pre-versioning creation time.
|
|
21250
|
-
// @ts-expect-error - TS2322 - Type 'Version | null | undefined' is not assignable to type 'Version | undefined'.
|
|
21251
21223
|
version: Widgets.getVersion(widgetType)
|
|
21252
21224
|
};
|
|
21253
21225
|
|
|
@@ -21434,6 +21406,22 @@ class Editor extends React.Component {
|
|
|
21434
21406
|
// eslint-disable-next-line no-restricted-syntax
|
|
21435
21407
|
clearTimeout(this.deferredChange);
|
|
21436
21408
|
}
|
|
21409
|
+
getWidgetEditor(id, type) {
|
|
21410
|
+
if (!Widgets.getEditor(type)) {
|
|
21411
|
+
return;
|
|
21412
|
+
}
|
|
21413
|
+
return /*#__PURE__*/React.createElement(WidgetEditor, _extends({
|
|
21414
|
+
ref: id,
|
|
21415
|
+
id: id
|
|
21416
|
+
// eslint-disable-next-line react/jsx-no-bind
|
|
21417
|
+
,
|
|
21418
|
+
onChange: this._handleWidgetEditorChange.bind(this, id)
|
|
21419
|
+
// eslint-disable-next-line react/jsx-no-bind
|
|
21420
|
+
,
|
|
21421
|
+
onRemove: this._handleWidgetEditorRemove.bind(this, id),
|
|
21422
|
+
apiOptions: this.props.apiOptions
|
|
21423
|
+
}, this.props.widgets[id]));
|
|
21424
|
+
}
|
|
21437
21425
|
render() {
|
|
21438
21426
|
let pieces;
|
|
21439
21427
|
let widgets;
|
|
@@ -21456,6 +21444,8 @@ class Editor extends React.Component {
|
|
|
21456
21444
|
widgets = {};
|
|
21457
21445
|
underlayPieces = [];
|
|
21458
21446
|
for (let i = 0; i < pieces.length; i++) {
|
|
21447
|
+
// We split on widgets so every even-numbered indexed piece is
|
|
21448
|
+
// text and odd-numbered indexes are the widget references.
|
|
21459
21449
|
if (i % 2 === 0) {
|
|
21460
21450
|
// Normal text
|
|
21461
21451
|
underlayPieces.push(pieces[i]);
|
|
@@ -23658,6 +23648,10 @@ class CombinedHintsEditor extends React.Component {
|
|
|
23658
23648
|
}, cb, silent);
|
|
23659
23649
|
};
|
|
23660
23650
|
this.handleHintRemove = i => {
|
|
23651
|
+
// eslint-disable-next-line no-alert
|
|
23652
|
+
if (!confirm("Are you sure you want to delete this hint?")) {
|
|
23653
|
+
return;
|
|
23654
|
+
}
|
|
23661
23655
|
const hints = _(this.props.hints).clone();
|
|
23662
23656
|
// @ts-expect-error - TS2339 - Property 'splice' does not exist on type 'Hint'.
|
|
23663
23657
|
hints.splice(i, 1);
|
|
@@ -26145,6 +26139,16 @@ DefinitionEditor.defaultProps = {
|
|
|
26145
26139
|
definition: ""
|
|
26146
26140
|
};
|
|
26147
26141
|
|
|
26142
|
+
class DeprecatedStandinEditor extends React.Component {
|
|
26143
|
+
serialize() {
|
|
26144
|
+
return EditorJsonify.serialize.call(this);
|
|
26145
|
+
}
|
|
26146
|
+
render() {
|
|
26147
|
+
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("p", null, "This widget has been deprecated and removed"), /*#__PURE__*/React.createElement("p", null, "Learners will see a message and they will not be graded on this part. Please replace this widget with a supported one."));
|
|
26148
|
+
}
|
|
26149
|
+
}
|
|
26150
|
+
DeprecatedStandinEditor.widgetName = "deprecated-standin";
|
|
26151
|
+
|
|
26148
26152
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
26149
26153
|
const {
|
|
26150
26154
|
InfoTip: InfoTip$k,
|
|
@@ -35206,7 +35210,7 @@ VideoEditor.defaultProps = {
|
|
|
35206
35210
|
location: ""
|
|
35207
35211
|
};
|
|
35208
35212
|
|
|
35209
|
-
var AllEditors = [CategorizerEditor, CSProgramEditor, DefinitionEditor, DropdownEditor, ExampleGraphieWidgetEditor, ExampleWidgetEditor, ExplanationEditor, ExpressionEditor, GradedGroupEditor, GradedGroupSetEditor, GrapherEditor, GroupEditor, IframeEditor, ImageEditor, InputNumberEditor, InteractionEditor, InteractiveGraphEditor, LabelImageEditor, LightsPuzzleEditor, MatcherEditor, MatrixEditor, MeasurerEditor, MoleculeWidgetEditor, NumberLineEditor, NumericInputEditor, OrdererEditor, PassageEditor, PassageRefEditor, PassageRefTargetEditor, PlotterEditor, ReactionDiagramWidgetEditor, SequenceEditor, SimpleMarkdownTesterEditor, SimulatorEditor, SorterEditor, TableEditor, TransformerEditor, UnitInputEditor, VideoEditor, RadioEditor];
|
|
35213
|
+
var AllEditors = [CategorizerEditor, CSProgramEditor, DefinitionEditor, DropdownEditor, ExampleGraphieWidgetEditor, ExampleWidgetEditor, ExplanationEditor, ExpressionEditor, GradedGroupEditor, GradedGroupSetEditor, GrapherEditor, GroupEditor, IframeEditor, ImageEditor, InputNumberEditor, InteractionEditor, InteractiveGraphEditor, LabelImageEditor, LightsPuzzleEditor, MatcherEditor, MatrixEditor, MeasurerEditor, MoleculeWidgetEditor, NumberLineEditor, NumericInputEditor, OrdererEditor, PassageEditor, PassageRefEditor, PassageRefTargetEditor, PlotterEditor, ReactionDiagramWidgetEditor, SequenceEditor, SimpleMarkdownTesterEditor, SimulatorEditor, SorterEditor, TableEditor, TransformerEditor, UnitInputEditor, VideoEditor, RadioEditor, DeprecatedStandinEditor];
|
|
35210
35214
|
|
|
35211
35215
|
class TextInput extends React.Component {
|
|
35212
35216
|
constructor(...args) {
|