forked from agermanidis/livepython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCodeView.js
More file actions
111 lines (99 loc) · 2.96 KB
/
Copy pathCodeView.js
File metadata and controls
111 lines (99 loc) · 2.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import React, {Component} from 'react'
import jq from 'jquery'
import SyntaxHighlighter from 'react-syntax-highlighter'
import { tomorrowNight } from 'react-syntax-highlighter/dist/styles'
tomorrowNight.hljs.background = 'none'
tomorrowNight.hljs.padding = 0
class CodeView extends Component {
constructor() {
super();
this.state = {
activity: null,
intervalId: null
};
}
spaceFixedLineNumber(curLine, totLines) {
return (
"\u00a0".repeat(totLines.toString().length - curLine.toString().length) +
curLine.toString()
);
}
componentDidMount() {
this.tick();
}
tick() {
try {
const currentOffset = document.scrollingElement.scrollTop;
const targetOffset = jq(".selected").offset().top - 400;
const change = (targetOffset - currentOffset) / 30;
document.scrollingElement.scrollTop += change;
} catch (e) {}
requestAnimationFrame(this.tick.bind(this));
}
componentWillReceiveProps(props) {
var activity = JSON.parse(JSON.stringify(this.state.activity)) || {};
if (!hasOwnProperty.call(activity, props.filename)) {
activity[props.filename] = {};
}
activity[props.filename][props.lineno - 1] = Date.now();
this.setState({ activity });
}
render() {
if (!this.state.activity) return "";
if (!this.state.activity[this.props.filename]) return "";
if (!this.props.source) return "";
var lines = this.props.source.split("\n");
var lineEls = [];
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (!line.length) line = "\n";
var isExceptionLine = false;
var cs = "line";
var exceptionMessage;
if (this.props.exception) {
var exception = this.props.exception;
if (i === exception.lineno - 1) {
isExceptionLine = true;
cs += " exception";
exceptionMessage = " " + exception.type + ": " + exception.message;
}
} else if (
i === this.props.lineno - 1 &&
this.props.state !== "finished"
) {
cs += " selected";
}
const lastActive = this.state.activity[this.props.filename][i] || 0;
const opacity = 1 - Math.min(1, (Date.now() - lastActive) / 800);
var el = (
<div
key={i}
className={cs}
style={{
backgroundColor: `rgba(39, 136, 101, ${opacity})`
}}
>
<p key={i} className="line-number">
{this.spaceFixedLineNumber(i + 1, lines.length)}
</p>
<SyntaxHighlighter language="python" style={tomorrowNight}>
{line}
</SyntaxHighlighter>
{isExceptionLine && (
<pre id="exception-message">{exceptionMessage}</pre>
)}
{"\n"}
</div>
);
lineEls.push(el);
}
return (
<div id="code-view">
<div id="source">
<div id="code-area">{lineEls}</div>
</div>
</div>
);
}
}
export default CodeView