[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class DifferentialDiffTableOfContentsView extends AphrontView { 4 5 private $changesets = array(); 6 private $visibleChangesets = array(); 7 private $references = array(); 8 private $repository; 9 private $diff; 10 private $renderURI = '/differential/changeset/'; 11 private $revisionID; 12 private $whitespace; 13 private $unitTestData; 14 15 public function setChangesets($changesets) { 16 $this->changesets = $changesets; 17 return $this; 18 } 19 20 public function setVisibleChangesets($visible_changesets) { 21 $this->visibleChangesets = $visible_changesets; 22 return $this; 23 } 24 25 public function setRenderingReferences(array $references) { 26 $this->references = $references; 27 return $this; 28 } 29 30 public function setRepository(PhabricatorRepository $repository) { 31 $this->repository = $repository; 32 return $this; 33 } 34 35 public function setDiff(DifferentialDiff $diff) { 36 $this->diff = $diff; 37 return $this; 38 } 39 40 public function setUnitTestData($unit_test_data) { 41 $this->unitTestData = $unit_test_data; 42 return $this; 43 } 44 45 public function setRevisionID($revision_id) { 46 $this->revisionID = $revision_id; 47 return $this; 48 } 49 50 public function setWhitespace($whitespace) { 51 $this->whitespace = $whitespace; 52 return $this; 53 } 54 55 public function render() { 56 57 $this->requireResource('differential-core-view-css'); 58 $this->requireResource('differential-table-of-contents-css'); 59 60 $rows = array(); 61 62 $coverage = array(); 63 if ($this->unitTestData) { 64 $coverage_by_file = array(); 65 foreach ($this->unitTestData as $result) { 66 $test_coverage = idx($result, 'coverage'); 67 if (!$test_coverage) { 68 continue; 69 } 70 foreach ($test_coverage as $file => $results) { 71 $coverage_by_file[$file][] = $results; 72 } 73 } 74 foreach ($coverage_by_file as $file => $coverages) { 75 $coverage[$file] = ArcanistUnitTestResult::mergeCoverage($coverages); 76 } 77 } 78 79 $changesets = $this->changesets; 80 $paths = array(); 81 foreach ($changesets as $id => $changeset) { 82 $type = $changeset->getChangeType(); 83 $ftype = $changeset->getFileType(); 84 $ref = idx($this->references, $id); 85 $display_file = $changeset->getDisplayFilename(); 86 87 $meta = null; 88 if (DifferentialChangeType::isOldLocationChangeType($type)) { 89 $away = $changeset->getAwayPaths(); 90 if (count($away) > 1) { 91 $meta = array(); 92 if ($type == DifferentialChangeType::TYPE_MULTICOPY) { 93 $meta[] = pht('Deleted after being copied to multiple locations:'); 94 } else { 95 $meta[] = pht('Copied to multiple locations:'); 96 } 97 foreach ($away as $path) { 98 $meta[] = $path; 99 } 100 $meta = phutil_implode_html(phutil_tag('br'), $meta); 101 } else { 102 if ($type == DifferentialChangeType::TYPE_MOVE_AWAY) { 103 $display_file = $this->renderRename( 104 $display_file, 105 reset($away), 106 "\xE2\x86\x92"); 107 } else { 108 $meta = pht('Copied to %s', reset($away)); 109 } 110 } 111 } else if ($type == DifferentialChangeType::TYPE_MOVE_HERE) { 112 $old_file = $changeset->getOldFile(); 113 $display_file = $this->renderRename( 114 $display_file, 115 $old_file, 116 "\xE2\x86\x90"); 117 } else if ($type == DifferentialChangeType::TYPE_COPY_HERE) { 118 $meta = pht('Copied from %s', $changeset->getOldFile()); 119 } 120 121 $link = $this->renderChangesetLink($changeset, $ref, $display_file); 122 123 $line_count = $changeset->getAffectedLineCount(); 124 if ($line_count == 0) { 125 $lines = ''; 126 } else { 127 $lines = ' '.pht('(%d line(s))', $line_count); 128 } 129 130 $char = DifferentialChangeType::getSummaryCharacterForChangeType($type); 131 $chartitle = DifferentialChangeType::getFullNameForChangeType($type); 132 $desc = DifferentialChangeType::getShortNameForFileType($ftype); 133 if ($desc) { 134 $desc = '('.$desc.')'; 135 } 136 $pchar = 137 ($changeset->getOldProperties() === $changeset->getNewProperties()) 138 ? '' 139 : phutil_tag( 140 'span', 141 array('title' => pht('Properties Changed')), 142 'M'); 143 144 $fname = $changeset->getFilename(); 145 $cov = $this->renderCoverage($coverage, $fname); 146 if ($cov === null) { 147 $mcov = $cov = phutil_tag('em', array(), '-'); 148 } else { 149 $mcov = phutil_tag( 150 'div', 151 array( 152 'id' => 'differential-mcoverage-'.md5($fname), 153 'class' => 'differential-mcoverage-loading', 154 ), 155 (isset($this->visibleChangesets[$id]) ? 156 pht('Loading...') : pht('?'))); 157 } 158 159 if ($meta) { 160 $meta = phutil_tag( 161 'div', 162 array( 163 'class' => 'differential-toc-meta', 164 ), 165 $meta); 166 } 167 168 if ($this->diff && $this->repository) { 169 $paths[] = 170 $changeset->getAbsoluteRepositoryPath($this->repository, $this->diff); 171 } 172 173 $rows[] = array( 174 $char, 175 $pchar, 176 $desc, 177 array($link, $lines, $meta), 178 $cov, 179 $mcov, 180 ); 181 } 182 183 $editor_link = null; 184 if ($paths && $this->user) { 185 $editor_link = $this->user->loadEditorLink( 186 $paths, 187 1, // line number 188 $this->repository->getCallsign()); 189 if ($editor_link) { 190 $editor_link = 191 phutil_tag( 192 'a', 193 array( 194 'href' => $editor_link, 195 'class' => 'button differential-toc-edit-all', 196 ), 197 pht('Open All in Editor')); 198 } 199 } 200 201 $reveal_link = javelin_tag( 202 'a', 203 array( 204 'sigil' => 'differential-reveal-all', 205 'mustcapture' => true, 206 'class' => 'button differential-toc-reveal-all', 207 ), 208 pht('Show All Context')); 209 210 $buttons = phutil_tag( 211 'div', 212 array( 213 'class' => 'differential-toc-buttons grouped', 214 ), 215 array( 216 $editor_link, 217 $reveal_link, 218 )); 219 220 $table = id(new AphrontTableView($rows)); 221 $table->setHeaders( 222 array( 223 '', 224 '', 225 '', 226 pht('Path'), 227 pht('Coverage (All)'), 228 pht('Coverage (Touched)'), 229 )); 230 $table->setColumnClasses( 231 array( 232 'differential-toc-char center', 233 'differential-toc-prop center', 234 'differential-toc-ftype center', 235 'differential-toc-file wide', 236 'differential-toc-cov', 237 'differential-toc-cov', 238 )); 239 $table->setDeviceVisibility( 240 array( 241 true, 242 true, 243 true, 244 true, 245 false, 246 false, 247 )); 248 $anchor = id(new PhabricatorAnchorView()) 249 ->setAnchorName('toc') 250 ->setNavigationMarker(true); 251 252 return id(new PHUIObjectBoxView()) 253 ->setHeaderText(pht('Table of Contents')) 254 ->appendChild($anchor) 255 ->appendChild($table) 256 ->appendChild($buttons); 257 } 258 259 private function renderRename($display_file, $other_file, $arrow) { 260 $old = explode('/', $display_file); 261 $new = explode('/', $other_file); 262 263 $start = count($old); 264 foreach ($old as $index => $part) { 265 if (!isset($new[$index]) || $part != $new[$index]) { 266 $start = $index; 267 break; 268 } 269 } 270 271 $end = count($old); 272 foreach (array_reverse($old) as $from_end => $part) { 273 $index = count($new) - $from_end - 1; 274 if (!isset($new[$index]) || $part != $new[$index]) { 275 $end = $from_end; 276 break; 277 } 278 } 279 280 $rename = 281 '{'. 282 implode('/', array_slice($old, $start, count($old) - $end - $start)). 283 ' '.$arrow.' '. 284 implode('/', array_slice($new, $start, count($new) - $end - $start)). 285 '}'; 286 287 array_splice($new, $start, count($new) - $end - $start, $rename); 288 return implode('/', $new); 289 } 290 291 private function renderCoverage(array $coverage, $file) { 292 $info = idx($coverage, $file); 293 if (!$info) { 294 return null; 295 } 296 297 $not_covered = substr_count($info, 'U'); 298 $covered = substr_count($info, 'C'); 299 300 if (!$not_covered && !$covered) { 301 return null; 302 } 303 304 return sprintf('%d%%', 100 * ($covered / ($covered + $not_covered))); 305 } 306 307 308 private function renderChangesetLink( 309 DifferentialChangeset $changeset, 310 $ref, 311 $display_file) { 312 313 return javelin_tag( 314 'a', 315 array( 316 'href' => '#'.$changeset->getAnchorName(), 317 'sigil' => 'differential-load', 318 'meta' => array( 319 'id' => 'diff-'.$changeset->getAnchorName(), 320 ), 321 ), 322 $display_file); 323 } 324 325 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |