Skip to content

Commit 928cc28

Browse files
committed
CodeCoverage: HTML template facelift
1 parent 7380e44 commit 928cc28

File tree

2 files changed

+100
-68
lines changed

2 files changed

+100
-68
lines changed

src/CodeCoverage/Generators/HtmlGenerator.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,11 @@ protected function renderSelf()
6262

6363
private function setupHighlight()
6464
{
65-
ini_set('highlight.comment', '#999; font-style: italic');
66-
ini_set('highlight.default', '#000');
67-
ini_set('highlight.html', '#06B');
68-
ini_set('highlight.keyword', '#D24; font-weight: bold');
69-
ini_set('highlight.string', '#080');
65+
ini_set('highlight.comment', 'hc');
66+
ini_set('highlight.default', 'hd');
67+
ini_set('highlight.html', 'hh');
68+
ini_set('highlight.keyword', 'hk');
69+
ini_set('highlight.string', 'hs');
7070
}
7171

7272

src/CodeCoverage/Generators/template.phtml

Lines changed: 95 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -9,45 +9,72 @@
99

1010
<style type="text/css">
1111
html {
12-
font: 16px/1.5 sans-serif;
13-
border-top: 4.7em solid #F4EBDB;
12+
font: 14px/1.5 Verdana,"Geneva CE",lucida,sans-serif;
13+
border-top: 4.7em solid #f4ebdb;
1414
}
1515

1616
body {
1717
max-width: 990px;
1818
margin: -4.7em auto 0;
19-
background: white;
19+
background: #fcfaf5;
2020
color: #333;
2121
}
2222

23+
footer {
24+
margin-left: .5em;
25+
}
26+
2327
h1 {
28+
font-family: "Trebuchet MS","Geneva CE",lucida,sans-serif;
2429
font-size: 1.9em;
25-
margin: .5em 0 1.5em;
26-
color: #7A7772;
30+
margin: .5em .5em 1.5em;
31+
color: #7a7772;
2732
text-shadow: 1px 1px 0 white;
2833
}
2934

3035
div.code {
31-
font: 14px/1.2 Consolas, monospace;
32-
background: #FDF5CE;
33-
padding: .4em .7em;
36+
background: white;
3437
border: 1px dotted silver;
35-
overflow-x: auto;
3638
display: none;
39+
color: #333;
40+
position: relative;
41+
overflow: auto;
42+
}
43+
44+
code,
45+
div.code {
46+
font: 13px/1.3 monospace;
47+
padding: .4em .7em;
48+
}
49+
50+
div.code div {
51+
white-space: pre;
3752
}
3853

