@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.

Support symbol linking in Remarkup code blocks

Summary:
Trigger the crossreference behavior on code blocks. Limited to
Differential, where we know what the project is, but includes regular
comments, inline comments, and previews of both.

(Hopefully event handlers on deleted elements also get deleted, so we
don't leak memory? Also, caching is a problem, and I didn't find a way
to mark existing cache entries as stale, like
`DifferentialChangesetParser::CACHE_VERSION`...)

Test Plan:
Load Differential revision, make lots of comments, click on
things.

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Maniphest Tasks: T1602

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

+118 -66
+22 -22
src/__celerity_resource_map__.php
··· 1306 1306 ), 1307 1307 'javelin-behavior-differential-feedback-preview' => 1308 1308 array( 1309 - 'uri' => '/res/f27f3f49/rsrc/js/application/differential/behavior-comment-preview.js', 1309 + 'uri' => '/res/d6c8a84c/rsrc/js/application/differential/behavior-comment-preview.js', 1310 1310 'type' => 'js', 1311 1311 'requires' => 1312 1312 array( ··· 1860 1860 ), 1861 1861 'javelin-behavior-repository-crossreference' => 1862 1862 array( 1863 - 'uri' => '/res/b24ebee5/rsrc/js/application/repository/repository-crossreference.js', 1863 + 'uri' => '/res/d3ff7611/rsrc/js/application/repository/repository-crossreference.js', 1864 1864 'type' => 'js', 1865 1865 'requires' => 1866 1866 array( ··· 3119 3119 'uri' => '/res/pkg/19ebcc79/differential.pkg.css', 3120 3120 'type' => 'css', 3121 3121 ), 3122 - 29296904 => 3122 + '5b33c790' => 3123 3123 array( 3124 3124 'name' => 'differential.pkg.js', 3125 3125 'symbols' => ··· 3143 3143 16 => 'javelin-behavior-differential-dropdown-menus', 3144 3144 17 => 'javelin-behavior-buoyant', 3145 3145 ), 3146 - 'uri' => '/res/pkg/29296904/differential.pkg.js', 3146 + 'uri' => '/res/pkg/5b33c790/differential.pkg.js', 3147 3147 'type' => 'js', 3148 3148 ), 3149 3149 'c8ce2d88' => ··· 3251 3251 'aphront-typeahead-control-css' => 'edf6b149', 3252 3252 'differential-changeset-view-css' => '19ebcc79', 3253 3253 'differential-core-view-css' => '19ebcc79', 3254 - 'differential-inline-comment-editor' => '29296904', 3254 + 'differential-inline-comment-editor' => '5b33c790', 3255 3255 'differential-local-commits-view-css' => '19ebcc79', 3256 3256 'differential-results-table-css' => '19ebcc79', 3257 3257 'differential-revision-add-comment-css' => '19ebcc79', ··· 3264 3264 'inline-comment-summary-css' => '19ebcc79', 3265 3265 'javelin-behavior' => '6fb20113', 3266 3266 'javelin-behavior-aphront-basic-tokenizer' => '97f65640', 3267 - 'javelin-behavior-aphront-drag-and-drop' => '29296904', 3268 - 'javelin-behavior-aphront-drag-and-drop-textarea' => '29296904', 3267 + 'javelin-behavior-aphront-drag-and-drop' => '5b33c790', 3268 + 'javelin-behavior-aphront-drag-and-drop-textarea' => '5b33c790', 3269 3269 'javelin-behavior-aphront-form-disable-on-submit' => '971b021e', 3270 3270 'javelin-behavior-audit-preview' => '5e68be89', 3271 - 'javelin-behavior-buoyant' => '29296904', 3272 - 'javelin-behavior-differential-accept-with-errors' => '29296904', 3273 - 'javelin-behavior-differential-add-reviewers-and-ccs' => '29296904', 3274 - 'javelin-behavior-differential-comment-jump' => '29296904', 3275 - 'javelin-behavior-differential-diff-radios' => '29296904', 3276 - 'javelin-behavior-differential-dropdown-menus' => '29296904', 3277 - 'javelin-behavior-differential-edit-inline-comments' => '29296904', 3278 - 'javelin-behavior-differential-feedback-preview' => '29296904', 3279 - 'javelin-behavior-differential-keyboard-navigation' => '29296904', 3280 - 'javelin-behavior-differential-populate' => '29296904', 3281 - 'javelin-behavior-differential-show-more' => '29296904', 3271 + 'javelin-behavior-buoyant' => '5b33c790', 3272 + 'javelin-behavior-differential-accept-with-errors' => '5b33c790', 3273 + 'javelin-behavior-differential-add-reviewers-and-ccs' => '5b33c790', 3274 + 'javelin-behavior-differential-comment-jump' => '5b33c790', 3275 + 'javelin-behavior-differential-diff-radios' => '5b33c790', 3276 + 'javelin-behavior-differential-dropdown-menus' => '5b33c790', 3277 + 'javelin-behavior-differential-edit-inline-comments' => '5b33c790', 3278 + 'javelin-behavior-differential-feedback-preview' => '5b33c790', 3279 + 'javelin-behavior-differential-keyboard-navigation' => '5b33c790', 3280 + 'javelin-behavior-differential-populate' => '5b33c790', 3281 + 'javelin-behavior-differential-show-more' => '5b33c790', 3282 3282 'javelin-behavior-diffusion-commit-graph' => '5e68be89', 3283 3283 'javelin-behavior-diffusion-pull-lastmodified' => '5e68be89', 3284 3284 'javelin-behavior-maniphest-batch-selector' => '7707de41', ··· 3288 3288 'javelin-behavior-maniphest-transaction-preview' => '7707de41', 3289 3289 'javelin-behavior-phabricator-autofocus' => '971b021e', 3290 3290 'javelin-behavior-phabricator-keyboard-shortcuts' => '971b021e', 3291 - 'javelin-behavior-phabricator-object-selector' => '29296904', 3291 + 'javelin-behavior-phabricator-object-selector' => '5b33c790', 3292 3292 'javelin-behavior-phabricator-oncopy' => '971b021e', 3293 3293 'javelin-behavior-phabricator-tooltips' => '971b021e', 3294 3294 'javelin-behavior-phabricator-watch-anchor' => '971b021e', 3295 3295 'javelin-behavior-refresh-csrf' => '971b021e', 3296 - 'javelin-behavior-repository-crossreference' => '29296904', 3296 + 'javelin-behavior-repository-crossreference' => '5b33c790', 3297 3297 'javelin-behavior-workflow' => '971b021e', 3298 3298 'javelin-dom' => '6fb20113', 3299 3299 'javelin-event' => '6fb20113', ··· 3319 3319 'phabricator-core-buttons-css' => 'edf6b149', 3320 3320 'phabricator-core-css' => 'edf6b149', 3321 3321 'phabricator-directory-css' => 'edf6b149', 3322 - 'phabricator-drag-and-drop-file-upload' => '29296904', 3322 + 'phabricator-drag-and-drop-file-upload' => '5b33c790', 3323 3323 'phabricator-dropdown-menu' => '971b021e', 3324 3324 'phabricator-flag-css' => 'edf6b149', 3325 3325 'phabricator-jump-nav' => 'edf6b149', ··· 3331 3331 'phabricator-prefab' => '971b021e', 3332 3332 'phabricator-project-tag-css' => '7839ae2d', 3333 3333 'phabricator-remarkup-css' => 'edf6b149', 3334 - 'phabricator-shaped-request' => '29296904', 3334 + 'phabricator-shaped-request' => '5b33c790', 3335 3335 'phabricator-standard-page-view' => 'edf6b149', 3336 3336 'phabricator-tooltip' => '971b021e', 3337 3337 'phabricator-transaction-view-css' => 'edf6b149',
+13 -3
src/applications/differential/controller/DifferentialRevisionViewController.php
··· 256 256 DifferentialChangesetParser::WHITESPACE_IGNORE_ALL); 257 257 258 258 if ($arc_project) { 259 - $symbol_indexes = $this->buildSymbolIndexes( 259 + list($symbol_indexes, $project_phids) = $this->buildSymbolIndexes( 260 260 $arc_project, 261 261 $visible_changesets); 262 262 } else { 263 263 $symbol_indexes = array(); 264 + $project_phids = null; 264 265 } 265 266 266 267 $revision_detail->setActions($actions); ··· 274 275 $comment_view->setUser($user); 275 276 $comment_view->setTargetDiff($target); 276 277 $comment_view->setVersusDiffID($diff_vs); 278 + 279 + if ($arc_project) { 280 + Javelin::initBehavior( 281 + 'repository-crossreference', 282 + array( 283 + 'section' => $comment_view->getID(), 284 + 'projects' => $project_phids, 285 + )); 286 + } 277 287 278 288 $changeset_view = new DifferentialChangesetListView(); 279 289 $changeset_view->setChangesets($changesets); ··· 777 787 778 788 $langs = $arc_project->getSymbolIndexLanguages(); 779 789 if (!$langs) { 780 - return array(); 790 + return array(array(), array()); 781 791 } 782 792 783 793 $symbol_indexes = array(); ··· 797 807 } 798 808 } 799 809 800 - return $symbol_indexes; 810 + return array($symbol_indexes, $project_phids); 801 811 } 802 812 803 813 private function loadOtherRevisions(
+17 -6
src/applications/differential/view/DifferentialRevisionCommentListView.php
··· 25 25 private $user; 26 26 private $target; 27 27 private $versusDiffID; 28 + private $id; 28 29 29 30 public function setComments(array $comments) { 30 31 assert_instances_of($comments, 'DifferentialComment'); ··· 63 64 public function setVersusDiffID($diff_vs) { 64 65 $this->versusDiffID = $diff_vs; 65 66 return $this; 67 + } 68 + 69 + public function getID() { 70 + if (!$this->id) { 71 + $this->id = celerity_generate_unique_node_id(); 72 + } 73 + return $this->id; 66 74 } 67 75 68 76 public function render() { ··· 179 187 $hidden = null; 180 188 } 181 189 182 - return 183 - '<div class="differential-comment-list">'. 184 - implode("\n", $header). 185 - $hidden. 186 - implode("\n", $visible). 187 - '</div>'; 190 + return javelin_render_tag( 191 + 'div', 192 + array( 193 + 'class' => 'differential-comment-list', 194 + 'id' => $this->getID(), 195 + ), 196 + implode("\n", $header). 197 + $hidden. 198 + implode("\n", $visible)); 188 199 } 189 200 }
+8 -1
webroot/rsrc/js/application/differential/behavior-comment-preview.js
··· 19 19 } 20 20 21 21 var callback = function(r) { 22 - JX.DOM.setContent(JX.$(config.preview), JX.$H(r)); 22 + var preview = JX.$(config.preview); 23 + JX.DOM.setContent(preview, JX.$H(r)); 24 + JX.Stratcom.invoke('differential-preview-update', null, { 25 + container: preview 26 + }); 23 27 }; 24 28 25 29 var getdata = function() { ··· 50 54 var inline = JX.$(config.inline); 51 55 52 56 JX.DOM.setContent(inline, JX.$H(r)); 57 + JX.Stratcom.invoke('differential-preview-update', null, { 58 + container: inline 59 + }); 53 60 54 61 // Go through the previews and activate any "View" links where the 55 62 // actual comment appears in the document.
+58 -34
webroot/rsrc/js/application/repository/repository-crossreference.js
··· 10 10 // NOTE: Pretty much everything in this file is a worst practice. We're 11 11 // constrained by the markup generated by the syntax highlighters. 12 12 13 - var container = JX.$(config.container); 14 - JX.DOM.alterClass(container, 'repository-crossreference', true); 15 - JX.DOM.listen( 16 - container, 17 - 'click', 18 - 'tag:span', 19 - function(e) { 20 - if (window.getSelection && !window.getSelection().isCollapsed) { 21 - return; 22 - } 23 - var target = e.getTarget(); 24 - var map = {nc : 'class', nf : 'function', na : null}; 25 - while (target !== document.body) { 26 - if (JX.DOM.isNode(target, 'span') && (target.className in map)) { 27 - var symbol = target.textContent || target.innerText; 28 - var query = { 29 - lang : config.lang, 30 - projects : config.projects.join(','), 31 - jump : true 32 - }; 33 - if (map[target.className]) { 34 - query.type = map[target.className]; 35 - } 36 - if (target.hasAttribute('data-symbol-context')) { 37 - query.context = target.getAttribute('data-symbol-context'); 38 - } 39 - if (target.hasAttribute('data-symbol-name')) { 40 - symbol = target.getAttribute('data-symbol-name'); 13 + function link(element, lang) { 14 + JX.DOM.alterClass(element, 'repository-crossreference', true); 15 + JX.DOM.listen( 16 + element, 17 + 'click', 18 + 'tag:span', 19 + function(e) { 20 + if (window.getSelection && !window.getSelection().isCollapsed) { 21 + return; 22 + } 23 + var target = e.getTarget(); 24 + var map = {nc : 'class', nf : 'function', na : null}; 25 + while (target !== document.body) { 26 + if (JX.DOM.isNode(target, 'span') && (target.className in map)) { 27 + var symbol = target.textContent || target.innerText; 28 + var query = { 29 + lang : lang, 30 + projects : config.projects.join(','), 31 + jump : true 32 + }; 33 + if (map[target.className]) { 34 + query.type = map[target.className]; 35 + } 36 + if (target.hasAttribute('data-symbol-context')) { 37 + query.context = target.getAttribute('data-symbol-context'); 38 + } 39 + if (target.hasAttribute('data-symbol-name')) { 40 + symbol = target.getAttribute('data-symbol-name'); 41 + } 42 + var uri = JX.$U('/diffusion/symbol/' + symbol + '/'); 43 + uri.addQueryParams(query); 44 + window.open(uri); 45 + e.kill(); 46 + break; 41 47 } 42 - var uri = JX.$U('/diffusion/symbol/' + symbol + '/'); 43 - uri.addQueryParams(query); 44 - window.open(uri); 45 - e.kill(); 46 - break; 48 + target = target.parentNode; 47 49 } 48 - target = target.parentNode; 50 + }); 51 + } 52 + 53 + function linkAll(section) { 54 + var blocks = section.getElementsByClassName('remarkup-code-block'); 55 + for (var i = 0; i < blocks.length; ++i) { 56 + if (blocks[i].hasAttribute('data-code-lang')) { 57 + var lang = blocks[i].getAttribute('data-code-lang'); 58 + link(blocks[i], lang); 49 59 } 60 + } 61 + } 62 + 63 + if (config.container) { 64 + link(JX.$(config.container), config.lang); 65 + } else if (config.section) { 66 + linkAll(JX.$(config.section)); 67 + } 68 + 69 + JX.Stratcom.listen( 70 + 'differential-preview-update', 71 + null, 72 + function(e) { 73 + linkAll(e.getData().container); 50 74 }); 51 75 52 76 });