@khanacademy/perseus 0.2.4 → 0.2.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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Core Perseus API (includes renderers and widgets)",
4
4
  "author": "Khan Academy",
5
5
  "license": "MIT",
6
- "version": "0.2.4",
6
+ "version": "0.2.7",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },
@@ -21,26 +21,27 @@
21
21
  "test": "bash -c 'yarn --silent --cwd \"../..\" test ${@:0} $($([[ ${@: -1} = -* ]] || [[ ${@: -1} = bash ]]) && echo $PWD)'"
22
22
  },
23
23
  "dependencies": {
24
- "@khanacademy/kmath": "0.0.5",
25
- "@khanacademy/math-input": "^0.5.1",
26
- "@khanacademy/kas": "^0.2.3",
27
- "@khanacademy/simple-markdown": "^0.8.1",
24
+ "@khanacademy/kmath": "^0.0.5",
25
+ "@khanacademy/math-input": "^0.5.2",
26
+ "@khanacademy/kas": "^0.2.4",
27
+ "@khanacademy/simple-markdown": "^0.8.3",
28
28
  "mathquill": "git+https://git@github.com/Khan/mathquill.git#a9ae54e057c5c1acc8244a5627acbff29901d992"
29
29
  },
30
30
  "devDependencies": {
31
- "@khanacademy/wonder-blocks-button": "2.11.5",
31
+ "@khanacademy/wonder-blocks-button": "^2.11.5",
32
32
  "@khanacademy/wonder-blocks-color": "^1.1.20",
33
33
  "@khanacademy/wonder-blocks-core": "^4.3.0",
34
34
  "@khanacademy/wonder-blocks-data": "^7.0.0",
35
35
  "@khanacademy/wonder-blocks-dropdown": "^2.6.7",
36
36
  "@khanacademy/wonder-blocks-i18n": "^1.2.3",
37
- "@khanacademy/wonder-blocks-layout": "1.4.9",
37
+ "@khanacademy/wonder-blocks-layout": "^1.4.9",
38
38
  "@khanacademy/wonder-blocks-link": "^3.8.5",
39
+ "@khanacademy/wonder-blocks-modal": "^2.3.1",
39
40
  "@khanacademy/wonder-blocks-popover": "^1.1.10",
40
- "@khanacademy/wonder-blocks-progress-spinner": "1.1.31",
41
+ "@khanacademy/wonder-blocks-progress-spinner": "^1.1.31",
41
42
  "@khanacademy/wonder-blocks-spacing": "^3.0.5",
42
43
  "@khanacademy/wonder-blocks-tooltip": "^1.3.10",
43
- "@khanacademy/wonder-blocks-typography": "1.1.31",
44
+ "@khanacademy/wonder-blocks-typography": "^1.1.31",
44
45
  "@khanacademy/wonder-stuff-core": "^0.1.2",
45
46
  "aphrodite": "^1.2.5",
46
47
  "classnames": "^1.1.4",
@@ -50,26 +51,27 @@
50
51
  "intersection-observer": "^0.12.0",
51
52
  "jquery": "^2.1.1",
52
53
  "lodash.debounce": "^4.0.8",
53
- "perseus-build-settings": "^0.0.1",
54
+ "perseus-build-settings": "^0.0.2",
54
55
  "prop-types": "^15.6.1",
55
56
  "react": "16.14.0",
56
57
  "react-dom": "16.14.0",
57
58
  "underscore": "^1.4.4"
58
59
  },
