@khanacademy/perseus-editor 4.1.5 → 4.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/es/index.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +9 -6
- package/.babelrc.js +0 -8
- package/.eslintrc.js +0 -12
- package/CHANGELOG.md +0 -1155
- package/src/README.md +0 -7
- package/src/__stories__/editor-page.stories.tsx +0 -65
- package/src/__stories__/editor.stories.tsx +0 -134
- package/src/__stories__/item-editor.stories.tsx +0 -41
- package/src/__stories__/tex-error-view.stories.tsx +0 -26
- package/src/__testdata__/input-number.testdata.ts +0 -27
- package/src/__tests__/editor.test.tsx +0 -142
- package/src/__tests__/hint-editor.test.tsx +0 -83
- package/src/__tests__/i18n.test.ts +0 -501
- package/src/__tests__/integration.test.ts +0 -5
- package/src/__tests__/item-extras-editor.test.tsx +0 -85
- package/src/__tests__/traversal.test.ts +0 -377
- package/src/all-editors.test.ts +0 -16
- package/src/all-editors.ts +0 -83
- package/src/all-widgets.ts +0 -7
- package/src/article-editor.tsx +0 -438
- package/src/components/__stories__/blur-input.stories.tsx +0 -22
- package/src/components/__stories__/section-control-button.stories.tsx +0 -26
- package/src/components/__tests__/blur-input.test.tsx +0 -67
- package/src/components/blur-input.tsx +0 -69
- package/src/components/checkbox.tsx +0 -194
- package/src/components/device-framer.tsx +0 -90
- package/src/components/drag-target.tsx +0 -87
- package/src/components/dropdown-option.tsx +0 -311
- package/src/components/form-wrapped-text-field.tsx +0 -245
- package/src/components/graph-points-count-selector.tsx +0 -31
- package/src/components/graph-settings.tsx +0 -627
- package/src/components/graph-type-selector.tsx +0 -31
- package/src/components/hover-behavior.ts +0 -177
- package/src/components/json-editor.tsx +0 -121
- package/src/components/link.ts +0 -173
- package/src/components/section-control-button.tsx +0 -53
- package/src/components/segment-count-selector.tsx +0 -27
- package/src/components/simple-button.tsx +0 -85
- package/src/components/sortable.tsx +0 -187
- package/src/components/util.ts +0 -38
- package/src/components/viewport-resizer.tsx +0 -72
- package/src/components/widget-editor.tsx +0 -222
- package/src/components/widget-select.tsx +0 -48
- package/src/diffs/__stories__/perseus-diff-wrapper.tsx +0 -11
- package/src/diffs/__stories__/structured-item-diff.stories.tsx +0 -855
- package/src/diffs/__stories__/tags-diff.stories.tsx +0 -36
- package/src/diffs/__stories__/text-diff.stories.tsx +0 -35
- package/src/diffs/__tests__/split-diff.test.ts +0 -33
- package/src/diffs/__tests__/string-array-diff.test.ts +0 -73
- package/src/diffs/__tests__/structured-item-diff.test.ts +0 -433
- package/src/diffs/__tests__/widget-diff-performer.test.ts +0 -43
- package/src/diffs/article-diff.tsx +0 -69
- package/src/diffs/item-diff.tsx +0 -76
- package/src/diffs/renderer-diff.tsx +0 -137
- package/src/diffs/split-diff.ts +0 -31
- package/src/diffs/string-array-diff.ts +0 -74
- package/src/diffs/structured-item-diff.tsx +0 -275
- package/src/diffs/tags-diff.tsx +0 -49
- package/src/diffs/text-diff.tsx +0 -193
- package/src/diffs/widget-diff-performer.ts +0 -69
- package/src/diffs/widget-diff.tsx +0 -290
- package/src/editor-page.tsx +0 -325
- package/src/editor.tsx +0 -1099
- package/src/hint-editor.tsx +0 -469
- package/src/i18n.ts +0 -140
- package/src/iframe-content-renderer.tsx +0 -188
- package/src/index.ts +0 -30
- package/src/item-editor.tsx +0 -158
- package/src/item-extras-editor.tsx +0 -230
- package/src/katex-mhchem/index.js +0 -73
- package/src/katex-mhchem/parser.js +0 -2659
- package/src/multirenderer-editor.tsx +0 -1061
- package/src/stateful-article-editor.tsx +0 -173
- package/src/stateful-editor-page.tsx +0 -88
- package/src/styles/perseus-editor.less +0 -1321
- package/src/testing-widgets.ts +0 -11
- package/src/tex-error-view.tsx +0 -90
- package/src/util/points.test.ts +0 -24
- package/src/util/points.ts +0 -13
- package/src/util/register-all-widgets-and-editors-for-testing.test.ts +0 -17
- package/src/util/register-all-widgets-and-editors-for-testing.ts +0 -17
- package/src/version.ts +0 -10
- package/src/widgets/__stories__/categorizer-editor.stories.tsx +0 -24
- package/src/widgets/__stories__/definition-editor.stories.tsx +0 -18
- package/src/widgets/__stories__/dropdown-editor.stories.tsx +0 -18
- package/src/widgets/__stories__/explanation-editor.stories.tsx +0 -18
- package/src/widgets/__stories__/expression-editor.stories.tsx +0 -122
- package/src/widgets/__stories__/image-editor.stories.tsx +0 -72
- package/src/widgets/__stories__/input-number-editor.stories.tsx +0 -18
- package/src/widgets/__stories__/interaction-editor.stories.tsx +0 -37
- package/src/widgets/__stories__/label-image-editor.stories.tsx +0 -99
- package/src/widgets/__stories__/matcher-editor.stories.tsx +0 -18
- package/src/widgets/__stories__/number-line-editor.stories.tsx +0 -18
- package/src/widgets/__stories__/numeric-input-editor.stories.tsx +0 -18
- package/src/widgets/__stories__/radio-editor.stories.tsx +0 -116
- package/src/widgets/__stories__/sorter-editor.stories.tsx +0 -18
- package/src/widgets/__tests__/categorizer-editor.test.tsx +0 -51
- package/src/widgets/__tests__/definition-editor.test.tsx +0 -41
- package/src/widgets/__tests__/dropdown-editor.test.tsx +0 -57
- package/src/widgets/__tests__/explanation-editor.test.tsx +0 -59
- package/src/widgets/__tests__/expression-editor.test.tsx +0 -403
- package/src/widgets/__tests__/input-number-editor.test.tsx +0 -128
- package/src/widgets/__tests__/matcher-editor.test.tsx +0 -47
- package/src/widgets/__tests__/number-line-editor.test.tsx +0 -144
- package/src/widgets/__tests__/numeric-input-editor.test.tsx +0 -177
- package/src/widgets/__tests__/radio-editor.test.tsx +0 -118
- package/src/widgets/__tests__/sorter-editor.test.tsx +0 -55
- package/src/widgets/categorizer-editor.tsx +0 -104
- package/src/widgets/cs-program-editor.tsx +0 -256
- package/src/widgets/definition-editor.tsx +0 -77
- package/src/widgets/deprecated-standin-editor.tsx +0 -29
- package/src/widgets/dropdown-editor.tsx +0 -211
- package/src/widgets/example-graphie-widget-editor.tsx +0 -70
- package/src/widgets/example-graphie-widget.tsx +0 -172
- package/src/widgets/example-widget-editor.tsx +0 -62
- package/src/widgets/example-widget.tsx +0 -154
- package/src/widgets/explanation-editor.tsx +0 -92
- package/src/widgets/expression-editor.tsx +0 -557
- package/src/widgets/graded-group-editor.tsx +0 -161
- package/src/widgets/graded-group-set-editor.tsx +0 -104
- package/src/widgets/grapher-editor.tsx +0 -155
- package/src/widgets/group-editor.tsx +0 -83
- package/src/widgets/iframe-editor.tsx +0 -202
- package/src/widgets/image-editor.tsx +0 -367
- package/src/widgets/input-number-editor.tsx +0 -288
- package/src/widgets/interaction-editor/constraint-editor.tsx +0 -134
- package/src/widgets/interaction-editor/function-editor.tsx +0 -108
- package/src/widgets/interaction-editor/index.ts +0 -3
- package/src/widgets/interaction-editor/interaction-editor.tsx +0 -749
- package/src/widgets/interaction-editor/label-editor.tsx +0 -87
- package/src/widgets/interaction-editor/line-editor.tsx +0 -125
- package/src/widgets/interaction-editor/mathquill-input.tsx +0 -81
- package/src/widgets/interaction-editor/movable-line-editor.tsx +0 -121
- package/src/widgets/interaction-editor/movable-point-editor.tsx +0 -89
- package/src/widgets/interaction-editor/parametric-editor.tsx +0 -117
- package/src/widgets/interaction-editor/point-editor.tsx +0 -72
- package/src/widgets/interaction-editor/rectangle-editor.tsx +0 -96
- package/src/widgets/interactive-graph-editor.tsx +0 -571
- package/src/widgets/label-image/__stories__/answer-choices.stories.tsx +0 -82
- package/src/widgets/label-image/__stories__/behavior.stories.tsx +0 -31
- package/src/widgets/label-image/__stories__/marker.stories.tsx +0 -75
- package/src/widgets/label-image/__stories__/question-markers.stories.tsx +0 -107
- package/src/widgets/label-image/__stories__/select-image.stories.tsx +0 -59
- package/src/widgets/label-image/answer-choices.tsx +0 -231
- package/src/widgets/label-image/behavior.tsx +0 -122
- package/src/widgets/label-image/marker.tsx +0 -290
- package/src/widgets/label-image/question-markers.tsx +0 -176
- package/src/widgets/label-image/select-image.tsx +0 -81
- package/src/widgets/label-image-editor.tsx +0 -252
- package/src/widgets/lights-puzzle-editor.tsx +0 -278
- package/src/widgets/matcher-editor.tsx +0 -149
- package/src/widgets/matrix-editor.tsx +0 -156
- package/src/widgets/measurer-editor.tsx +0 -253
- package/src/widgets/molecule-editor.tsx +0 -64
- package/src/widgets/number-line-editor.tsx +0 -512
- package/src/widgets/numeric-input-editor.tsx +0 -536
- package/src/widgets/orderer-editor.tsx +0 -172
- package/src/widgets/passage-editor.tsx +0 -117
- package/src/widgets/passage-ref-editor.tsx +0 -80
- package/src/widgets/passage-ref-target-editor.tsx +0 -49
- package/src/widgets/plotter-editor.tsx +0 -542
- package/src/widgets/radio/editor.tsx +0 -398
- package/src/widgets/reaction-diagram-editor.tsx +0 -131
- package/src/widgets/sequence-editor.tsx +0 -205
- package/src/widgets/simple-markdown-tester-editor.tsx +0 -86
- package/src/widgets/simple-markdown-tester.tsx +0 -92
- package/src/widgets/simulator-editor.tsx +0 -146
- package/src/widgets/sorter-editor.tsx +0 -103
- package/src/widgets/table-editor.tsx +0 -164
- package/src/widgets/unit-editor.tsx +0 -299
- package/src/widgets/video-editor.tsx +0 -73
- package/tsconfig-build.json +0 -22
- package/tsconfig-build.tsbuildinfo +0 -1
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-useless-escape */
|
|
2
|
-
/**
|
|
3
|
-
* This editor is for embedding Khan Academy CS programs.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
components,
|
|
8
|
-
Changeable,
|
|
9
|
-
Dependencies,
|
|
10
|
-
EditorJsonify,
|
|
11
|
-
Errors,
|
|
12
|
-
Log,
|
|
13
|
-
} from "@khanacademy/perseus";
|
|
14
|
-
import $ from "jquery";
|
|
15
|
-
import PropTypes from "prop-types";
|
|
16
|
-
import * as React from "react";
|
|
17
|
-
import _ from "underscore";
|
|
18
|
-
|
|
19
|
-
import BlurInput from "../components/blur-input";
|
|
20
|
-
|
|
21
|
-
const {InfoTip, PropCheckBox} = components;
|
|
22
|
-
|
|
23
|
-
const DEFAULT_WIDTH = 400;
|
|
24
|
-
const DEFAULT_HEIGHT = 400;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* This is used for editing a name/value pair.
|
|
28
|
-
*/
|
|
29
|
-
class PairEditor extends React.Component<any> {
|
|
30
|
-
static propTypes = {
|
|
31
|
-
...Changeable.propTypes,
|
|
32
|
-
name: PropTypes.string,
|
|
33
|
-
value: PropTypes.string,
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
static defaultProps = {
|
|
37
|
-
name: "",
|
|
38
|
-
value: "",
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
change = (...args) => {
|
|
42
|
-
return Changeable.change.apply(this, args);
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
serialize = () => {
|
|
46
|
-
return EditorJsonify.serialize.call(this);
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
render(): React.ReactNode {
|
|
50
|
-
return (
|
|
51
|
-
<fieldset className="pair-editor">
|
|
52
|
-
<label>
|
|
53
|
-
Name:{" "}
|
|
54
|
-
<BlurInput
|
|
55
|
-
value={this.props.name}
|
|
56
|
-
onChange={this.change("name")}
|
|
57
|
-
/>
|
|
58
|
-
</label>
|
|
59
|
-
<label>
|
|
60
|
-
{" "}
|
|
61
|
-
Value:{" "}
|
|
62
|
-
<BlurInput
|
|
63
|
-
value={this.props.value}
|
|
64
|
-
onChange={this.change("value")}
|
|
65
|
-
/>
|
|
66
|
-
</label>
|
|
67
|
-
</fieldset>
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* This is used for editing a set of name/value pairs.
|
|
74
|
-
*/
|
|
75
|
-
class PairsEditor extends React.Component<any> {
|
|
76
|
-
static propTypes = {
|
|
77
|
-
...Changeable.propTypes,
|
|
78
|
-
pairs: PropTypes.arrayOf(
|
|
79
|
-
PropTypes.shape({
|
|
80
|
-
name: PropTypes.string,
|
|
81
|
-
value: PropTypes.string,
|
|
82
|
-
}),
|
|
83
|
-
).isRequired,
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
change = (...args) => {
|
|
87
|
-
return Changeable.change.apply(this, args);
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
handlePairChange = (pairIndex, pair: any) => {
|
|
91
|
-
// If they're both non empty, add a new one
|
|
92
|
-
const pairs = this.props.pairs.slice();
|
|
93
|
-
pairs[pairIndex] = pair;
|
|
94
|
-
|
|
95
|
-
const lastPair = pairs[pairs.length - 1];
|
|
96
|
-
if (lastPair.name && lastPair.value) {
|
|
97
|
-
pairs.push({name: "", value: ""});
|
|
98
|
-
}
|
|
99
|
-
this.change("pairs", pairs);
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
serialize = () => {
|
|
103
|
-
return EditorJsonify.serialize.call(this);
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
render(): React.ReactNode {
|
|
107
|
-
const editors = _.map(this.props.pairs, (pair, i) => {
|
|
108
|
-
return (
|
|
109
|
-
<PairEditor
|
|
110
|
-
key={i}
|
|
111
|
-
name={pair.name}
|
|
112
|
-
value={pair.value}
|
|
113
|
-
// eslint-disable-next-line react/jsx-no-bind
|
|
114
|
-
onChange={this.handlePairChange.bind(this, i)}
|
|
115
|
-
/>
|
|
116
|
-
);
|
|
117
|
-
});
|
|
118
|
-
return <div>{editors}</div>;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const KA_PROGRAM_URL = /khanacademy\.org\/computer-programming\/[^\/]+\/(\d+)/;
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Given a program URL from the site, extract its program ID.
|
|
126
|
-
* If the input does not match the known URL patterns, it is assumed to be
|
|
127
|
-
* a program ID.
|
|
128
|
-
*/
|
|
129
|
-
function isolateProgramID(programUrl: string) {
|
|
130
|
-
const match = KA_PROGRAM_URL.exec(programUrl);
|
|
131
|
-
if (match) {
|
|
132
|
-
programUrl = match[1];
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return programUrl;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* This is the main editor for this widget, to specify all the options.
|
|
140
|
-
*/
|
|
141
|
-
class CSProgramEditor extends React.Component<any> {
|
|
142
|
-
static propTypes = {
|
|
143
|
-
...Changeable.propTypes,
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
static widgetName = "cs-program" as const;
|
|
147
|
-
|
|
148
|
-
static defaultProps: any = {
|
|
149
|
-
programID: "",
|
|
150
|
-
programType: null,
|
|
151
|
-
settings: [{name: "", value: ""}],
|
|
152
|
-
showEditor: false,
|
|
153
|
-
showButtons: false,
|
|
154
|
-
width: DEFAULT_WIDTH,
|
|
155
|
-
height: DEFAULT_HEIGHT,
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
change: (...args: ReadonlyArray<unknown>) => any = (...args) => {
|
|
159
|
-
// @ts-expect-error - TS2345 - Argument of type 'readonly unknown[]' is not assignable to parameter of type 'any[]'.
|
|
160
|
-
return Changeable.change.apply(this, args);
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
_handleSettingsChange: (arg1: any) => void = (settings) => {
|
|
164
|
-
this.change({settings: settings.pairs});
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
_handleProgramIDChange: (arg1: string) => void = (programID) => {
|
|
168
|
-
programID = isolateProgramID(programID);
|
|
169
|
-
const {isDevServer, InitialRequestUrl} = Dependencies.getDependencies();
|
|
170
|
-
|
|
171
|
-
const host = isDevServer
|
|
172
|
-
? InitialRequestUrl.origin
|
|
173
|
-
: "https://www.khanacademy.org";
|
|
174
|
-
const baseUrl = `${host}/api/internal/scratchpads/${programID}`;
|
|
175
|
-
|
|
176
|
-
$.getJSON(baseUrl)
|
|
177
|
-
.done((programInfo) => {
|
|
178
|
-
const programType = programInfo.userAuthoredContentType;
|
|
179
|
-
this.change({
|
|
180
|
-
width: programInfo.width,
|
|
181
|
-
height: programInfo.height,
|
|
182
|
-
programID: programID,
|
|
183
|
-
programType: programType,
|
|
184
|
-
});
|
|
185
|
-
})
|
|
186
|
-
.fail((jqxhr, textStatus, error) => {
|
|
187
|
-
Log.error(
|
|
188
|
-
"Error retrieving scratchpad info for program ID ",
|
|
189
|
-
Errors.TransientService,
|
|
190
|
-
{
|
|
191
|
-
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'Error | null | undefined'.
|
|
192
|
-
cause: error,
|
|
193
|
-
loggedMetadata: {
|
|
194
|
-
textStatus,
|
|
195
|
-
programID,
|
|
196
|
-
},
|
|
197
|
-
},
|
|
198
|
-
);
|
|
199
|
-
this.change({
|
|
200
|
-
width: DEFAULT_WIDTH,
|
|
201
|
-
height: DEFAULT_HEIGHT,
|
|
202
|
-
programID: programID,
|
|
203
|
-
programType: null,
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
serialize: () => any = () => {
|
|
209
|
-
return EditorJsonify.serialize.call(this);
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
render(): React.ReactNode {
|
|
213
|
-
return (
|
|
214
|
-
<div>
|
|
215
|
-
<label>
|
|
216
|
-
Url or Program ID:{" "}
|
|
217
|
-
<BlurInput
|
|
218
|
-
value={this.props.programID}
|
|
219
|
-
onChange={this._handleProgramIDChange}
|
|
220
|
-
/>
|
|
221
|
-
</label>
|
|
222
|
-
<br />
|
|
223
|
-
<PropCheckBox
|
|
224
|
-
label="Show Editor"
|
|
225
|
-
showEditor={this.props.showEditor}
|
|
226
|
-
onChange={this.props.onChange}
|
|
227
|
-
/>
|
|
228
|
-
<InfoTip>
|
|
229
|
-
If you show the editor, you should use the "full-width"
|
|
230
|
-
alignment to make room for the width of the editor.
|
|
231
|
-
</InfoTip>
|
|
232
|
-
<br />
|
|
233
|
-
<PropCheckBox
|
|
234
|
-
label="Show Buttons"
|
|
235
|
-
showButtons={this.props.showButtons}
|
|
236
|
-
onChange={this.props.onChange}
|
|
237
|
-
/>
|
|
238
|
-
<br />
|
|
239
|
-
<label>
|
|
240
|
-
Settings:
|
|
241
|
-
<PairsEditor
|
|
242
|
-
name="settings"
|
|
243
|
-
pairs={this.props.settings}
|
|
244
|
-
onChange={this._handleSettingsChange}
|
|
245
|
-
/>
|
|
246
|
-
<InfoTip>
|
|
247
|
-
Settings that you add here are available to the program
|
|
248
|
-
as an object returned by <code>Program.settings()</code>
|
|
249
|
-
</InfoTip>
|
|
250
|
-
</label>
|
|
251
|
-
</div>
|
|
252
|
-
);
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
export default CSProgramEditor;
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
2
|
-
import {components, Changeable, EditorJsonify} from "@khanacademy/perseus";
|
|
3
|
-
import PropTypes from "prop-types";
|
|
4
|
-
import * as React from "react";
|
|
5
|
-
import _ from "underscore";
|
|
6
|
-
|
|
7
|
-
import Editor from "../editor";
|
|
8
|
-
|
|
9
|
-
const {TextInput} = components;
|
|
10
|
-
|
|
11
|
-
type Props = any;
|
|
12
|
-
|
|
13
|
-
class DefinitionEditor extends React.Component<Props> {
|
|
14
|
-
static propTypes = {
|
|
15
|
-
...Changeable.propTypes,
|
|
16
|
-
togglePrompt: PropTypes.string,
|
|
17
|
-
definition: PropTypes.string,
|
|
18
|
-
apiOptions: PropTypes.any,
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
static widgetName = "definition" as const;
|
|
22
|
-
|
|
23
|
-
static defaultProps: Props = {
|
|
24
|
-
togglePrompt: "",
|
|
25
|
-
definition: "",
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
change: (arg1: any, arg2: any, arg3: any) => any = (...args) => {
|
|
29
|
-
return Changeable.change.apply(this, args);
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
serialize: () => any = () => {
|
|
33
|
-
return EditorJsonify.serialize.call(this);
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
render(): React.ReactNode {
|
|
37
|
-
return (
|
|
38
|
-
<div className="perseus-widget-definition-editor">
|
|
39
|
-
<a
|
|
40
|
-
href="https://docs.google.com/document/d/1udaPef4imOfTMhmLDlWq4SM0mxL0r3YHFZE-5J1uGfo"
|
|
41
|
-
target="_blank"
|
|
42
|
-
>
|
|
43
|
-
Definition style guide
|
|
44
|
-
</a>
|
|
45
|
-
<div className="perseus-widget-row">
|
|
46
|
-
<label>
|
|
47
|
-
Word to be defined:{" "}
|
|
48
|
-
<TextInput
|
|
49
|
-
value={this.props.togglePrompt}
|
|
50
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
51
|
-
onChange={this.change("togglePrompt")}
|
|
52
|
-
placeholder="define me"
|
|
53
|
-
/>
|
|
54
|
-
</label>
|
|
55
|
-
</div>
|
|
56
|
-
<div className="perseus-widget-row">
|
|
57
|
-
<Editor
|
|
58
|
-
apiOptions={this.props.apiOptions}
|
|
59
|
-
content={this.props.definition}
|
|
60
|
-
widgetEnabled={false}
|
|
61
|
-
placeholder="definition goes here"
|
|
62
|
-
onChange={(props) => {
|
|
63
|
-
const newProps: Record<string, any> = {};
|
|
64
|
-
if (_.has(props, "content")) {
|
|
65
|
-
newProps.definition = props.content;
|
|
66
|
-
}
|
|
67
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
68
|
-
this.change(newProps);
|
|
69
|
-
}}
|
|
70
|
-
/>
|
|
71
|
-
</div>
|
|
72
|
-
</div>
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export default DefinitionEditor;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import {EditorJsonify} from "@khanacademy/perseus";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
|
|
4
|
-
type Props = {
|
|
5
|
-
// Callback for when a widget prop is changed.
|
|
6
|
-
onChange: (options: any) => void;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
class DeprecatedStandinEditor extends React.Component<Props> {
|
|
10
|
-
static widgetName = "deprecated-standin" as const;
|
|
11
|
-
|
|
12
|
-
serialize(): any {
|
|
13
|
-
return EditorJsonify.serialize.call(this);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
render(): React.ReactNode {
|
|
17
|
-
return (
|
|
18
|
-
<div>
|
|
19
|
-
<p>This widget has been deprecated and removed</p>
|
|
20
|
-
<p>
|
|
21
|
-
Learners will see a message and they will not be graded on
|
|
22
|
-
this part. Please replace this widget with a supported one.
|
|
23
|
-
</p>
|
|
24
|
-
</div>
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export default DeprecatedStandinEditor;
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
2
|
-
import {components, icons, EditorJsonify} from "@khanacademy/perseus";
|
|
3
|
-
import PropTypes from "prop-types";
|
|
4
|
-
import * as React from "react";
|
|
5
|
-
import ReactDOM from "react-dom";
|
|
6
|
-
import _ from "underscore";
|
|
7
|
-
|
|
8
|
-
const {InfoTip, InlineIcon} = components;
|
|
9
|
-
const {iconPlus, iconTrash} = icons;
|
|
10
|
-
|
|
11
|
-
type Props = any;
|
|
12
|
-
|
|
13
|
-
class DropdownEditor extends React.Component<Props> {
|
|
14
|
-
static propTypes = {
|
|
15
|
-
choices: PropTypes.arrayOf(
|
|
16
|
-
PropTypes.shape({
|
|
17
|
-
content: PropTypes.string,
|
|
18
|
-
correct: PropTypes.bool,
|
|
19
|
-
}),
|
|
20
|
-
),
|
|
21
|
-
placeholder: PropTypes.string,
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
static widgetName = "dropdown" as const;
|
|
25
|
-
|
|
26
|
-
static defaultProps: Props = {
|
|
27
|
-
placeholder: "",
|
|
28
|
-
choices: [
|
|
29
|
-
{
|
|
30
|
-
content: "",
|
|
31
|
-
correct: false,
|
|
32
|
-
},
|
|
33
|
-
],
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
onPlaceholderChange: (arg1: React.ChangeEvent<HTMLInputElement>) => void = (
|
|
37
|
-
e,
|
|
38
|
-
) => {
|
|
39
|
-
const placeholder = e.target.value;
|
|
40
|
-
this.props.onChange({placeholder: placeholder});
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
onCorrectChange: (
|
|
44
|
-
arg1: number,
|
|
45
|
-
arg2: React.ChangeEvent<HTMLInputElement>,
|
|
46
|
-
) => void = (choiceIndex) => {
|
|
47
|
-
const choices = _.map(this.props.choices, function (choice, i) {
|
|
48
|
-
return _.extend({}, choice, {
|
|
49
|
-
correct: i === choiceIndex,
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
this.props.onChange({choices: choices});
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
onContentChange: (
|
|
56
|
-
arg1: number,
|
|
57
|
-
arg2: React.ChangeEvent<HTMLInputElement>,
|
|
58
|
-
) => void = (choiceIndex, e) => {
|
|
59
|
-
const choices = this.props.choices.slice();
|
|
60
|
-
const choice = _.clone(choices[choiceIndex]);
|
|
61
|
-
choice.content = e.target.value;
|
|
62
|
-
choices[choiceIndex] = choice;
|
|
63
|
-
this.props.onChange({choices: choices});
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
addChoice: (arg1: React.MouseEvent) => void = (e) => {
|
|
67
|
-
e.preventDefault();
|
|
68
|
-
|
|
69
|
-
const choices = this.props.choices;
|
|
70
|
-
const blankChoice = {content: "", correct: false} as const;
|
|
71
|
-
this.props.onChange(
|
|
72
|
-
{
|
|
73
|
-
choices: choices.concat([blankChoice]),
|
|
74
|
-
},
|
|
75
|
-
this.focus.bind(this, choices.length),
|
|
76
|
-
);
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
removeChoice: (arg1: number, arg2: React.MouseEvent) => void = (
|
|
80
|
-
choiceIndex,
|
|
81
|
-
e,
|
|
82
|
-
) => {
|
|
83
|
-
e.preventDefault();
|
|
84
|
-
const choices = _(this.props.choices).clone();
|
|
85
|
-
choices.splice(choiceIndex, 1);
|
|
86
|
-
this.props.onChange({
|
|
87
|
-
choices: choices,
|
|
88
|
-
});
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
focus: (arg1: number) => boolean = (i) => {
|
|
92
|
-
// @ts-expect-error - TS2531 - Object is possibly 'null'. | TS2339 - Property 'focus' does not exist on type 'Element | Text'.
|
|
93
|
-
ReactDOM.findDOMNode(this.refs["editor" + i]).focus(); // eslint-disable-line react/no-string-refs
|
|
94
|
-
return true;
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
serialize: () => any = () => {
|
|
98
|
-
return EditorJsonify.serialize.call(this);
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
render(): React.ReactNode {
|
|
102
|
-
const dropdownGroupName = _.uniqueId("perseus_dropdown_");
|
|
103
|
-
return (
|
|
104
|
-
<div className="perseus-widget-dropdown">
|
|
105
|
-
<div className="dropdown-info">
|
|
106
|
-
Dropdown
|
|
107
|
-
<InfoTip>
|
|
108
|
-
<p>
|
|
109
|
-
The drop down is useful for making inequalities in a
|
|
110
|
-
custom format. We normally use the symbols {"<"},{" "}
|
|
111
|
-
{">"}, ≤, ≥ (in that order) which you can copy into
|
|
112
|
-
the choices. When possible, use the "multiple
|
|
113
|
-
choice" answer type instead.
|
|
114
|
-
</p>
|
|
115
|
-
</InfoTip>
|
|
116
|
-
</div>
|
|
117
|
-
<div className="dropdown-placeholder">
|
|
118
|
-
<input
|
|
119
|
-
type="text"
|
|
120
|
-
placeholder="Placeholder value"
|
|
121
|
-
value={this.props.placeholder}
|
|
122
|
-
onChange={this.onPlaceholderChange}
|
|
123
|
-
/>
|
|
124
|
-
<InfoTip>
|
|
125
|
-
<p>
|
|
126
|
-
This value will appear as the drop down default. It
|
|
127
|
-
should give the user some indication of the values
|
|
128
|
-
available in the drop down itself, e.g.,
|
|
129
|
-
Yes/No/Maybe.
|
|
130
|
-
</p>
|
|
131
|
-
</InfoTip>
|
|
132
|
-
</div>
|
|
133
|
-
<div className="clearfix" />
|
|
134
|
-
<ul className="dropdown-choices">
|
|
135
|
-
{this.props.choices.map(function (choice, i) {
|
|
136
|
-
const checkedClass = choice.correct
|
|
137
|
-
? "correct"
|
|
138
|
-
: "incorrect";
|
|
139
|
-
|
|
140
|
-
return (
|
|
141
|
-
<li key={"" + i}>
|
|
142
|
-
<div>
|
|
143
|
-
<input
|
|
144
|
-
ref={"radio" + i}
|
|
145
|
-
type="radio"
|
|
146
|
-
name={dropdownGroupName}
|
|
147
|
-
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'boolean | undefined'.
|
|
148
|
-
checked={
|
|
149
|
-
choice.correct ? "checked" : ""
|
|
150
|
-
}
|
|
151
|
-
// eslint-disable-next-line react/jsx-no-bind
|
|
152
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
153
|
-
onChange={this.onCorrectChange.bind(
|
|
154
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
155
|
-
this,
|
|
156
|
-
i,
|
|
157
|
-
)}
|
|
158
|
-
value={i}
|
|
159
|
-
/>
|
|
160
|
-
<input
|
|
161
|
-
type="text"
|
|
162
|
-
ref={"editor" + i}
|
|
163
|
-
// eslint-disable-next-line react/jsx-no-bind
|
|
164
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
165
|
-
onChange={this.onContentChange.bind(
|
|
166
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
167
|
-
this,
|
|
168
|
-
i,
|
|
169
|
-
)}
|
|
170
|
-
className={checkedClass}
|
|
171
|
-
value={choice.content}
|
|
172
|
-
/>
|
|
173
|
-
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
|
|
174
|
-
<a
|
|
175
|
-
href="#"
|
|
176
|
-
className="simple-button orange"
|
|
177
|
-
aria-label="Delete choice"
|
|
178
|
-
// eslint-disable-next-line react/jsx-no-bind
|
|
179
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
180
|
-
onClick={this.removeChoice.bind(
|
|
181
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
182
|
-
this,
|
|
183
|
-
i,
|
|
184
|
-
)}
|
|
185
|
-
>
|
|
186
|
-
<span className="remove-choice">
|
|
187
|
-
<InlineIcon {...iconTrash} />
|
|
188
|
-
</span>
|
|
189
|
-
</a>
|
|
190
|
-
</div>
|
|
191
|
-
</li>
|
|
192
|
-
);
|
|
193
|
-
}, this)}
|
|
194
|
-
</ul>
|
|
195
|
-
|
|
196
|
-
<div className="add-choice-container">
|
|
197
|
-
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
|
|
198
|
-
<a
|
|
199
|
-
href="#"
|
|
200
|
-
className="simple-button orange"
|
|
201
|
-
onClick={this.addChoice}
|
|
202
|
-
>
|
|
203
|
-
<InlineIcon {...iconPlus} /> Add a choice{" "}
|
|
204
|
-
</a>
|
|
205
|
-
</div>
|
|
206
|
-
</div>
|
|
207
|
-
);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
export default DropdownEditor;
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import {Changeable, EditorJsonify} from "@khanacademy/perseus";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
|
|
4
|
-
import ExampleGraphie from "./example-graphie-widget";
|
|
5
|
-
|
|
6
|
-
const ExampleGraphieWidget = ExampleGraphie.widget;
|
|
7
|
-
|
|
8
|
-
type Props = any;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* This is the widget's editor. This is what shows up on the left side
|
|
12
|
-
* of the screen in the demo page. Only the question writer sees this.
|
|
13
|
-
*/
|
|
14
|
-
class ExampleGraphieWidgetEditor extends React.Component<Props> {
|
|
15
|
-
static propTypes = {
|
|
16
|
-
...Changeable.propTypes,
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
static widgetName = "example-graphie-widget" as const;
|
|
20
|
-
|
|
21
|
-
static defaultProps: Props = {
|
|
22
|
-
correct: [4, 4],
|
|
23
|
-
graph: {
|
|
24
|
-
box: [340, 340],
|
|
25
|
-
labels: ["x", "y"],
|
|
26
|
-
range: [
|
|
27
|
-
[-10, 10],
|
|
28
|
-
[-10, 10],
|
|
29
|
-
],
|
|
30
|
-
step: [1, 1],
|
|
31
|
-
gridStep: [1, 1],
|
|
32
|
-
valid: true,
|
|
33
|
-
backgroundImage: null,
|
|
34
|
-
markings: "grid",
|
|
35
|
-
showProtractor: false,
|
|
36
|
-
},
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
change: (arg1: any, arg2: any, arg3: any) => any = (...args) => {
|
|
40
|
-
return Changeable.change.apply(this, args);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
handleChange: (arg1: any) => void = (newProps) => {
|
|
44
|
-
if (newProps.coord) {
|
|
45
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
46
|
-
this.change({
|
|
47
|
-
correct: newProps.coord,
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
serialize: () => any = () => {
|
|
53
|
-
return EditorJsonify.serialize.call(this);
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
render(): React.ReactNode {
|
|
57
|
-
return (
|
|
58
|
-
<div>
|
|
59
|
-
<ExampleGraphieWidget
|
|
60
|
-
graph={this.props.graph}
|
|
61
|
-
coord={this.props.correct}
|
|
62
|
-
onChange={this.handleChange}
|
|
63
|
-
apiOptions={this.props.apiOptions}
|
|
64
|
-
/>
|
|
65
|
-
</div>
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export default ExampleGraphieWidgetEditor;
|