Skip to content

Commit 58d0dba

Browse files
committed
remove dead code, fix linting errors, get infinite loop functionality working
1 parent f9d487e commit 58d0dba

File tree

7 files changed

+31
-127
lines changed

7 files changed

+31
-127
lines changed

client/modules/IDE/actions/ide.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,10 @@ export function setUnsavedChanges(value) {
183183
};
184184
}
185185

186-
export function detectInfiniteLoops() {
186+
export function detectInfiniteLoops(message) {
187187
return {
188-
type: ActionTypes.DETECT_INFINITE_LOOPS
188+
type: ActionTypes.DETECT_INFINITE_LOOPS,
189+
message
189190
};
190191
}
191192

client/modules/IDE/components/Console.js

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,23 @@ class Console extends React.Component {
2020
* @type {Array}
2121
*/
2222
this.children = [];
23+
this.appendConsoleEvent = this.appendConsoleEvent.bind(this);
2324
}
2425

2526
componentWillReceiveProps(nextProps) {
2627
if (nextProps.isPlaying && !this.props.isPlaying) {
2728
this.children = [];
28-
} else if (nextProps.consoleEvent !== this.props.consoleEvent) {
29+
} else if (nextProps.consoleEvent !== this.props.consoleEvent && this.props.isPlaying) {
2930
const args = nextProps.consoleEvent.arguments;
3031
Object.keys(args).forEach((key) => {
3132
if (args[key].includes('Exiting potential infinite loop')) {
32-
// stop sketch
33-
// dispatch infinite loop found
3433
this.props.stopSketch();
35-
this.props.detectInfiniteLoops();
34+
this.props.expandConsole();
35+
this.appendConsoleEvent(nextProps.consoleEvent);
3636
}
3737
});
3838
if (nextProps.isExpanded) {
39-
// const args = nextProps.consoleEvent.arguments;
40-
const method = nextProps.consoleEvent.method;
41-
const nextChild = (
42-
<div key={this.children.length} className={`preview-console__${method}`}>
43-
{Object.keys(args).map((key) => <span key={`${this.children.length}-${key}`}>{args[key]}</span>)}
44-
</div>
45-
);
46-
this.children.push(nextChild);
39+
this.appendConsoleEvent(nextProps.consoleEvent);
4740
}
4841
}
4942
}
@@ -58,6 +51,17 @@ class Console extends React.Component {
5851
this.refs.console_messages.scrollTop = this.refs.console_messages.scrollHeight;
5952
}
6053

54+
appendConsoleEvent(consoleEvent) {
55+
const args = consoleEvent.arguments;
56+
const method = consoleEvent.method;
57+
const nextChild = (
58+
<div key={this.children.length} className={`preview-console__${method}`}>
59+
{Object.keys(args).map((key) => <span key={`${this.children.length}-${key}`}>{args[key]}</span>)}
60+
</div>
61+
);
62+
this.children.push(nextChild);
63+
}
64+
6165
render() {
6266
const childrenToDisplay = this.children.slice(-consoleMax);
6367
const consoleClass = classNames({
@@ -92,7 +96,6 @@ Console.propTypes = {
9296
collapseConsole: PropTypes.func.isRequired,
9397
expandConsole: PropTypes.func.isRequired,
9498
stopSketch: PropTypes.func.isRequired,
95-
detectInfiniteLoops: PropTypes.func.isRequired
9699
};
97100

98101
export default Console;

client/modules/IDE/components/Editor.js

Lines changed: 1 addition & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ const downArrowUrl = require('../../../images/down-arrow.svg');
2828
import classNames from 'classnames';
2929

3030
import { debounce } from 'throttle-debounce';
31-
import loopProtect from 'loop-protect';
3231

3332
class Editor extends React.Component {
3433
constructor(props) {
@@ -66,17 +65,12 @@ class Editor extends React.Component {
6665
}
6766
});
6867

69-
this._cm.on('change', debounce(1000, () => {
68+
this._cm.on('change', debounce(200, () => {
7069
this.props.setUnsavedChanges(true);
7170
this.props.updateFileContent(this.props.file.name, this._cm.getValue());
7271
if (this.props.autorefresh && this.props.isPlaying) {
7372
this.props.startRefreshSketch();
7473
}
75-
// this.checkForInfiniteLoop((infiniteLoop, prevs) => {
76-
// if (!infiniteLoop && prevs && this.props.autorefresh) {
77-
// this.props.startRefreshSketch();
78-
// }
79-
// });
8074
}));
8175

8276
this._cm.on('keyup', () => {
@@ -123,14 +117,6 @@ class Editor extends React.Component {
123117
if (this.props.theme !== prevProps.theme) {
124118
this._cm.setOption('theme', `p5-${this.props.theme}`);
125119
}
126-
127-
if (this.props.infiniteLoop && this.props.infiniteLoop !== prevProps.infiniteLoop) {
128-
const msg = document.createElement('div');
129-
const loopError = 'Loop is taking too long to run. This might be an infinite loop.';
130-
msg.appendChild(document.createTextNode(loopError));
131-
msg.className = 'lint-error';
132-
this.widgets.push(this._cm.addLineWidget(1, msg, { coverGutter: false, noHScroll: true }));
133-
}
134120
}
135121

136122
componentWillUnmount() {
@@ -153,77 +139,6 @@ class Editor extends React.Component {
153139
}
154140
}
155141

156-
checkForInfiniteLoop(callback) {
157-
const prevIsplaying = this.props.isPlaying;
158-
let infiniteLoop = false;
159-
let prevLine;
160-
this.props.resetInfiniteLoops();
161-
let iframe;
162-
163-
for (let i = 0; i < this.widgets.length; ++i) {
164-
this._cm.removeLineWidget(this.widgets[i]);
165-
}
166-
this.widgets.length = 0;
167-
168-
loopProtect.alias = 'protect';
169-
170-
let foundInfiniteLoop = false;
171-
loopProtect.hit = (line) => {
172-
foundInfiniteLoop = true;
173-
if (line !== prevLine) {
174-
this.props.detectInfiniteLoops();
175-
this.props.stopSketch();
176-
infiniteLoop = true;
177-
callback(infiniteLoop, prevIsplaying);
178-
const msg = document.createElement('div');
179-
const loopError = `line ${line}: This loop is taking too long to run. This might be an infinite loop.`;
180-
msg.appendChild(document.createTextNode(loopError));
181-
msg.className = 'lint-error';
182-
this.widgets.push(this._cm.addLineWidget(line - 1, msg, { coverGutter: false, noHScroll: true }));
183-
prevLine = line;
184-
}
185-
};
186-
187-
const processed = loopProtect(this.props.file.content);
188-
189-
let iframeForLoop = document.getElementById('iframeForLoop');
190-
if (iframeForLoop === null) {
191-
iframe = document.createElement('iframe');
192-
iframe.id = 'iframeForLoop';
193-
iframe.style.display = 'none';
194-
document.body.appendChild(iframe);
195-
iframeForLoop = iframe;
196-
} else {
197-
iframeForLoop.srcdoc = '';
198-
}
199-
const win = iframeForLoop.contentWindow;
200-
const doc = win.document;
201-
doc.open();
202-
203-
win.protect = loopProtect;
204-
205-
doc.write(`<!DOCTYPE html>
206-
<html>
207-
<head>
208-
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/p5.min.js"></script>
209-
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/addons/p5.dom.min.js"></script>
210-
</head>
211-
<body>
212-
<script>
213-
${processed}
214-
</script>
215-
</body>
216-
</html>`);
217-
win.onerror = () => true;
218-
doc.close();
219-
220-
setTimeout(() => {
221-
if (!foundInfiniteLoop) {
222-
callback(infiniteLoop, prevIsplaying, prevLine);
223-
}
224-
}, 200);
225-
}
226-
227142
_cm: CodeMirror.Editor
228143

229144
render() {
@@ -289,14 +204,10 @@ Editor.propTypes = {
289204
closeEditorOptions: PropTypes.func.isRequired,
290205
showKeyboardShortcutModal: PropTypes.func.isRequired,
291206
setUnsavedChanges: PropTypes.func.isRequired,
292-
infiniteLoop: PropTypes.bool.isRequired,
293-
detectInfiniteLoops: PropTypes.func.isRequired,
294-
resetInfiniteLoops: PropTypes.func.isRequired,
295207
startRefreshSketch: PropTypes.func.isRequired,
296208
autorefresh: PropTypes.bool.isRequired,
297209
isPlaying: PropTypes.bool.isRequired,
298210
theme: PropTypes.string.isRequired,
299-
stopSketch: PropTypes.func.isRequired
300211
};
301212

302213
export default Editor;

client/modules/IDE/components/PreviewFrame.js

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -217,30 +217,25 @@ class PreviewFrame extends React.Component {
217217
let htmlHeadContents = htmlHead[0].split(headRegex)[1];
218218
htmlHeadContents = htmlHeadContents.slice(1, htmlHeadContents.length - 2);
219219
htmlHeadContents += '<script type="text/javascript" src="/loop-protect.min.js"></script>\n';
220-
htmlFile = htmlFile.replace(/(?:<head.*?>)([\s\S]*?)(?:<\/head>)/gmi, `<head>\n${htmlHeadContents}\n</head>`);
221220

222221
if (this.props.textOutput || this.props.isTextOutputPlaying) {
223-
const htmlHead = htmlFile.match(/(?:<head.*?>)([\s\S]*?)(?:<\/head>)/gmi);
224-
const headRegex = new RegExp('head', 'i');
225-
let htmlHeadContents = htmlHead[0].split(headRegex)[1];
226-
htmlHeadContents = htmlHeadContents.slice(1, htmlHeadContents.length - 2);
227222
htmlHeadContents += '<script src="/loadData.js"></script>\n';
228223
htmlHeadContents += '<script src="/interceptor-functions.js"></script>\n';
229224
htmlHeadContents += '<script src="/intercept-p5.js"></script>\n';
230225
htmlHeadContents += '<script type="text/javascript" src="/ntc.min.js"></script>';
231-
htmlFile = htmlFile.replace(/(?:<head.*?>)([\s\S]*?)(?:<\/head>)/gmi, `<head>\n${htmlHeadContents}\n</head>`);
232226
}
233227

228+
htmlFile = htmlFile.replace(/(?:<head.*?>)([\s\S]*?)(?:<\/head>)/gmi, `<head>\n${htmlHeadContents}\n</head>`);
229+
234230
scriptOffs = getAllScriptOffsets(htmlFile);
235231
htmlFile += hijackConsoleErrorsScript(JSON.stringify(scriptOffs));
236232

237233
return htmlFile;
238234
}
239235

240236
renderSketch() {
241-
this.props.resetInfiniteLoops();
242237
const doc = ReactDOM.findDOMNode(this);
243-
if (this.props.isPlaying && !this.props.infiniteLoop) {
238+
if (this.props.isPlaying) {
244239
srcDoc.set(doc, this.injectLocalFiles());
245240
this.props.endSketchRefresh();
246241
} else {
@@ -288,8 +283,6 @@ PreviewFrame.propTypes = {
288283
files: PropTypes.array.isRequired,
289284
dispatchConsoleEvent: PropTypes.func,
290285
children: PropTypes.element,
291-
infiniteLoop: PropTypes.bool.isRequired,
292-
resetInfiniteLoops: PropTypes.func.isRequired,
293286
autorefresh: PropTypes.bool.isRequired,
294287
endSketchRefresh: PropTypes.func.isRequired,
295288
previewIsRefreshing: PropTypes.bool.isRequired,

client/modules/IDE/components/Toolbar.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class Toolbar extends React.Component {
7272
>
7373
<InlineSVG src={stopUrl} alt="Stop Sketch" />
7474
</button>
75-
{/* <div className="toolbar__autorefresh">
75+
<div className="toolbar__autorefresh">
7676
<input
7777
id="autorefresh"
7878
type="checkbox"
@@ -84,7 +84,7 @@ class Toolbar extends React.Component {
8484
<label htmlFor="autorefresh" className="toolbar__autorefresh-label">
8585
Auto-refresh
8686
</label>
87-
</div> */}
87+
</div>
8888
<div className={nameContainerClass}>
8989
<a
9090
className="toolbar__project-name"

client/modules/IDE/pages/IDEView.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,6 @@ class IDEView extends React.Component {
277277
closeEditorOptions={this.props.closeEditorOptions}
278278
showKeyboardShortcutModal={this.props.showKeyboardShortcutModal}
279279
setUnsavedChanges={this.props.setUnsavedChanges}
280-
infiniteLoop={this.props.ide.infiniteLoop}
281-
detectInfiniteLoops={this.props.detectInfiniteLoops}
282-
resetInfiniteLoops={this.props.resetInfiniteLoops}
283280
isPlaying={this.props.ide.isPlaying}
284281
theme={this.props.preferences.theme}
285282
startRefreshSketch={this.props.startRefreshSketch}
@@ -293,7 +290,6 @@ class IDEView extends React.Component {
293290
expandConsole={this.props.expandConsole}
294291
collapseConsole={this.props.collapseConsole}
295292
stopSketch={this.props.stopSketch}
296-
detectInfiniteLoops={this.props.detectInfiniteLoops}
297293
/>
298294
</SplitPane>
299295
<div>
@@ -322,8 +318,6 @@ class IDEView extends React.Component {
322318
isTextOutputPlaying={this.props.ide.isTextOutputPlaying}
323319
textOutput={this.props.preferences.textOutput}
324320
dispatchConsoleEvent={this.props.dispatchConsoleEvent}
325-
infiniteLoop={this.props.ide.infiniteLoop}
326-
resetInfiniteLoops={this.props.resetInfiniteLoops}
327321
autorefresh={this.props.preferences.autorefresh}
328322
previewIsRefreshing={this.props.ide.previewIsRefreshing}
329323
endSketchRefresh={this.props.endSketchRefresh}
@@ -433,7 +427,8 @@ IDEView.propTypes = {
433427
keyboardShortcutVisible: PropTypes.bool.isRequired,
434428
unsavedChanges: PropTypes.bool.isRequired,
435429
infiniteLoop: PropTypes.bool.isRequired,
436-
previewIsRefreshing: PropTypes.bool.isRequired
430+
previewIsRefreshing: PropTypes.bool.isRequired,
431+
infiniteLoopMessage: PropTypes.string.isRequired
437432
}).isRequired,
438433
startSketch: PropTypes.func.isRequired,
439434
stopSketch: PropTypes.func.isRequired,

client/modules/IDE/reducers/ide.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ const initialState = {
1818
keyboardShortcutVisible: false,
1919
unsavedChanges: false,
2020
infiniteLoop: false,
21-
previewIsRefreshing: false
21+
previewIsRefreshing: false,
22+
infiniteLoopMessage: ''
2223
};
2324

2425
const ide = (state = initialState, action) => {
@@ -74,9 +75,9 @@ const ide = (state = initialState, action) => {
7475
case ActionTypes.SET_UNSAVED_CHANGES:
7576
return Object.assign({}, state, { unsavedChanges: action.value });
7677
case ActionTypes.DETECT_INFINITE_LOOPS:
77-
return Object.assign({}, state, { infiniteLoop: true });
78+
return Object.assign({}, state, { infiniteLoop: true, infiniteLoopMessage: action.message });
7879
case ActionTypes.RESET_INFINITE_LOOPS:
79-
return Object.assign({}, state, { infiniteLoop: false });
80+
return Object.assign({}, state, { infiniteLoop: false, infiniteLoopMessage: '' });
8081
case ActionTypes.START_SKETCH_REFRESH:
8182
return Object.assign({}, state, { previewIsRefreshing: true });
8283
case ActionTypes.END_SKETCH_REFRESH:

0 commit comments

Comments
 (0)