Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/components/Output/Output.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React from "react";
import { PYTHON, HTML, PROCESSING } from "../../constants";
import { PYTHON, HTML, PROCESSING, REACT } from "../../constants";
import { OUTPUT_ONLY } from "../../constants";
import EditorRadio from "../TextEditor/components/EditorRadio.js";
import CreateProcessingDoc from "../Output/Processing";
import CreatePythonDoc from "../Output/Python";
import CreateReactDoc from "../Output/React";
import { Button } from "reactstrap";
import ViewportAwareButton from "../common/ViewportAwareButton.js";
import OpenPanelButtonContainer from "../common/containers/OpenPanelButtonContainer.js";
Expand Down Expand Up @@ -99,6 +100,9 @@ class Output extends React.Component {
case PROCESSING:
srcDocFunc = () => CreateProcessingDoc(runResult, showConsole);
break;
case REACT:
srcDocFunc = () => CreateReactDoc(runResult, showConsole);
break;
case PYTHON:
runResult = btoa(runResult);
srcDocFunc = () => CreatePythonDoc(runResult, showConsole);
Expand Down
41 changes: 3 additions & 38 deletions src/components/Output/Processing.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,4 @@
const getProcessingSrcDocLoggingScript = () => `
<script type="text/javascript">
if (typeof console != "undefined")
if (typeof console.log != 'undefined')
console.olog = console.log;
else
console.olog = function() {};

console.log = (message) => {
console.olog(message);
let a = document.getElementById("inner")
if(a){
// a.style.display = "block"
a.value = a.value + "> " + message + "\\n";
if(a.scrollTop >= (a.scrollHeight - a.offsetHeight) - a.offsetHeight){
a.scrollTop = a.scrollHeight
}
}
};

window.onerror = (err)=> {
let a = document.getElementById("outer")
if(a){
a.style.display = "block"
}
console.log("\\n\\nERROR: " + err + "\\n")
}

console.error = console.debug = console.info = console.log;

function closeConsole(){
var mypre = document.getElementById("inner");
mypre.style.display = "none"
}
</script>
`;
import { getJsSrcDocLoggingScript } from "./constants";

const getUserScript = code => `
<script type="text/javascript">
Expand All @@ -48,7 +13,7 @@ const getProcessingSrcDocBody = (code, showConsole) => `
? `<div id="outer"><textarea id="inner"></textarea></div>`
: `<div id="outer" style="display:none;"><textarea id="inner"></textarea></div>`
}
${getProcessingSrcDocLoggingScript()}
${getJsSrcDocLoggingScript()}
${getUserScript(code)}
</body>
`;
Expand Down Expand Up @@ -81,6 +46,6 @@ const getProcessingSrcDocHead = () => `
</head>
`;

export default function(code, showConsole) {
export default function (code, showConsole) {
return `<html> ${getProcessingSrcDocHead()} ${getProcessingSrcDocBody(code, showConsole)}</html>`;
}
63 changes: 63 additions & 0 deletions src/components/Output/React.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { getJsSrcDocLoggingScript } from "./constants";

const getReactSrcDocHead = () => `
<head>
<style>html,body: {margin:0, width:100%}</style>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/@material-ui/core@latest/umd/material-ui.development.js" crossorigin="anonymous"></script>
<style>
#inner {
height:100px;
background-color:#222;
color: #DDD;
font-family: monospace;
word-wrap:break-word;
overflow:auto;
margin: 10px auto;
position:relative;
padding: 10px 35px 10px 10px;
width: 100%;
box-sizing: border-box; /* For IE and modern versions of Chrome */
-moz-box-sizing: border-box; /* For Firefox */
-webkit-box-sizing: border-box; /* For Safari */
}
#output {
display: block;
position: relative;
background: white;
min-height: 70vh;
padding: 10px 35px 10px 10px;
}
#closeConsoleButton { position: fixed; top: 20px; right: 30px; color: #ddd;}
</style>
</head>
`;

const getUserScript = (code) => `
<script type="text/babel">
${code}
ReactDOM.render(
<App />,
document.getElementById('output'),
);
</script>
`;

const getReactSrcDocBody = (code, showConsole) => `
<body>
${
showConsole
? `<div id="outer"><textarea id="inner"></textarea></div>`
: `<div id="outer" style="display:none;"><textarea id="inner"></textarea></div>`
}
${getJsSrcDocLoggingScript()}
${getUserScript(code)}
<div id="output"></div>
</body>
`;

export default function (code, showConsole) {
return `<html> ${getReactSrcDocHead()} ${getReactSrcDocBody(code, showConsole)}</html>`;
}
36 changes: 36 additions & 0 deletions src/components/Output/constants/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export const getJsSrcDocLoggingScript = () => `
<script type="text/javascript">
if (typeof console != "undefined")
if (typeof console.log != 'undefined')
console.olog = console.log;
else
console.olog = function() {};

