/
context.jsx
117 lines (102 loc) · 3.37 KB
/
context.jsx
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
112
113
114
115
116
117
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { CodeSnippet } from 'components/test';
import isString from 'lodash/isString';
import classNames from 'classnames/bind';
import styles from './test.css';
const cx = classNames.bind(styles);
const imgRegEx = /(?:png|jpe?g|gif)$/i;
const protocolRegEx = /^(?:(?:https?|ftp):\/\/)/i;
const urlRegEx = /^(?:(?:https?|ftp):\/\/)?(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/ // eslint-disable-line
class TestContext extends Component {
static displayName = 'TestContext';
static propTypes = {
className: PropTypes.string,
context: PropTypes.oneOfType([
PropTypes.string,
PropTypes.object,
PropTypes.array
])
};
renderImage = (ctx, title) => {
const isUrl = urlRegEx.test(ctx);
const hasProtocol = protocolRegEx.test(ctx);
const linkUrl = (isUrl && !hasProtocol) ? `http://${ctx}` : ctx;
return (
<a
href={ linkUrl }
className={ cx('image-link') }
rel='noopener noreferrer'
target='_blank' >
<img src={ linkUrl } className={ cx('image') } alt={ title } />
</a>
);
}
renderLink = (url, title) => {
const linkUrl = `${protocolRegEx.test(url) ? '' : 'http://'}${url}`;
return (
<a
href={ linkUrl }
className={ cx('text-link') }
rel='noopener noreferrer'
target='_blank'
alt={ title } >
{ url }
</a>
);
}
renderContextContent = (content, title, highlight = false) => {
// Images
if (imgRegEx.test(content)) {
return this.renderImage(content, title);
}
// URLs
if (urlRegEx.test(content)) {
return this.renderLink(content, title);
}
// Default
const code = isString(content) ? content : JSON.stringify(content, null, 2);
return (
<CodeSnippet className={ cx('code-snippet') } code={ code } highlight={ highlight } />
);
}
renderContext = (ctx, i) => {
const containerProps = {
className: cx('context-item')
};
if (i !== undefined) {
containerProps.key = i;
}
// Context is a simple string
if (isString(ctx)) {
return (
<div { ...containerProps } >
{ this.renderContextContent(ctx) }
</div>
);
}
// Context is an object with title and value
const { title, value } = ctx;
return (
<div { ...containerProps } >
<h4 className={ cx('context-item-title') }>{ title }:</h4>
{ this.renderContextContent(value, title, true) }
</div>
);
}
render() {
const { className, context } = this.props;
// All context comes in stringified initially so we parse it here
const ctx = JSON.parse(context);
return (
<div className={ cx(className, 'context') }>
<h4 className={ cx('context-title') }>Additional Test Context</h4>
{ Array.isArray(ctx)
? ctx.map(this.renderContext)
: this.renderContext(ctx)
}
</div>
);
}
}
export default TestContext;