-
Notifications
You must be signed in to change notification settings - Fork 4
/
component.js
85 lines (72 loc) · 2.16 KB
/
component.js
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
import io from 'socket.io-client';
import React from 'react';
let worker = new Worker('/worker.bundle.js');
export default class LZ77 extends React.Component {
static defaultProps = {
url: null,
height: 300
};
constructor(props) {
super(props);
this.state = { data: '' };
}
componentWillMount() {
let socket = io(this.props.url);
socket.io.engine.on('upgrade', (transport) => {
let onData = transport.onData;
transport.onData = (data) => {
worker.postMessage(data);
onData.call(transport, data);
};
});
worker.onmessage = (e) => {
this.setState({ data: e.data });
};
}
render() {
return <div className="container">
<LZ77Visualizer
key="lz77"
height={this.props.height}
data={this.state.data} />
</div>;
}
}
class LZ77Visualizer extends React.Component {
constructor(props) {
super(props);
this.shouldScrollBottom = false;
}
componentWillUpdate() {
let { container } = this.refs;
this.shouldScrollBottom = !!container && container.scrollHeight - container.scrollTop - container.clientHeight < 100;
}
componentDidUpdate() {
let { container } = this.refs;
if (container && this.shouldScrollBottom) {
container.scrollTop = container.scrollHeight - container.clientHeight;
}
}
render() {
let { data } = this.props;
data = data || 'Waiting for incoming data..';
let html = htmlEscape(data)
.replace(/###start\[(\d+)\]###/g, (_, length) => {
let opacity = Math.min(parseInt(length, 10) / 20, 1);
return '<span style="background:rgba(255,255,0,' + opacity + ')">';
})
.replace(/###end###/g, '</span>');
return <pre
ref="container"
style={{
height: `${this.props.height}px`,
overflow: 'scroll',
font: '12px Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif'
}}
className="lz77"
dangerouslySetInnerHTML={{ __html: html }} />;
}
}
function htmlEscape(str) {
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
}