console.log = (message) => {
console.olog(message);
let a = document.getElementById("inner")
if(a){
// a.style.display = "block"
a.value = a.value + "> " + message + "\\n";
if(a.scrollTop >= (a.scrollHeight - a.offsetHeight) - a.offsetHeight){
a.scrollTop = a.scrollHeight
}
}
};

window.onerror = (err)=> {
let a = document.getElementById("outer")
if(a){
a.style.display = "block"
}
console.log("\\n\\nERROR: " + err + "\\n")
}

console.error = console.debug = console.info = console.log;

function closeConsole(){
var mypre = document.getElementById("inner");
mypre.style.display = "none"
}
</script>
`;
11 changes: 7 additions & 4 deletions src/components/Sketches/constants/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const { PYTHON, HTML, PROCESSING, REACT } = require("../../../constants");

const SketchThumbnailArray = [
"Ant",
"Badger",
Expand Down Expand Up @@ -60,12 +62,13 @@ const SketchThumbnailArray = [
];

const LanguageDropdownValues = [
{ display: "Python", value: "python" },
{ display: "Processing", value: "processing" },
{ display: "HTML", value: "html" },
{ display: "Python", value: PYTHON },
{ display: "Processing", value: PROCESSING },
{ display: "React", value: REACT },
{ display: "HTML", value: HTML },
];

const LanguageDropdownDefault = { display: "Python", value: "python" };
const LanguageDropdownDefault = { display: "Python", value: PYTHON };

module.exports = {
SketchThumbnailArray,
Expand Down
14 changes: 9 additions & 5 deletions src/components/Sketches/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import CreateSketchModalContainer from "./containers/CreateSketchModalContainer"
import EditSketchModalContainer from "./containers/EditSketchModalContainer";
import OpenPanelButtonContainer from "../common/containers/OpenPanelButtonContainer";
import { SketchThumbnailArray } from "./constants";
import { PYTHON, PROCESSING, REACT, HTML } from "../../constants";
import CodeDownloader from "../../util/languages/CodeDownloader";
import "styles/Sketches.scss";

Expand All @@ -13,8 +14,7 @@ import { Button } from "reactstrap";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCogs } from "@fortawesome/free-solid-svg-icons";
import { faFile } from "@fortawesome/free-solid-svg-icons";
import { faPython } from "@fortawesome/free-brands-svg-icons";
import { faHtml5 } from "@fortawesome/free-brands-svg-icons";
import { faPython, faHtml5, faReact } from "@fortawesome/free-brands-svg-icons";

const ROW_PADDING = 100;
const SKETCH_WIDTH = 220;
Expand Down Expand Up @@ -109,15 +109,19 @@ class Sketches extends React.Component {
let faLanguage;
let languageDisplay; // not a great way to do this!
switch (language) {
case "python":
case PYTHON:
faLanguage = faPython;
languageDisplay = "Python";
break;
case "processing":
case PROCESSING:
faLanguage = faCogs;
languageDisplay = "Processing";
break;
case "html":
case REACT:
faLanguage = faReact;
languageDisplay = "React";
break;
case HTML:
default:
faLanguage = faHtml5;
languageDisplay = "HTML";
Expand Down
1 change: 1 addition & 0 deletions src/components/TextEditor/components/TextEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ if (typeof window !== "undefined" && typeof window.navigator !== "undefined") {
require("codemirror/mode/javascript/javascript.js");
require("codemirror/mode/htmlmixed/htmlmixed.js");
require("codemirror/mode/python/python.js");
require("codemirror/mode/jsx/jsx.js");
require("codemirror/mode/clike/clike.js");
}
/**----------Props--------
Expand Down
28 changes: 17 additions & 11 deletions src/components/common/DropdownButton.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from "react";
import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from "reactstrap";
import { faCogs } from "@fortawesome/free-solid-svg-icons";
import { faPython } from "@fortawesome/free-brands-svg-icons";
import { faHtml5 } from "@fortawesome/free-brands-svg-icons";
import { faPython, faHtml5, faReact } from "@fortawesome/free-brands-svg-icons";
import { PYTHON, PROCESSING, REACT, HTML } from "../../constants";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

/**--------Props---------------
Expand All @@ -25,11 +25,11 @@ export default class DropdownButton extends React.Component {
//==============React Lifecycle Functions===================//
componentDidMount() {}

toggleHandler = prevVal => {
toggleHandler = (prevVal) => {
this.setState({ dropdownOpen: !prevVal });
};

selectLanguage = program => {
selectLanguage = (program) => {
let result = true;
if (this.props.dirty) {
result = window.confirm("Are you sure you want to change programs? You have unsaved changes");
Expand All @@ -42,16 +42,19 @@ export default class DropdownButton extends React.Component {

renderDropdownItems = () => {
//map each program string in the array to a dropdown item
return this.props.dropdownItems.map(program => {
return this.props.dropdownItems.map((program) => {
let faLanguage;
switch (program.language) {
case "python":
case PYTHON:
faLanguage = faPython;
break;
case "processing":
case PROCESSING:
faLanguage = faCogs;
break;
case "html":
case REACT:
faLanguage = faReact;
break;
case HTML:
default:
faLanguage = faHtml5;
}
Expand All @@ -72,13 +75,16 @@ export default class DropdownButton extends React.Component {

let faLanguage;
switch (this.props.currentLanguage) {
case "python":
case PYTHON:
faLanguage = faPython;
break;
case "processing":
case PROCESSING:
faLanguage = faCogs;
break;
case "html":
case REACT:
faLanguage = faReact;
break;
case HTML:
default:
faLanguage = faHtml5;
}
Expand Down
6 changes: 5 additions & 1 deletion src/constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ const PYTHON = "python";
const JAVASCRIPT = "javascript";
const HTML = "html";
const PROCESSING = "processing";
const REACT = "react";

const SUPPORTED_LANGUAGES = [PYTHON, JAVASCRIPT, HTML, PROCESSING];
const SUPPORTED_LANGUAGES = [PYTHON, JAVASCRIPT, HTML, PROCESSING, REACT];

//used for syntax highlighting in editor
let CODEMIRROR_CONVERSIONS = {};
Expand All @@ -21,6 +22,8 @@ SUPPORTED_LANGUAGES.forEach((lang) => {
return (CODEMIRROR_CONVERSIONS[lang] = "htmlmixed");
case PROCESSING:
return (CODEMIRROR_CONVERSIONS[lang] = "javascript");
case REACT:
return (CODEMIRROR_CONVERSIONS[lang] = "jsx");
default:
console.error("SUPPORTED LANGUAGE WITH NO MODE");
}
Expand Down Expand Up @@ -76,6 +79,7 @@ module.exports = {
JAVASCRIPT,
HTML,
PROCESSING,
REACT,

// photo names
PHOTO_NAMES,
Expand Down
22 changes: 15 additions & 7 deletions src/util/languages/CodeDownloader.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import ProcessingConstructor from "../../components/Output/Processing";
import ReactConstructor from "../../components/Output/React";
import { PYTHON, REACT, HTML, PROCESSING } from "../../constants";

export default class CodeDownloader {
static download = (name, language, code) => {
let extension = ".";
switch (language) {
case "python":
case PYTHON:
extension += "py";
break;
case "processing": // this is because we construct the processing result as an HTML file. jank.
case "html":
case PROCESSING: // this is because we construct the processing result as an HTML file. jank.
case REACT: // same here
case HTML:
extension += "html";
break;
default:
Expand All @@ -17,10 +20,15 @@ export default class CodeDownloader {
// taken from this: https://stackoverflow.com/questions/44656610/download-a-string-as-txt-file-in-react
const element = document.createElement("a");
let file;
if (language === "processing") {
file = new Blob([ProcessingConstructor(code, true)], { type: "text/plain" });
} else {
file = new Blob([code], { type: "text/plain" });
switch (language) {
case PROCESSING:
file = new Blob([ProcessingConstructor(code, true)], { type: "text/plain" });
break;
case REACT:
file = new Blob([ReactConstructor(code, true)], { type: "text/plain" });
break;
default:
file = new Blob([code], { type: "text/plain" });
}
element.href = URL.createObjectURL(file);
element.download = name + extension;
Expand Down