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
|
<script>
import { linkRegex } from '../../utils';
import LineNumber from './line_number.vue';
export default {
functional: true,
props: {
line: {
type: Object,
required: true,
},
path: {
type: String,
required: true,
},
},
render(h, { props }) {
const { line, path } = props;
let chars;
if (gon?.features?.ciJobLineLinks) {
chars = line.content.map(content => {
return h(
'span',
{
class: ['gl-white-space-pre-wrap', content.style],
},
// Simple "tokenization": Split text in chunks of text
// which alternate between text and urls.
content.text.split(linkRegex).map(chunk => {
// Return normal string for non-links
if (!chunk.match(linkRegex)) {
return chunk;
}
return h(
'a',
{
attrs: {
href: chunk,
class: 'gl-reset-color! gl-text-decoration-underline',
rel: 'nofollow noopener noreferrer', // eslint-disable-line @gitlab/require-i18n-strings
},
},
chunk,
);
}),
);
});
} else {
chars = line.content.map(content => {
return h(
'span',
{
class: ['gl-white-space-pre-wrap', content.style],
},
content.text,
);
});
}
return h('div', { class: 'js-line log-line' }, [
h(LineNumber, {
props: {
lineNumber: line.lineNumber,
path,
},
}),
...chars,
]);
},
};
</script>
|