59
60
  "peerDependencies": {
60
- "@khanacademy/wonder-blocks-button": "2.11.5",
61
+ "@khanacademy/wonder-blocks-button": "^2.11.5",
61
62
  "@khanacademy/wonder-blocks-color": "^1.1.20",
62
63
  "@khanacademy/wonder-blocks-core": "^4.3.0",
63
64
  "@khanacademy/wonder-blocks-data": "^7.0.0",
64
65
  "@khanacademy/wonder-blocks-dropdown": "^2.6.7",
65
66
  "@khanacademy/wonder-blocks-i18n": "^1.2.3",
66
- "@khanacademy/wonder-blocks-layout": "1.4.9",
67
+ "@khanacademy/wonder-blocks-layout": "^1.4.9",
67
68
  "@khanacademy/wonder-blocks-link": "^3.8.5",
69
+ "@khanacademy/wonder-blocks-modal": "^2.3.1",
68
70
  "@khanacademy/wonder-blocks-popover": "^1.1.10",
69
- "@khanacademy/wonder-blocks-progress-spinner": "1.1.31",
71
+ "@khanacademy/wonder-blocks-progress-spinner": "^1.1.31",
70
72
  "@khanacademy/wonder-blocks-spacing": "^3.0.5",
71
73
  "@khanacademy/wonder-blocks-tooltip": "^1.3.10",
72
- "@khanacademy/wonder-blocks-typography": "1.1.31",
74
+ "@khanacademy/wonder-blocks-typography": "^1.1.31",
73
75
  "@khanacademy/wonder-stuff-core": "^0.1.2",
74
76
  "aphrodite": "^1.2.5",
75
77
  "classnames": "^1.1.4",
@@ -0,0 +1,34 @@
1
+ // @flow
2
+
3
+ import JiptParagraphs from "../jipt-paragraphs.js";
4
+
5
+ const {parseToArray} = JiptParagraphs;
6
+
7
+ describe("jipt-paragraphs", () => {
8
+ it("should split paragraphs using custom JIPT SimpleMarkdown rules", () => {
9
+ expect(parseToArray(" \n\nhello\n\n")).toMatchInlineSnapshot(`
10
+ Array [
11
+ " ",
12
+ "hello",
13
+ ]
14
+ `);
15
+ });
16
+
17
+ it("should recognize code fences using custom JIPT SimpleMarkdown rules", () => {
18
+ expect(
19
+ parseToArray(
20
+ "Let's write the canonical Hello World in Javascript\n\n" +
21
+ '```js\nconst x = "hello world";\nconsole.log(x);```\n\n' +
22
+ "**Congratulations, you are on your way to becoming a " +
23
+ "computer programmer!",
24
+ ),
25
+ ).toMatchInlineSnapshot(`
26
+ Array [
27
+ "Let's write the canonical Hello World in Javascript",
28
+ "const x = \\"hello world\\";
29
+ console.log(x);",
30
+ "**Congratulations, you are on your way to becoming a computer programmer!",
31
+ ]
32
+ `);
33
+ });
34
+ });
@@ -11,28 +11,36 @@ const arrayRules: ParserRules = {
11
11
  fence: {
12
12
  match: SimpleMarkdown.defaultRules.fence.match,
13
13
  order: 1,
14
- // $FlowFixMe[incompatible-type]
15
- parse: (capture, state, parse) => capture[3],
14
+ parse: (capture, state, parse) => ({
15
+ type: "codeBlock",
16
+ lang: capture[2] || undefined,
17
+ content: capture[3],
18
+ }),
16
19
  },
17
20
  paragraph: {
18
21
  match: SimpleMarkdown.defaultRules.paragraph.match,
19
22
  order: 2,
20
- // $FlowFixMe[incompatible-type]
21
- parse: (capture, state, parse) => capture[1],
23
+ parse: (capture, state, parse) => ({
24
+ content: capture[1],
25
+ }),
22
26
  },
23
27
  };
24
28
 
25
- // $FlowFixMe[prop-missing]
26
- const builtArrayParser = SimpleMarkdown.parserFor(arrayRules);
29
+ const builtArrayParser: $Call<
30
+ typeof SimpleMarkdown.parserFor,
31
+ typeof arrayRules,
32
+ > = SimpleMarkdown.parserFor(arrayRules);
27
33
 
28
34
  // This should just return an array of strings! magick!
29
- const parseToArray = (source: string): $FlowFixMe => {
35
+ const parseToArray = (source: string): Array<string> => {
30
36
  // Remove any leading newlines to avoid splitting weirdness
31
37
  // (simple-markdown has the `newline` rule for this, and i have
32
38
  // no idea how this will handle leading newlines without that rule),
33
39
  // and add \n\n to let it parse at a block/paragraph level
34
40
  const paragraphedSource = source.replace(/^\n\s*\n/, "") + "\n\n";
35
- return builtArrayParser(paragraphedSource, {inline: false});
41
+ return builtArrayParser(paragraphedSource, {inline: false}).map((c) => {
42
+ return c["content"];
43
+ });
36
44
  };
37
45
 
38
46
  const joinFromArray = (paragraphs: $ReadOnlyArray<string>): string =>
@@ -1,9 +1,7 @@
1
- /* eslint-disable react/sort-comp */
2
1
  // @flow
3
2
  import {SingleSelect, OptionItem} from "@khanacademy/wonder-blocks-dropdown";
4
3
  import * as React from "react";
5
4
  import ReactDOM from "react-dom";
6
- import _ from "underscore";
7
5
 
8
6
  import {ApiOptions} from "../perseus-api.jsx";
9
7
 
@@ -51,6 +49,33 @@ class Dropdown extends React.Component<Props> {
51
49
  };
52
50
  }
53
51
 
52
+ focus: () => boolean = () => {
53
+ // TODO(LP-10797): This focus() call doesn't do anything because our
54
+ // root element is a <div> and that cannot be focused without a
55
+ // tabIndex.
56
+ // $FlowFixMe[incompatible-use]
57
+ // $FlowFixMe[prop-missing]
58
+ ReactDOM.findDOMNode(this).focus();
59
+ return true;
60
+ };
61
+
62
+ _handleChangeEvent: (SyntheticInputEvent<>) => void = (e) => {
63
+ this._handleChange(parseInt(e.target.value));
64
+ };
65
+
66
+ _handleChange: (number) => void = (selected) => {
67
+ this.props.trackInteraction();
68
+ this.props.onChange({selected: selected});
69
+ };
70
+
71
+ getUserInput: () => UserInput = () => {
72
+ return {value: this.props.selected};
73
+ };
74
+
75
+ simpleValidate: (Rubric) => PerseusScore = (rubric) => {
76
+ return Dropdown.validate(this.getUserInput(), rubric);
77
+ };
78
+
54
79
  render(): React.Node {
55
80
  const children = [
56
81
  <OptionItem
@@ -79,8 +104,8 @@ class Dropdown extends React.Component<Props> {
79
104
  e.stopPropagation();
80
105
  }}
81
106
  >
82
- {/* $FlowFixMe[prop-missing]: placeholder is missing */}
83
107
  <SingleSelect
108
+ placeholder=""
84
109
  onChange={(value) => this._handleChange(parseInt(value))}
85
110
  selectedValue={String(this.props.selected)}
86
111
  disabled={this.props.apiOptions.readOnly}
@@ -90,33 +115,6 @@ class Dropdown extends React.Component<Props> {
90
115
  </div>
91
116
  );
92
117
  }
93
-
94
- focus: () => boolean = () => {
95
- // TODO(LP-10797): This focus() call doesn't do anything because our
96
- // root element is a <div> and that cannot be focused without a
97
- // tabIndex.
98
- // $FlowFixMe[incompatible-use]
99
- // $FlowFixMe[prop-missing]
100
- ReactDOM.findDOMNode(this).focus();
101
- return true;
102
- };
103
-
104
- _handleChangeEvent: (SyntheticInputEvent<>) => void = (e) => {
105
- this._handleChange(parseInt(e.target.value));
106
- };
107
-
108
- _handleChange: (number) => void = (selected) => {
109
- this.props.trackInteraction();
110
- this.props.onChange({selected: selected});
111
- };
112
-
113
- getUserInput: () => UserInput = () => {
114
- return {value: this.props.selected};
115
- };
116
-
117
- simpleValidate: (Rubric) => PerseusScore = (rubric) => {
118
- return Dropdown.validate(this.getUserInput(), rubric);
119
- };
120
118
  }
121
119
 
122
120
  type RenderProps = {|
@@ -129,7 +127,7 @@ const optionsTransform: (PerseusDropdownWidgetOptions) => RenderProps = (
129
127
  ) => {
130
128
  return {
131
129
  placeholder: widgetOptions.placeholder,
132
- choices: _.map(widgetOptions.choices, (choice) => choice.content),
130
+ choices: widgetOptions.choices.map((choice) => choice.content),
133
131
  };
134
132
  };
135
133