@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Line highlighting for pastes

Summary:
Add the ability to select singular and multiple lines in paste to highlight.
This is related to T3627

Test Plan: Create a paste, select one or more lines.

Reviewers: epriestley, tberman

Reviewed By: epriestley

CC: aran, chad

Maniphest Tasks: T3627

Differential Revision: https://secure.phabricator.com/D6668

authored by

Korvin Szanto and committed by
epriestley
40cf765c a5f790e1

+98 -48
+16 -16
src/__celerity_resource_map__.php
··· 1140 1140 ), 1141 1141 'diffusion-source-css' => 1142 1142 array( 1143 - 'uri' => '/res/e76bcd50/rsrc/css/application/diffusion/diffusion-source.css', 1143 + 'uri' => '/res/162c8794/rsrc/css/application/diffusion/diffusion-source.css', 1144 1144 'type' => 'css', 1145 1145 'requires' => 1146 1146 array( ··· 1666 1666 2 => 'javelin-dom', 1667 1667 ), 1668 1668 'disk' => '/rsrc/js/application/diffusion/behavior-jump-to.js', 1669 - ), 1670 - 'javelin-behavior-diffusion-line-linker' => 1671 - array( 1672 - 'uri' => '/res/12866f13/rsrc/js/application/diffusion/behavior-line-linker.js', 1673 - 'type' => 'js', 1674 - 'requires' => 1675 - array( 1676 - 0 => 'javelin-behavior', 1677 - 1 => 'javelin-stratcom', 1678 - 2 => 'javelin-dom', 1679 - 3 => 'javelin-history', 1680 - ), 1681 - 'disk' => '/rsrc/js/application/diffusion/behavior-line-linker.js', 1682 1669 ), 1683 1670 'javelin-behavior-diffusion-pull-lastmodified' => 1684 1671 array( ··· 2067 2054 ), 2068 2055 'disk' => '/rsrc/js/core/behavior-keyboard-shortcuts.js', 2069 2056 ), 2057 + 'javelin-behavior-phabricator-line-linker' => 2058 + array( 2059 + 'uri' => '/res/1cefdb6a/rsrc/js/core/behavior-line-linker.js', 2060 + 'type' => 'js', 2061 + 'requires' => 2062 + array( 2063 + 0 => 'javelin-behavior', 2064 + 1 => 'javelin-stratcom', 2065 + 2 => 'javelin-dom', 2066 + 3 => 'javelin-history', 2067 + ), 2068 + 'disk' => '/rsrc/js/core/behavior-line-linker.js', 2069 + ), 2070 2070 'javelin-behavior-phabricator-nav' => 2071 2071 array( 2072 2072 'uri' => '/res/afabcf16/rsrc/js/core/behavior-phabricator-nav.js', ··· 2249 2249 ), 2250 2250 'javelin-behavior-pholio-mock-view' => 2251 2251 array( 2252 - 'uri' => '/res/3ff82e28/rsrc/js/application/pholio/behavior-pholio-mock-view.js', 2252 + 'uri' => '/res/f9588dcf/rsrc/js/application/pholio/behavior-pholio-mock-view.js', 2253 2253 'type' => 'js', 2254 2254 'requires' => 2255 2255 array( ··· 3498 3498 ), 3499 3499 'phabricator-source-code-view-css' => 3500 3500 array( 3501 - 'uri' => '/res/979d5280/rsrc/css/layout/phabricator-source-code-view.css', 3501 + 'uri' => '/res/70bcbea4/rsrc/css/layout/phabricator-source-code-view.css', 3502 3502 'type' => 'css', 3503 3503 'requires' => 3504 3504 array(
+6 -4
src/applications/diffusion/controller/DiffusionBrowseFileController.php
··· 241 241 'table', 242 242 array( 243 243 'class' => "diffusion-source remarkup-code PhabricatorMonospaced", 244 - 'sigil' => 'diffusion-source', 244 + 'sigil' => 'phabricator-source', 245 245 ), 246 246 $rows); 247 247 ··· 728 728 'th', 729 729 array( 730 730 'class' => 'diffusion-line-link', 731 - 'sigil' => 'diffusion-line-link', 731 + 'sigil' => 'phabricator-source-line', 732 732 'style' => $style, 733 733 ), 734 734 $line_link); 735 735 736 - Javelin::initBehavior('diffusion-line-linker'); 736 + Javelin::initBehavior('phabricator-line-linker'); 737 737 738 738 if ($line['target']) { 739 739 Javelin::initBehavior( ··· 768 768 $rows[] = phutil_tag( 769 769 'tr', 770 770 array( 771 - 'class' => ($line['highlighted'] ? 'highlighted' : null), 771 + 'class' => ($line['highlighted'] ? 772 + 'phabricator-source-highlight' : 773 + null), 772 774 ), 773 775 $blame); 774 776
+3 -2
src/applications/paste/application/PhabricatorApplicationPaste.php
··· 33 33 34 34 public function getRoutes() { 35 35 return array( 36 - '/P(?P<id>[1-9]\d*)' => 'PhabricatorPasteViewController', 36 + '/P(?P<id>[1-9]\d*)(?:\$(?P<lines>\d+(?:-\d+)?))?' 37 + => 'PhabricatorPasteViewController', 37 38 '/paste/' => array( 38 39 '(query/(?P<queryKey>[^/]+)/)?' => 'PhabricatorPasteListController', 39 40 'create/' => 'PhabricatorPasteEditController', 40 41 'edit/(?P<id>[1-9]\d*)/' => 'PhabricatorPasteEditController', 41 - 'comment/(?P<id>[1-9]\d*)/' => 'PhabricatorPasteCommentController', 42 + 'comment/(?P<id>[1-9]\d*)/' => 'PhabricatorPasteCommentController', 42 43 ), 43 44 ); 44 45 }
+5 -2
src/applications/paste/controller/PhabricatorPasteController.php
··· 42 42 43 43 public function buildSourceCodeView( 44 44 PhabricatorPaste $paste, 45 - $max_lines = null) { 45 + $max_lines = null, 46 + $highlights = array()) { 46 47 47 48 $lines = phutil_split_lines($paste->getContent()); 48 49 49 50 return id(new PhabricatorSourceCodeView()) 50 51 ->setLimit($max_lines) 51 - ->setLines($lines); 52 + ->setLines($lines) 53 + ->setHighlights($highlights) 54 + ->setURI(new PhutilURI($paste->getURI())); 52 55 } 53 56 54 57 }
+20 -1
src/applications/paste/controller/PhabricatorPasteViewController.php
··· 6 6 final class PhabricatorPasteViewController extends PhabricatorPasteController { 7 7 8 8 private $id; 9 + private $highlightMap; 9 10 10 11 public function shouldAllowPublic() { 11 12 return true; ··· 13 14 14 15 public function willProcessRequest(array $data) { 15 16 $this->id = $data['id']; 17 + $raw_lines = idx($data, 'lines'); 18 + $map = array(); 19 + if ($raw_lines) { 20 + $lines = explode('-', $raw_lines); 21 + $first = idx($lines, 0, 0); 22 + $last = idx($lines, 1); 23 + if ($last) { 24 + $min = min($first, $last); 25 + $max = max($first, $last); 26 + $map = array_fuse(range($min, $max)); 27 + } else { 28 + $map[$first] = $first; 29 + } 30 + } 31 + $this->highlightMap = $map; 16 32 } 17 33 18 34 public function processRequest() { ··· 52 68 $header = $this->buildHeaderView($paste); 53 69 $actions = $this->buildActionView($user, $paste, $file); 54 70 $properties = $this->buildPropertyView($paste, $fork_phids); 55 - $source_code = $this->buildSourceCodeView($paste); 71 + $source_code = $this->buildSourceCodeView( 72 + $paste, 73 + null, 74 + $this->highlightMap); 56 75 57 76 $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView()) 58 77 ->setActionList($actions)
+35 -9
src/view/layout/PhabricatorSourceCodeView.php
··· 4 4 5 5 private $lines; 6 6 private $limit; 7 + private $uri; 7 8 private $highlights = array(); 8 9 9 10 public function setLimit($limit) { ··· 16 17 return $this; 17 18 } 18 19 19 - public function setHighlights(array $highlights) { 20 - $this->highlights = array_fuse($highlights); 20 + public function setURI(PhutilURI $uri) { 21 + $this->uri = $uri; 22 + return $this; 23 + } 24 + 25 + public function setHighlights(array $array) { 26 + $this->highlights = array_fuse($array); 21 27 return $this; 22 28 } 23 29 ··· 26 32 require_celerity_resource('syntax-highlighting-css'); 27 33 28 34 Javelin::initBehavior('phabricator-oncopy', array()); 35 + Javelin::initBehavior('phabricator-line-linker'); 29 36 30 37 $line_number = 1; 31 38 32 39 $rows = array(); 40 + 33 41 foreach ($this->lines as $line) { 34 42 $hit_limit = $this->limit && 35 43 ($line_number == $this->limit) && ··· 53 61 $row_attributes['class'] = 'phabricator-source-highlight'; 54 62 } 55 63 56 - // TODO: Provide nice links. 64 + $line_uri = $this->uri . "$" . $line_number; 65 + $line_href = (string) new PhutilURI($line_uri); 66 + 67 + $tag_number = javelin_tag( 68 + 'a', 69 + array( 70 + 'href' => $line_href 71 + ), 72 + $line_number); 57 73 58 74 $rows[] = phutil_tag( 59 75 'tr', 60 76 $row_attributes, 61 - hsprintf( 62 - '<th class="phabricator-source-line">%s</th>'. 63 - '<td class="phabricator-source-code">%s</td>', 64 - $content_number, 65 - $content_line)); 77 + array( 78 + javelin_tag( 79 + 'th', 80 + array( 81 + 'class' => 'phabricator-source-line', 82 + 'sigil' => 'phabricator-source-line' 83 + ), 84 + $tag_number), 85 + phutil_tag( 86 + 'td', 87 + array( 88 + 'class' => 'phabricator-source-code' 89 + ), 90 + $content_line))); 66 91 67 92 if ($hit_limit) { 68 93 break; ··· 81 106 array( 82 107 'class' => 'phabricator-source-code-container', 83 108 ), 84 - phutil_tag( 109 + javelin_tag( 85 110 'table', 86 111 array( 87 112 'class' => implode(' ', $classes), 113 + 'sigil' => 'phabricator-source' 88 114 ), 89 115 phutil_implode_html('', $rows))); 90 116 }
+1 -1
webroot/rsrc/css/application/diffusion/diffusion-source.css
··· 9 9 font-size: 10px; 10 10 } 11 11 12 - .diffusion-source tr.highlighted { 12 + .diffusion-source tr.phabricator-source-highlight { 13 13 background: #ffff00; 14 14 } 15 15
+1
webroot/rsrc/css/layout/phabricator-source-code-view.css
··· 10 10 .phabricator-source-code { 11 11 white-space: pre-wrap; 12 12 padding: 2px 8px 1px; 13 + width: 100%; 13 14 } 14 15 15 16 .phabricator-source-line {
+11 -13
webroot/rsrc/js/application/diffusion/behavior-line-linker.js webroot/rsrc/js/core/behavior-line-linker.js
··· 1 1 /** 2 - * @provides javelin-behavior-diffusion-line-linker 2 + * @provides javelin-behavior-phabricator-line-linker 3 3 * @requires javelin-behavior 4 4 * javelin-stratcom 5 5 * javelin-dom 6 6 * javelin-history 7 7 */ 8 8 9 - JX.behavior('diffusion-line-linker', function() { 10 - 9 + JX.behavior('phabricator-line-linker', function() { 11 10 var origin = null; 12 11 var target = null; 13 12 var root = null; 14 13 15 14 function getRowNumber(tr) { 16 - var th = JX.DOM.find(tr, 'th', 'diffusion-line-link'); 15 + var th = JX.DOM.find(tr, 'th', 'phabricator-source-line'); 17 16 return +(th.textContent || th.innerText); 18 17 } 19 18 20 19 JX.Stratcom.listen( 21 20 'mousedown', 22 - 'diffusion-line-link', 21 + 'phabricator-source-line', 23 22 function(e) { 24 - if (e.isRightButton()) { 23 + if (!e.isNormalMouseEvent()) { 25 24 return; 26 25 } 27 26 origin = e.getNode('tag:tr'); 28 27 target = origin; 29 - root = e.getNode('diffusion-source'); 28 + root = e.getNode('phabricator-source'); 30 29 e.kill(); 31 30 }); 32 31 33 32 JX.Stratcom.listen( 34 33 'click', 35 - 'diffusion-line-link', 34 + 'phabricator-source-line', 36 35 function(e) { 37 36 e.kill(); 38 37 }); 39 38 40 39 var highlight = function(e) { 41 - if (!origin || e.getNode('diffusion-source') !== root) { 40 + if (!origin || e.getNode('phabricator-source') !== root) { 42 41 return; 43 42 } 44 43 target = e.getNode('tag:tr'); ··· 51 50 highlighting = true; 52 51 source = trs[i]; 53 52 } 54 - JX.DOM.alterClass(trs[i], 'highlighted', highlighting); 53 + JX.DOM.alterClass(trs[i], 'phabricator-source-highlight', highlighting); 55 54 if (trs[i] === (source === origin ? target : origin)) { 56 55 highlighting = false; 57 56 } 58 57 } 59 58 }; 60 59 61 - JX.Stratcom.listen('mouseover', 'diffusion-source', highlight); 60 + JX.Stratcom.listen('mouseover', 'phabricator-source', highlight); 62 61 63 62 JX.Stratcom.listen( 64 63 'mouseup', ··· 73 72 var o = getRowNumber(origin); 74 73 var t = getRowNumber(target); 75 74 var lines = (o == t ? o : Math.min(o, t) + '-' + Math.max(o, t)); 76 - var th = JX.DOM.find(origin, 'th', 'diffusion-line-link'); 75 + var th = JX.DOM.find(origin, 'th', 'phabricator-source-line'); 77 76 var uri = JX.DOM.find(th, 'a').href; 78 77 uri = uri.replace(/(.*\$)\d+/, '$1' + lines); 79 - 80 78 origin = null; 81 79 target = null; 82 80 e.kill();