39-
span.line {
40-
color: #9F9C7F;
41-
font-weight: normal;
42-
font-style: normal;
54+
div.code a {
55+
color: #c0c0c0;
4356
}
4457

45-
.t {
46-
background: #99f999;
58+
div.code a:hover {
59+
color: inherit;
60+
font-weight: bold;
61+
text-decoration: none;
4762
}
4863

49-
.u {
50-
background: #f9ac9e;
64+
code {
65+
white-space: nowrap;
66+
position: absolute;
67+
top: 0;
68+
}
69+
70+
a {
71+
color: #006aeb;
72+
text-decoration: none;
73+
}
74+
75+
a:active,
76+
a:hover {
77+
text-decoration: underline;
5178
}
5279

5380
td {
@@ -64,14 +91,14 @@
6491
}
6592

6693
.bar {
67-
border: 1px solid #ACACAC;
94+
border: 1px solid #acacac;
6895
background: #e50400;
6996
width: 35px;
7097
height: 1em;
7198
}
7299

73100
.bar div {
74-
background: #1A7E1E;
101+
background: #1a7e1e;
75102
height: 1em;
76103
}
77104

@@ -86,6 +113,15 @@
86113
.not-loaded td * {
87114
color: red;
88115
}
116+
117+
.t { background-color: #e0ffe0; }
118+
.u { background-color: #ffe0e0; }
119+
120+
code .hc { color: #929292; }
121+
code .hd { color: #333; }
122+
code .hh { color: #06B; }
123+
code .hk { color: #e71818; }
124+
code .hs { color: #008000; }
89125
</style>
90126
</head>
91127

@@ -98,49 +134,39 @@
98134
<tr<?= $info->class ? " class='$info->class'" : '' ?>>
99135
<td class="number"><small><?= $info->coverage ?> %</small></td>
100136
<td><div class="bar"><div style="width: <?= $info->coverage ?>%"></div></div></td>
101-
<td><a href="#fragment<?= $id ?>" onclick="toggle(this); return false"><span><?= $info->name ?></span></a></td>
137+
<td><a href="#F<?= $id ?>" class="toggle"><?= $info->name ?></a></td>
102138
</tr>
103139
</table>
104140

105-
<div class="code" id="fragment<?= $id ?>">
141+
<div class="code" id="F<?= $id ?>">
106142
<?php
107-
$source = explode('<br />', highlight_file($info->file, TRUE));
108-
109-
end($source);
110-
$numWidth = strlen((string) key($source));
111-
112-
unset($prevColor);
113-
$tags = '';
114-
foreach ($source as $n => $line) {
115-
if (isset($info->lines[$n + 1]) && isset($classes[$info->lines[$n + 1]])) {
116-
$color = $classes[$info->lines[$n + 1]];
117-
} else {
118-
$color = ''; // not executable
143+
$code = file_get_contents($info->file);
144+
$lineCount = substr_count($code, "\n") + 1;
145+
$digits = ceil(log10($lineCount));
146+
147+
$prevClass = NULL;
148+
$closeTag = $buffer = '';
149+
for ($i = 1; $i < $lineCount; $i++) {
150+
$class = isset($info->lines[$i]) && isset($classes[$info->lines[$i]])
151+
? $classes[$info->lines[$i]]
152+
: '';
153+
154+
if ($class !== $prevClass) {
155+
echo rtrim($buffer) . $closeTag;
156+
$buffer = '';
157+
$closeTag = '</div>';
158+
echo '<div' . ($class ? " class='$class'" : '') . '>';
119159
}
120-
if (!isset($prevColor)) {
121-
$prevColor = $color;
122-
}
123-
$line = sprintf("<span class='line'>%{$numWidth}s: </span>", $n + 1) . $line;
124-
if ($prevColor !== $color || $n === count($source) - 1) {
125-
echo '<div' . ($prevColor ? " class='$prevColor'" : '') . '>', str_replace(' />', '>', $tags);
126-
$openTags = [];
127-
preg_match_all('#<([^>]+)#', $tags, $matches);
128-
foreach ($matches[1] as $m) {
129-
if ($m[0] === '/') {
130-
array_pop($openTags);
131-
} elseif (substr($m, -1) !== '/') {
132-
$openTags[] = $m;
133-
}
134-
}
135-
foreach (array_reverse($openTags) as $tag) {
136-
echo '</' . preg_replace('# .*#', '', $tag) . '>';
137-
}
138-
echo "</div>\n";
139-
$tags = ($openTags ? '<' . implode('><', $openTags) . '>' : '');
140-
$prevColor = $color;
141-
}
142-
$tags .= "$line<br />\n";
160+
161+
$buffer .= "<a href='#F{$id}L{$i}' id='F{$id}L{$i}'>" . sprintf("%{$digits}s", $i) . "</a>\n";
162+
$prevClass = $class;
143163
}
164+
echo $buffer . $closeTag;
165+
166+
echo strtr(highlight_string($code, TRUE), [
167+
'<code>' => "<code style='left: {$digits}em'>",
168+
'<span style="color: ' => '<span class="',
169+
]);
144170
?></div>
145171
</div>
146172
<?php endforeach ?>
@@ -150,14 +176,20 @@
150176
</footer>
151177

152178
<script>
153-
function toggle(link) {
154-
var el = document.getElementById(link.href.split('#')[1]);
155-
if (el.style.display === 'block') {
156-
el.style.display = 'none';
157-
return false;
158-
} else {
159-
el.style.display = 'block';
179+
document.body.addEventListener('click', function (e) {
180+
if (e.target.className === 'toggle') {
181+
var el = document.getElementById(e.target.href.split('#')[1]);
182+
if (el.style.display === 'block') {
183+
el.style.display = 'none';
184+
} else {
185+
el.style.display = 'block';
186+
}
187+
e.preventDefault();
160188
}
189+
});
190+
191+
if (el = document.getElementById(window.location.hash.replace(/^#|L\d+$/g, ''))) {
192+
el.style.display = 'block';
161193
}
162194
</script>
163195
</body>

0 commit comments

Comments
 (0)