|
9 | 9 |
|
10 | 10 | <style type="text/css">
|
11 | 11 | 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; |
14 | 14 | }
|
15 | 15 |
|
16 | 16 | body {
|
17 | 17 | max-width: 990px;
|
18 | 18 | margin: -4.7em auto 0;
|
19 |
| - background: white; |
| 19 | + background: #fcfaf5; |
20 | 20 | color: #333;
|
21 | 21 | }
|
22 | 22 |
|
| 23 | + footer { |
| 24 | + margin-left: .5em; |
| 25 | + } |
| 26 | + |
23 | 27 | h1 {
|
| 28 | + font-family: "Trebuchet MS","Geneva CE",lucida,sans-serif; |
24 | 29 | font-size: 1.9em;
|
25 |
| - margin: .5em 0 1.5em; |
26 |
| - color: #7A7772; |
| 30 | + margin: .5em .5em 1.5em; |
| 31 | + color: #7a7772; |
27 | 32 | text-shadow: 1px 1px 0 white;
|
28 | 33 | }
|
29 | 34 |
|
30 | 35 | div.code {
|
31 |
| - font: 14px/1.2 Consolas, monospace; |
32 |
| - background: #FDF5CE; |
33 |
| - padding: .4em .7em; |
| 36 | + background: white; |
34 | 37 | border: 1px dotted silver;
|
35 |
| - overflow-x: auto; |
36 | 38 | 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; |
37 | 52 | }
|
38 | 53 |
|
39 |
| - span.line { |
40 |
| - color: #9F9C7F; |
41 |
| - font-weight: normal; |
42 |
| - font-style: normal; |
| 54 | + div.code a { |
| 55 | + color: #c0c0c0; |
43 | 56 | }
|
44 | 57 |
|
45 |
| - .t { |
46 |
| - background: #99f999; |
| 58 | + div.code a:hover { |
| 59 | + color: inherit; |
| 60 | + font-weight: bold; |
| 61 | + text-decoration: none; |
47 | 62 | }
|
48 | 63 |
|
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; |
51 | 78 | }
|
52 | 79 |
|
53 | 80 | td {
|
|
64 | 91 | }
|
65 | 92 |
|
66 | 93 | .bar {
|
67 |
| - border: 1px solid #ACACAC; |
| 94 | + border: 1px solid #acacac; |
68 | 95 | background: #e50400;
|
69 | 96 | width: 35px;
|
70 | 97 | height: 1em;
|
71 | 98 | }
|
72 | 99 |
|
73 | 100 | .bar div {
|
74 |
| - background: #1A7E1E; |
| 101 | + background: #1a7e1e; |
75 | 102 | height: 1em;
|
76 | 103 | }
|
77 | 104 |
|
|
86 | 113 | .not-loaded td * {
|
87 | 114 | color: red;
|
88 | 115 | }
|
| 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; } |
89 | 125 | </style>
|
90 | 126 | </head>
|
91 | 127 |
|
|
98 | 134 | <tr<?= $info->class ? " class='$info->class'" : '' ?>>
|
99 | 135 | <td class="number"><small><?= $info->coverage ?> %</small></td>
|
100 | 136 | <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> |
102 | 138 | </tr>
|
103 | 139 | </table>
|
104 | 140 |
|
105 |
| - <div class="code" id="fragment<?= $id ?>"> |
| 141 | + <div class="code" id="F<?= $id ?>"> |
106 | 142 | <?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'" : '') . '>'; |
119 | 159 | }
|
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; |
143 | 163 | }
|
| 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 | + ]); |
144 | 170 | ?></div>
|
145 | 171 | </div>
|
146 | 172 | <?php endforeach ?>
|
|
150 | 176 | </footer>
|
151 | 177 |
|
152 | 178 | <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(); |
160 | 188 | }
|
| 189 | + }); |
| 190 | + |
| 191 | + if (el = document.getElementById(window.location.hash.replace(/^#|L\d+$/g, ''))) { |
| 192 | + el.style.display = 'block'; |
161 | 193 | }
|
162 | 194 | </script>
|
163 | 195 | </body>
|
|
0 commit comments