docusaurus-live-brython 3.0.0-beta.8 → 3.0.1
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/.devcontainer/devcontainer.json +38 -0
- package/.prettierignore +17 -0
- package/.prettierrc +9 -8
- package/CHANGELOG.md +5 -0
- package/README.md +7 -4
- package/lib/assets/py_back_trace.py +2 -1
- package/lib/index.d.ts +1 -7
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +94 -16
- package/lib/options.d.ts +1 -0
- package/lib/options.d.ts.map +1 -0
- package/lib/options.js +2 -2
- package/lib/theme/CodeBlock/index.d.ts +3 -3
- package/lib/theme/CodeBlock/index.d.ts.map +1 -0
- package/lib/theme/CodeBlock/index.jsx +24 -14
- package/lib/theme/CodeEditor/Actions/DownloadCode.d.ts +1 -0
- package/lib/theme/CodeEditor/Actions/DownloadCode.d.ts.map +1 -0
- package/lib/theme/CodeEditor/Actions/DownloadCode.jsx +8 -8
- package/lib/theme/CodeEditor/Actions/Reset.d.ts +1 -0
- package/lib/theme/CodeEditor/Actions/Reset.d.ts.map +1 -0
- package/lib/theme/CodeEditor/Actions/Reset.jsx +5 -5
- package/lib/theme/CodeEditor/Actions/RunCode.d.ts +2 -1
- package/lib/theme/CodeEditor/Actions/RunCode.d.ts.map +1 -0
- package/lib/theme/CodeEditor/Actions/RunCode.jsx +4 -4
- package/lib/theme/CodeEditor/Actions/ShowRaw.d.ts +1 -0
- package/lib/theme/CodeEditor/Actions/ShowRaw.d.ts.map +1 -0
- package/lib/theme/CodeEditor/Actions/ShowRaw.jsx +13 -7
- package/lib/theme/CodeEditor/Actions/ShowSyncStatus.d.ts +1 -0
- package/lib/theme/CodeEditor/Actions/ShowSyncStatus.d.ts.map +1 -0
- package/lib/theme/CodeEditor/Actions/ShowSyncStatus.jsx +21 -16
- package/lib/theme/CodeEditor/Actions/styles.module.css +2 -3
- package/lib/theme/CodeEditor/BrythonCommunicator.d.ts +2 -1
- package/lib/theme/CodeEditor/BrythonCommunicator.d.ts.map +1 -0
- package/lib/theme/CodeEditor/BrythonCommunicator.jsx +13 -9
- package/lib/theme/CodeEditor/Button/index.d.ts +3 -2
- package/lib/theme/CodeEditor/Button/index.d.ts.map +1 -0
- package/lib/theme/CodeEditor/Button/index.jsx +1 -1
- package/lib/theme/CodeEditor/Button/styles.module.css +1 -1
- package/lib/theme/CodeEditor/CodeHistory/index.d.ts +1 -0
- package/lib/theme/CodeEditor/CodeHistory/index.d.ts.map +1 -0
- package/lib/theme/CodeEditor/CodeHistory/index.jsx +26 -15
- package/lib/theme/CodeEditor/CodeHistory/styles.module.css +31 -31
- package/lib/theme/CodeEditor/ContextEditor/index.d.ts +22 -0
- package/lib/theme/CodeEditor/ContextEditor/index.d.ts.map +1 -0
- package/lib/theme/CodeEditor/ContextEditor/index.jsx +36 -0
- package/lib/theme/CodeEditor/Editor/EditorAce.d.ts +2 -1
- package/lib/theme/CodeEditor/Editor/EditorAce.d.ts.map +1 -0
- package/lib/theme/CodeEditor/Editor/EditorAce.jsx +17 -14
- package/lib/theme/CodeEditor/Editor/Header/index.d.ts +2 -1
- package/lib/theme/CodeEditor/Editor/Header/index.d.ts.map +1 -0
- package/lib/theme/CodeEditor/Editor/Header/index.jsx +12 -12
- package/lib/theme/CodeEditor/Editor/Header/styles.module.css +7 -7
- package/lib/theme/CodeEditor/Editor/HiddenCode/index.d.ts +8 -0
- package/lib/theme/CodeEditor/Editor/HiddenCode/index.d.ts.map +1 -0
- package/lib/theme/CodeEditor/Editor/HiddenCode/index.jsx +27 -0
- package/lib/theme/CodeEditor/Editor/HiddenCode/styles.module.css +52 -0
- package/lib/theme/CodeEditor/Editor/Result/Graphics/Canvas.d.ts +1 -0
- package/lib/theme/CodeEditor/Editor/Result/Graphics/Canvas.d.ts.map +1 -0
- package/lib/theme/CodeEditor/Editor/Result/Graphics/Canvas.jsx +8 -9
- package/lib/theme/CodeEditor/Editor/Result/Graphics/Turtle.d.ts +1 -0
- package/lib/theme/CodeEditor/Editor/Result/Graphics/Turtle.d.ts.map +1 -0
- package/lib/theme/CodeEditor/Editor/Result/Graphics/Turtle.jsx +11 -11
- package/lib/theme/CodeEditor/Editor/Result/Graphics/index.d.ts +4 -3
- package/lib/theme/CodeEditor/Editor/Result/Graphics/index.d.ts.map +1 -0
- package/lib/theme/CodeEditor/Editor/Result/Graphics/index.jsx +12 -10
- package/lib/theme/CodeEditor/Editor/Result/Graphics/styles.module.css +2 -2
- package/lib/theme/CodeEditor/Editor/Result/index.d.ts +2 -3
- package/lib/theme/CodeEditor/Editor/Result/index.d.ts.map +1 -0
- package/lib/theme/CodeEditor/Editor/Result/index.jsx +6 -9
- package/lib/theme/CodeEditor/Editor/Result/styles.module.css +15 -10
- package/lib/theme/CodeEditor/Editor/index.d.ts +6 -3
- package/lib/theme/CodeEditor/Editor/index.d.ts.map +1 -0
- package/lib/theme/CodeEditor/Editor/index.jsx +34 -28
- package/lib/theme/CodeEditor/Editor/styles.module.css +15 -7
- package/lib/theme/CodeEditor/Editor/utils/checkForButtonClick.d.ts +1 -0
- package/lib/theme/CodeEditor/Editor/utils/checkForButtonClick.d.ts.map +1 -0
- package/lib/theme/CodeEditor/Editor/utils/saveSvg.d.ts +1 -0
- package/lib/theme/CodeEditor/Editor/utils/saveSvg.d.ts.map +1 -0
- package/lib/theme/CodeEditor/Editor/utils/saveSvg.js +19 -8
- package/lib/theme/CodeEditor/Editor/utils/svgWithoutAnimations.d.ts +1 -0
- package/lib/theme/CodeEditor/Editor/utils/svgWithoutAnimations.d.ts.map +1 -0
- package/lib/theme/CodeEditor/Editor/utils/svgWithoutAnimations.js +43 -49
- package/lib/theme/CodeEditor/Icon/icons.d.ts +4 -1
- package/lib/theme/CodeEditor/Icon/icons.d.ts.map +1 -0
- package/lib/theme/CodeEditor/Icon/icons.js +3 -1
- package/lib/theme/CodeEditor/Icon/index.d.ts +4 -2
- package/lib/theme/CodeEditor/Icon/index.d.ts.map +1 -0
- package/lib/theme/CodeEditor/Icon/index.jsx +10 -3
- package/lib/theme/CodeEditor/Icon/styles.module.css +1 -1
- package/lib/theme/CodeEditor/WithScript/ScriptContext.d.ts +8 -0
- package/lib/theme/CodeEditor/WithScript/ScriptContext.d.ts.map +1 -0
- package/lib/theme/CodeEditor/WithScript/ScriptContext.jsx +27 -0
- package/lib/theme/CodeEditor/WithScript/Storage.d.ts +2 -1
- package/lib/theme/CodeEditor/WithScript/Storage.d.ts.map +1 -0
- package/lib/theme/CodeEditor/WithScript/Types.d.ts +12 -4
- package/lib/theme/CodeEditor/WithScript/Types.d.ts.map +1 -0
- package/lib/theme/CodeEditor/WithScript/bryRunner.d.ts +3 -0
- package/lib/theme/CodeEditor/WithScript/bryRunner.d.ts.map +1 -0
- package/lib/theme/CodeEditor/WithScript/bryRunner.js +29 -0
- package/lib/theme/CodeEditor/WithScript/createStore.d.ts +4 -0
- package/lib/theme/CodeEditor/WithScript/createStore.d.ts.map +1 -0
- package/lib/theme/CodeEditor/WithScript/{Store.jsx → createStore.js} +62 -74
- package/lib/theme/CodeEditor/WithScript/helpers.d.ts +1 -4
- package/lib/theme/CodeEditor/WithScript/helpers.d.ts.map +1 -0
- package/lib/theme/CodeEditor/WithScript/helpers.js +4 -14
- package/lib/theme/CodeEditor/constants.d.ts +1 -0
- package/lib/theme/CodeEditor/constants.d.ts.map +1 -0
- package/lib/theme/CodeEditor/hooks/index.d.ts +3 -0
- package/lib/theme/CodeEditor/hooks/index.d.ts.map +1 -0
- package/lib/theme/CodeEditor/hooks/index.js +2 -0
- package/lib/theme/CodeEditor/hooks/useScript.d.ts +3 -0
- package/lib/theme/CodeEditor/hooks/useScript.d.ts.map +1 -0
- package/lib/theme/CodeEditor/hooks/useScript.js +4 -0
- package/lib/theme/CodeEditor/hooks/useStore.d.ts +3 -0
- package/lib/theme/CodeEditor/hooks/useStore.d.ts.map +1 -0
- package/lib/theme/CodeEditor/hooks/useStore.js +10 -0
- package/lib/theme/CodeEditor/index.d.ts +24 -5
- package/lib/theme/CodeEditor/index.d.ts.map +1 -0
- package/lib/theme/CodeEditor/index.jsx +17 -16
- package/lib/theme/CodeEditor/styles.module.css +28 -30
- package/og-image.md +23 -0
- package/package.json +39 -20
- package/src/assets/py_back_trace.py +2 -1
- package/src/index.ts +96 -25
- package/src/options.ts +12 -12
- package/src/theme/CodeBlock/index.tsx +44 -68
- package/src/theme/CodeEditor/Actions/DownloadCode.tsx +23 -22
- package/src/theme/CodeEditor/Actions/Reset.tsx +14 -12
- package/src/theme/CodeEditor/Actions/RunCode.tsx +14 -11
- package/src/theme/CodeEditor/Actions/ShowRaw.tsx +17 -11
- package/src/theme/CodeEditor/Actions/ShowSyncStatus.tsx +32 -27
- package/src/theme/CodeEditor/Actions/styles.module.css +2 -3
- package/src/theme/CodeEditor/BrythonCommunicator.tsx +16 -19
- package/src/theme/CodeEditor/Button/index.tsx +17 -13
- package/src/theme/CodeEditor/Button/styles.module.css +1 -1
- package/src/theme/CodeEditor/CodeHistory/index.tsx +32 -20
- package/src/theme/CodeEditor/CodeHistory/styles.module.css +31 -31
- package/src/theme/CodeEditor/ContextEditor/index.tsx +74 -0
- package/src/theme/CodeEditor/Editor/EditorAce.tsx +20 -16
- package/src/theme/CodeEditor/Editor/Header/index.tsx +13 -19
- package/src/theme/CodeEditor/Editor/Header/styles.module.css +7 -7
- package/src/theme/CodeEditor/Editor/HiddenCode/index.tsx +49 -0
- package/src/theme/CodeEditor/Editor/HiddenCode/styles.module.css +52 -0
- package/src/theme/CodeEditor/Editor/Result/Graphics/Canvas.tsx +25 -22
- package/src/theme/CodeEditor/Editor/Result/Graphics/Turtle.tsx +23 -19
- package/src/theme/CodeEditor/Editor/Result/Graphics/index.tsx +16 -16
- package/src/theme/CodeEditor/Editor/Result/Graphics/styles.module.css +2 -2
- package/src/theme/CodeEditor/Editor/Result/index.tsx +7 -13
- package/src/theme/CodeEditor/Editor/Result/styles.module.css +15 -10
- package/src/theme/CodeEditor/Editor/index.tsx +67 -65
- package/src/theme/CodeEditor/Editor/styles.module.css +15 -7
- package/src/theme/CodeEditor/Editor/utils/checkForButtonClick.ts +5 -5
- package/src/theme/CodeEditor/Editor/utils/saveSvg.ts +63 -53
- package/src/theme/CodeEditor/Editor/utils/svgWithoutAnimations.ts +182 -201
- package/src/theme/CodeEditor/Icon/icons.ts +27 -13
- package/src/theme/CodeEditor/Icon/index.tsx +31 -11
- package/src/theme/CodeEditor/Icon/styles.module.css +1 -1
- package/src/theme/CodeEditor/WithScript/ScriptContext.tsx +36 -0
- package/src/theme/CodeEditor/WithScript/Storage.ts +3 -3
- package/src/theme/CodeEditor/WithScript/Types.ts +17 -11
- package/src/theme/CodeEditor/WithScript/bryRunner.ts +39 -0
- package/src/theme/CodeEditor/WithScript/createStore.ts +276 -0
- package/src/theme/CodeEditor/WithScript/helpers.ts +16 -26
- package/src/theme/CodeEditor/constants.ts +9 -11
- package/src/theme/CodeEditor/hooks/index.ts +2 -0
- package/src/theme/CodeEditor/hooks/useScript.ts +9 -0
- package/src/theme/CodeEditor/hooks/useStore.ts +15 -0
- package/src/theme/CodeEditor/index.tsx +45 -31
- package/src/theme/CodeEditor/styles.module.css +28 -30
- package/src/typings.d.ts +11 -0
- package/lib/theme/CodeEditor/WithScript/Store.d.ts +0 -15
- package/lib/types.d.ts +0 -28
- package/lib/types.js +0 -1
- package/src/theme/CodeEditor/WithScript/Store.tsx +0 -294
- package/src/types.ts +0 -29
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
display: flex;
|
|
4
4
|
align-items: center;
|
|
5
5
|
letter-spacing: 0.08em;
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
z-index: calc(var(--ifm-z-index-fixed) - 2);
|
|
8
8
|
padding: 0.2em;
|
|
9
9
|
padding-left: 0.5em;
|
|
@@ -15,13 +15,13 @@
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
.controls > .title {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
flex-shrink: 1;
|
|
19
|
+
flex-grow: 1;
|
|
20
|
+
overflow-x: hidden;
|
|
21
|
+
text-overflow: ellipsis;
|
|
22
|
+
white-space: nowrap;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
.controls.slim {
|
|
26
26
|
padding: 0;
|
|
27
|
-
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import styles from './styles.module.css';
|
|
3
|
+
import CodeBlock from '@theme/CodeBlock';
|
|
4
|
+
import clsx from 'clsx';
|
|
5
|
+
import Icon from '@theme/CodeEditor/Icon';
|
|
6
|
+
import { translate } from '@docusaurus/Translate';
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
type: 'pre' | 'post';
|
|
10
|
+
code: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const HiddenCode = (props: Props) => {
|
|
14
|
+
const [show, setShow] = React.useState(false);
|
|
15
|
+
const { code } = props;
|
|
16
|
+
if (code.length === 0) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
return (
|
|
20
|
+
<div className={clsx(styles.container)}>
|
|
21
|
+
{show && (
|
|
22
|
+
<div>
|
|
23
|
+
<CodeBlock
|
|
24
|
+
language="python"
|
|
25
|
+
showLineNumbers={false}
|
|
26
|
+
className={clsx(styles.hiddenCode, styles.pre, show && styles.open)}
|
|
27
|
+
>
|
|
28
|
+
{code}
|
|
29
|
+
</CodeBlock>
|
|
30
|
+
</div>
|
|
31
|
+
)}
|
|
32
|
+
<button
|
|
33
|
+
className={clsx(styles.toggleButton, show && styles.open, styles[props.type])}
|
|
34
|
+
onClick={() => setShow(!show)}
|
|
35
|
+
title={translate({
|
|
36
|
+
id: 'theme.CodeEditor.Editor.HiddenCode.toggleButtonTitle',
|
|
37
|
+
message: 'Toggle hidden code'
|
|
38
|
+
})}
|
|
39
|
+
>
|
|
40
|
+
<Icon
|
|
41
|
+
icon={show ? 'TrayMinus' : 'TrayPlus'}
|
|
42
|
+
rotate={(show ? 180 : 0) + (props.type === 'post' ? 180 : 0)}
|
|
43
|
+
/>
|
|
44
|
+
</button>
|
|
45
|
+
</div>
|
|
46
|
+
);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export default HiddenCode;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
.container > .toggleButton {
|
|
2
|
+
position: absolute;
|
|
3
|
+
left: 50%;
|
|
4
|
+
top: 0px;
|
|
5
|
+
z-index: var(--ifm-z-index-dropdown);
|
|
6
|
+
opacity: var(--show-hidden-code-toggle-opacity);
|
|
7
|
+
transition: opacity 0.6s ease; /* Adjust timing as needed */
|
|
8
|
+
padding: 0;
|
|
9
|
+
background: transparent;
|
|
10
|
+
border: 0;
|
|
11
|
+
color: var(--ifm-color-info-darkest);
|
|
12
|
+
cursor: pointer;
|
|
13
|
+
}
|
|
14
|
+
.container > .toggleButton:hover {
|
|
15
|
+
color: var(--ifm-color-info);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.container > .toggleButton.post {
|
|
19
|
+
left: 50%;
|
|
20
|
+
top: unset;
|
|
21
|
+
bottom: 0px;
|
|
22
|
+
}
|
|
23
|
+
.toggleButton > svg {
|
|
24
|
+
transition: all 0.1s ease; /* Adjust timing as needed */
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.container > .toggleButton.open {
|
|
28
|
+
color: var(--ifm-color-danger);
|
|
29
|
+
}
|
|
30
|
+
.container > .toggleButton.open:hover {
|
|
31
|
+
color: var(--ifm-color-danger-darkest);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.hiddenCode {
|
|
35
|
+
margin-bottom: 0;
|
|
36
|
+
--ifm-pre-padding: 0 3em;
|
|
37
|
+
}
|
|
38
|
+
.hiddenCode pre {
|
|
39
|
+
border-radius: 0;
|
|
40
|
+
}
|
|
41
|
+
.hiddenCode pre > code {
|
|
42
|
+
background-color: var(--ifm-color-secondary-dark);
|
|
43
|
+
border-radius: 0;
|
|
44
|
+
}
|
|
45
|
+
.hiddenCode > div[class^='codeBlockContent'] > div[class^='buttonGroup'] {
|
|
46
|
+
right: 0;
|
|
47
|
+
top: 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
html[data-theme='dark'] .hiddenCode pre > code {
|
|
51
|
+
background-color: var(--ifm-card-background-color);
|
|
52
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { DOM_ELEMENT_IDS } from '
|
|
3
|
-
import Graphics from '
|
|
2
|
+
import { DOM_ELEMENT_IDS } from '@theme/CodeEditor/constants';
|
|
3
|
+
import Graphics from '@theme/CodeEditor/Editor/Result/Graphics';
|
|
4
4
|
import styles from './styles.module.css';
|
|
5
|
-
import {
|
|
6
|
-
import Button from '
|
|
5
|
+
import { useStore, useScript } from '@theme/CodeEditor/hooks';
|
|
6
|
+
import Button from '@theme/CodeEditor/Button';
|
|
7
7
|
|
|
8
8
|
const downloadCanvas = (canvasId: string) => {
|
|
9
9
|
const canvas = document.getElementById(canvasId) as HTMLCanvasElement;
|
|
@@ -13,49 +13,52 @@ const downloadCanvas = (canvasId: string) => {
|
|
|
13
13
|
var dt = canvas.toDataURL('image/png');
|
|
14
14
|
/* Change MIME type to trick the browser to downlaod the file instead of displaying it */
|
|
15
15
|
dt = dt.replace(/^data:image\/[^;]*/, 'data:application/octet-stream');
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
/* In addition to <a>'s "download" attribute, you can define HTTP-style headers */
|
|
18
|
-
dt = dt.replace(
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
dt = dt.replace(
|
|
19
|
+
/^data:application\/octet-stream/,
|
|
20
|
+
'data:application/octet-stream;headers=Content-Disposition%3A%20attachment%3B%20filename=Canvas.png'
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
var downloadLink = document.createElement('a');
|
|
21
24
|
downloadLink.href = dt;
|
|
22
25
|
downloadLink.download = `${canvasId}.png`;
|
|
23
26
|
document.body.appendChild(downloadLink);
|
|
24
27
|
downloadLink.click();
|
|
25
28
|
document.body.removeChild(downloadLink);
|
|
26
|
-
|
|
29
|
+
};
|
|
27
30
|
|
|
28
31
|
const Canvas = () => {
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
const codeId = useStore(store, (state) => state.codeId);
|
|
32
|
+
const store = useStore();
|
|
33
|
+
const codeId = useScript(store, 'codeId');
|
|
32
34
|
|
|
33
35
|
return (
|
|
34
36
|
<Graphics
|
|
35
37
|
controls={
|
|
36
38
|
<Button
|
|
37
|
-
icon=
|
|
38
|
-
iconSize=
|
|
39
|
+
icon="Download"
|
|
40
|
+
iconSize="12px"
|
|
39
41
|
onClick={() => {
|
|
40
|
-
downloadCanvas(DOM_ELEMENT_IDS.canvasContainer(codeId))
|
|
42
|
+
downloadCanvas(DOM_ELEMENT_IDS.canvasContainer(codeId));
|
|
41
43
|
}}
|
|
42
44
|
title="Download SVG"
|
|
43
45
|
className={styles.slimStrippedButton}
|
|
44
46
|
/>
|
|
45
47
|
}
|
|
46
48
|
main={
|
|
47
|
-
<canvas
|
|
48
|
-
id={DOM_ELEMENT_IDS.canvasContainer(codeId)}
|
|
49
|
+
<canvas
|
|
50
|
+
id={DOM_ELEMENT_IDS.canvasContainer(codeId)}
|
|
49
51
|
width="500"
|
|
50
52
|
height="500"
|
|
51
53
|
style={{
|
|
52
|
-
display: 'block',
|
|
53
|
-
width: '500px',
|
|
54
|
+
display: 'block',
|
|
55
|
+
width: '500px',
|
|
54
56
|
height: '500px'
|
|
55
|
-
}}
|
|
57
|
+
}}
|
|
58
|
+
></canvas>
|
|
56
59
|
}
|
|
57
60
|
/>
|
|
58
|
-
)
|
|
61
|
+
);
|
|
59
62
|
};
|
|
60
63
|
|
|
61
|
-
export default Canvas;
|
|
64
|
+
export default Canvas;
|
|
@@ -1,39 +1,43 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import styles from './styles.module.css';
|
|
3
|
-
import { DOM_ELEMENT_IDS } from '
|
|
4
|
-
import Graphics from '
|
|
5
|
-
import { saveSvg } from '
|
|
6
|
-
import {
|
|
7
|
-
import Button from '
|
|
3
|
+
import { DOM_ELEMENT_IDS } from '@theme/CodeEditor/constants';
|
|
4
|
+
import Graphics from '@theme/CodeEditor/Editor/Result/Graphics';
|
|
5
|
+
import { saveSvg } from '@theme/CodeEditor/Editor/utils/saveSvg';
|
|
6
|
+
import { useStore, useScript } from '@theme/CodeEditor/hooks';
|
|
7
|
+
import Button from '@theme/CodeEditor/Button';
|
|
8
8
|
import clsx from 'clsx';
|
|
9
9
|
|
|
10
10
|
const Turtle = () => {
|
|
11
|
-
const
|
|
12
|
-
const codeId =
|
|
13
|
-
const code =
|
|
11
|
+
const store = useStore();
|
|
12
|
+
const codeId = useScript(store, 'codeId');
|
|
13
|
+
const code = useScript(store, 'code');
|
|
14
14
|
return (
|
|
15
15
|
<Graphics
|
|
16
16
|
controls={
|
|
17
17
|
<React.Fragment>
|
|
18
18
|
<Button
|
|
19
|
-
icon=
|
|
19
|
+
icon="AnimationPlay"
|
|
20
20
|
onClick={() => {
|
|
21
|
-
const turtleResult =
|
|
21
|
+
const turtleResult = document.getElementById(
|
|
22
|
+
DOM_ELEMENT_IDS.turtleSvgContainer(codeId)
|
|
23
|
+
) as any as SVGSVGElement;
|
|
22
24
|
if (turtleResult) {
|
|
23
|
-
saveSvg(turtleResult, `${codeId}`, code, true)
|
|
25
|
+
saveSvg(turtleResult, `${codeId}`, code, true);
|
|
24
26
|
}
|
|
25
27
|
}}
|
|
26
28
|
className={clsx(styles.slimStrippedButton)}
|
|
27
|
-
iconSize=
|
|
29
|
+
iconSize="12px"
|
|
28
30
|
title="Download Animated SVG"
|
|
29
31
|
/>
|
|
30
32
|
<Button
|
|
31
|
-
icon=
|
|
32
|
-
iconSize=
|
|
33
|
+
icon="Download"
|
|
34
|
+
iconSize="12px"
|
|
33
35
|
onClick={() => {
|
|
34
|
-
const turtleResult =
|
|
36
|
+
const turtleResult = document.getElementById(
|
|
37
|
+
DOM_ELEMENT_IDS.turtleSvgContainer(codeId)
|
|
38
|
+
) as any as SVGSVGElement;
|
|
35
39
|
if (turtleResult) {
|
|
36
|
-
saveSvg(turtleResult, `${codeId}`, code)
|
|
40
|
+
saveSvg(turtleResult, `${codeId}`, code);
|
|
37
41
|
}
|
|
38
42
|
}}
|
|
39
43
|
title="Download SVG"
|
|
@@ -42,7 +46,7 @@ const Turtle = () => {
|
|
|
42
46
|
</React.Fragment>
|
|
43
47
|
}
|
|
44
48
|
/>
|
|
45
|
-
)
|
|
46
|
-
}
|
|
49
|
+
);
|
|
50
|
+
};
|
|
47
51
|
|
|
48
|
-
export default Turtle;
|
|
52
|
+
export default Turtle;
|
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import styles from './styles.module.css';
|
|
3
|
-
import { DOM_ELEMENT_IDS } from '
|
|
3
|
+
import { DOM_ELEMENT_IDS } from '@theme/CodeEditor/constants';
|
|
4
4
|
import Draggable from 'react-draggable';
|
|
5
|
-
import { checkForButtonClick } from '
|
|
6
|
-
import {
|
|
7
|
-
import Button from '
|
|
5
|
+
import { checkForButtonClick } from '@theme/CodeEditor/Editor/utils/checkForButtonClick';
|
|
6
|
+
import { useStore, useScript } from '@theme/CodeEditor/hooks';
|
|
7
|
+
import Button from '@theme/CodeEditor/Button';
|
|
8
8
|
import clsx from 'clsx';
|
|
9
|
-
interface Props {
|
|
10
|
-
controls?:
|
|
11
|
-
main?:
|
|
9
|
+
export interface Props {
|
|
10
|
+
controls?: React.ReactNode;
|
|
11
|
+
main?: React.ReactNode;
|
|
12
12
|
}
|
|
13
13
|
const Graphics = (props: Props) => {
|
|
14
|
-
const
|
|
15
|
-
const codeId =
|
|
14
|
+
const store = useStore();
|
|
15
|
+
const codeId = useScript(store, 'codeId');
|
|
16
|
+
const graphicsModalExecutionNr = useScript(store, 'graphicsModalExecutionNr');
|
|
17
|
+
const nodeRef = React.useRef(null);
|
|
16
18
|
return (
|
|
17
|
-
<Draggable
|
|
18
|
-
|
|
19
|
-
positionOffset={{ x: 0, y: '-50%' }}
|
|
20
|
-
>
|
|
21
|
-
<div className={styles.brythonGraphicsResult}>
|
|
19
|
+
<Draggable onStop={checkForButtonClick} positionOffset={{ x: '15%', y: '25%' }} nodeRef={nodeRef}>
|
|
20
|
+
<div className={styles.brythonGraphicsResult} ref={nodeRef}>
|
|
22
21
|
<div className={styles.brythonGraphicsResultHead}>
|
|
23
22
|
<span>Output</span>
|
|
24
23
|
<span className={styles.spacer}></span>
|
|
@@ -30,12 +29,13 @@ const Graphics = (props: Props) => {
|
|
|
30
29
|
store.stopScript();
|
|
31
30
|
store.closeGraphicsModal();
|
|
32
31
|
}}
|
|
33
|
-
iconSize=
|
|
32
|
+
iconSize="12px"
|
|
34
33
|
/>
|
|
35
34
|
</div>
|
|
36
35
|
<div
|
|
37
36
|
id={DOM_ELEMENT_IDS.graphicsResult(codeId)}
|
|
38
37
|
className="brython-graphics-result"
|
|
38
|
+
key={`exec-${graphicsModalExecutionNr}`}
|
|
39
39
|
>
|
|
40
40
|
{props.main}
|
|
41
41
|
</div>
|
|
@@ -44,4 +44,4 @@ const Graphics = (props: Props) => {
|
|
|
44
44
|
);
|
|
45
45
|
};
|
|
46
46
|
|
|
47
|
-
export default Graphics;
|
|
47
|
+
export default Graphics;
|
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import styles from './styles.module.css';
|
|
3
|
-
// @ts-ignore
|
|
4
3
|
import CodeBlock from '@theme/CodeBlock';
|
|
5
|
-
import {
|
|
4
|
+
import { useStore, useScript } from '@theme/CodeEditor/hooks';
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const Result = (props: Props) => {
|
|
11
|
-
const { store } = useScript();
|
|
12
|
-
const logs = useStore(store, (state) => state.logs);
|
|
6
|
+
const Result = () => {
|
|
7
|
+
const store = useStore();
|
|
8
|
+
const logs = useScript(store, 'logs');
|
|
13
9
|
if (logs.length === 0) {
|
|
14
10
|
return null;
|
|
15
11
|
}
|
|
16
|
-
const errors: string[] = []
|
|
12
|
+
const errors: string[] = [];
|
|
17
13
|
let lineNr = 1;
|
|
18
|
-
const code = logs.map((msg) => {
|
|
14
|
+
const code = logs.slice().map((msg) => {
|
|
19
15
|
const msgLen = (msg.output || '').split('\n').length - 1;
|
|
20
16
|
if (msg.type === 'stderr') {
|
|
21
17
|
errors.push(`${lineNr}-${lineNr + msgLen}`);
|
|
@@ -25,9 +21,7 @@ const Result = (props: Props) => {
|
|
|
25
21
|
});
|
|
26
22
|
return (
|
|
27
23
|
<div className={styles.result}>
|
|
28
|
-
<CodeBlock metastring={`{${errors.join(',')}}`}>
|
|
29
|
-
{code.join('')}
|
|
30
|
-
</CodeBlock>
|
|
24
|
+
<CodeBlock metastring={`{${errors.join(',')}}`}>{code.join('')}</CodeBlock>
|
|
31
25
|
</div>
|
|
32
26
|
);
|
|
33
27
|
};
|
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
.result {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
grid-area: result;
|
|
3
|
+
max-width: 100%;
|
|
4
|
+
overflow-x: auto;
|
|
5
5
|
--ifm-leading: 0;
|
|
6
6
|
flex-grow: 1;
|
|
7
7
|
flex-basis: 80ch;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
.result>pre {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
.result > pre {
|
|
11
|
+
margin-bottom: 0px;
|
|
12
|
+
border-top-left-radius: 0;
|
|
13
|
+
border-top-right-radius: 0;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
.result :global(.theme-code-block-highlighted-line) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
17
|
+
color: var(--ifm-color-danger-darker) !important;
|
|
18
|
+
background: transparent;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.result pre {
|
|
22
|
+
border-top-left-radius: 0;
|
|
23
|
+
border-top-right-radius: 0;
|
|
24
|
+
}
|
|
@@ -1,71 +1,73 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { DOM_ELEMENT_IDS } from '@theme/CodeEditor/constants';
|
|
3
|
+
import { useStore, useScript } from '@theme/CodeEditor/hooks';
|
|
4
|
+
import Result from '@theme/CodeEditor/Editor/Result';
|
|
5
|
+
import Turtle from '@theme/CodeEditor/Editor/Result/Graphics/Turtle';
|
|
6
|
+
import Canvas from '@theme/CodeEditor/Editor/Result/Graphics/Canvas';
|
|
7
|
+
import Graphics from '@theme/CodeEditor/Editor/Result/Graphics';
|
|
8
|
+
import Header from '@theme/CodeEditor/Editor/Header';
|
|
9
|
+
import EditorAce from '@theme/CodeEditor/Editor/EditorAce';
|
|
10
|
+
import clsx from 'clsx';
|
|
11
|
+
import styles from './styles.module.css';
|
|
12
|
+
import HiddenCode from '@theme/CodeEditor/Editor/HiddenCode';
|
|
12
13
|
|
|
13
|
-
interface Props {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
14
|
+
export interface Props {
|
|
15
|
+
slim: boolean;
|
|
16
|
+
title: string;
|
|
17
|
+
resettable: boolean;
|
|
18
|
+
showLineNumbers: boolean;
|
|
19
|
+
download: boolean;
|
|
20
|
+
lang: string;
|
|
21
|
+
noCompare: boolean;
|
|
22
|
+
preCode: string;
|
|
23
|
+
postCode: string;
|
|
24
|
+
maxLines?: number;
|
|
25
|
+
versioned?: boolean;
|
|
26
|
+
onChange?: (code: string) => void;
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
const Editor = (props: Props) => {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
);
|
|
30
|
+
const store = useStore();
|
|
31
|
+
const lang = useScript(store, 'lang');
|
|
32
|
+
const codeId = useScript(store, 'codeId');
|
|
33
|
+
const hasCanvasOutput = useScript(store, 'hasCanvasOutput');
|
|
34
|
+
const hasTurtleOutput = useScript(store, 'hasTurtleOutput');
|
|
35
|
+
const graphicsModalExecutionNr = useScript(store, 'graphicsModalExecutionNr');
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<React.Fragment>
|
|
39
|
+
<Header
|
|
40
|
+
slim={props.slim}
|
|
41
|
+
title={props.title}
|
|
42
|
+
resettable={props.resettable}
|
|
43
|
+
download={props.download}
|
|
44
|
+
noCompare={props.noCompare}
|
|
45
|
+
/>
|
|
46
|
+
<div className={clsx(styles.editorContainer)}>
|
|
47
|
+
<HiddenCode type="pre" code={props.preCode} />
|
|
48
|
+
<EditorAce
|
|
49
|
+
showLineNumbers={props.showLineNumbers}
|
|
50
|
+
maxLines={props.maxLines}
|
|
51
|
+
versioned={props.versioned}
|
|
52
|
+
onChange={props.onChange}
|
|
53
|
+
/>
|
|
54
|
+
<HiddenCode type="post" code={props.postCode} />
|
|
55
|
+
</div>
|
|
56
|
+
{lang === 'python' && (
|
|
57
|
+
<>
|
|
58
|
+
<Result />
|
|
59
|
+
<div id={DOM_ELEMENT_IDS.outputDiv(codeId)}></div>
|
|
60
|
+
{graphicsModalExecutionNr > 0 && (
|
|
61
|
+
<>
|
|
62
|
+
{hasTurtleOutput && <Turtle />}
|
|
63
|
+
{hasCanvasOutput && <Canvas />}
|
|
64
|
+
{!hasCanvasOutput && !hasTurtleOutput && <Graphics />}
|
|
65
|
+
</>
|
|
66
|
+
)}
|
|
67
|
+
</>
|
|
68
|
+
)}
|
|
69
|
+
</React.Fragment>
|
|
70
|
+
);
|
|
69
71
|
};
|
|
70
72
|
|
|
71
|
-
export default Editor;
|
|
73
|
+
export default Editor;
|
|
@@ -1,20 +1,28 @@
|
|
|
1
|
+
.editorContainer {
|
|
2
|
+
grid-area: editor;
|
|
3
|
+
position: relative;
|
|
4
|
+
--show-hidden-code-toggle-opacity: 0;
|
|
5
|
+
}
|
|
1
6
|
.editor {
|
|
2
|
-
grid-area: editor;
|
|
3
7
|
display: flex;
|
|
4
8
|
flex-wrap: wrap;
|
|
5
9
|
}
|
|
6
10
|
|
|
7
11
|
.editor .noGutter :global(.ace_scroller) {
|
|
8
|
-
|
|
12
|
+
left: 4px !important;
|
|
9
13
|
}
|
|
10
14
|
|
|
11
15
|
.editor :global(.ace_scrollbar.ace_scrollbar-h) {
|
|
12
|
-
|
|
16
|
+
overflow-x: hidden !important;
|
|
13
17
|
}
|
|
14
18
|
|
|
15
19
|
.brythonEditor {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
flex-grow: 1;
|
|
21
|
+
flex-basis: 80ch;
|
|
22
|
+
/*rtl:ignore*/
|
|
23
|
+
direction: ltr;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.editorContainer:hover {
|
|
27
|
+
--show-hidden-code-toggle-opacity: 1;
|
|
20
28
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {DraggableEvent} from 'react-draggable';
|
|
1
|
+
import { DraggableEvent } from 'react-draggable';
|
|
2
2
|
/**
|
|
3
3
|
* When using react-draggable, the click-event is not propagated
|
|
4
4
|
* to the button on touch devices. Fix this by clicking the button
|
|
5
|
-
* programmatically.
|
|
5
|
+
* programmatically.
|
|
6
6
|
*/
|
|
7
7
|
const checkForButtonClick = (event: DraggableEvent) => {
|
|
8
8
|
if (!event.type || event.type.toLowerCase() !== 'touchend') {
|
|
@@ -19,7 +19,7 @@ const checkForButtonClick = (event: DraggableEvent) => {
|
|
|
19
19
|
}
|
|
20
20
|
if (elem.tagName.toLowerCase() === 'div') {
|
|
21
21
|
if (elem.classList.contains('react-draggable')) {
|
|
22
|
-
elem = null
|
|
22
|
+
elem = null;
|
|
23
23
|
break;
|
|
24
24
|
}
|
|
25
25
|
}
|
|
@@ -28,6 +28,6 @@ const checkForButtonClick = (event: DraggableEvent) => {
|
|
|
28
28
|
// add the click to the end of the event queue
|
|
29
29
|
setTimeout(() => elem?.click(), 1);
|
|
30
30
|
}
|
|
31
|
-
}
|
|
31
|
+
};
|
|
32
32
|
|
|
33
|
-
export { checkForButtonClick }
|
|
33
|
+
export { checkForButtonClick };
|