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

Search symbols by ctrl/cmd-click

Summary:
Refs T8302.
V1 of the implementation. This replaces the previous mode, but I guess there's no real reason we can't have
some symbols always clickable and the rest require modifier.

I'm also a little concerned about discoverability; Holding down ctrl/cmd will make the cursor change, so there's
some hint that something might be up, but that's probably not obvious enough.

Test Plan:
Tested in diffusion and differential and differential comments on:
- Windows/Chrome,
- Windows/IE 11
- LInux/Firefox 38
- Mac/Chrome
- Mac/Safari

Reviewers: chad, epriestley, #blessed_reviewers

Reviewed By: epriestley, #blessed_reviewers

Subscribers: Korvin, epriestley, joshuaspence

Maniphest Tasks: T8302

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

authored by

Aviv Eyal and committed by
epriestley
1aa8bc31 c7de1766

+113 -62
+22 -22
resources/celerity/map.php
··· 7 7 */ 8 8 return array( 9 9 'names' => array( 10 - 'core.pkg.css' => '97a49e3e', 11 - 'core.pkg.js' => 'a5ed8c89', 10 + 'core.pkg.css' => '68d4f4fb', 11 + 'core.pkg.js' => '3bbe23c6', 12 12 'darkconsole.pkg.js' => 'e7393ebb', 13 13 'differential.pkg.css' => '30602b8c', 14 - 'differential.pkg.js' => '8c98ce21', 14 + 'differential.pkg.js' => 'ebef29b1', 15 15 'diffusion.pkg.css' => '591664fa', 16 16 'diffusion.pkg.js' => '0115b37c', 17 17 'maniphest.pkg.css' => '68d4dd3d', ··· 111 111 'rsrc/css/application/uiexample/example.css' => '528b19de', 112 112 'rsrc/css/core/core.css' => 'aaea7a7a', 113 113 'rsrc/css/core/remarkup.css' => '07b7dc54', 114 - 'rsrc/css/core/syntax.css' => '6b7b24d9', 114 + 'rsrc/css/core/syntax.css' => '9fd11da8', 115 115 'rsrc/css/core/z-index.css' => 'c4732d32', 116 116 'rsrc/css/diviner/diviner-shared.css' => '38813222', 117 117 'rsrc/css/font/font-awesome.css' => 'e2e712fe', ··· 202 202 'rsrc/externals/javelin/ext/view/__tests__/ViewInterpreter.js' => '7a94d6a5', 203 203 'rsrc/externals/javelin/ext/view/__tests__/ViewRenderer.js' => '6ea96ac9', 204 204 'rsrc/externals/javelin/lib/Cookie.js' => '62dfea03', 205 - 'rsrc/externals/javelin/lib/DOM.js' => '6f7962d5', 205 + 'rsrc/externals/javelin/lib/DOM.js' => '147805fa', 206 206 'rsrc/externals/javelin/lib/History.js' => 'd4505101', 207 207 'rsrc/externals/javelin/lib/JSON.js' => '69adf288', 208 208 'rsrc/externals/javelin/lib/Leader.js' => '331b1611', ··· 399 399 'rsrc/js/application/releeph/releeph-preview-branch.js' => 'b2b4fbaf', 400 400 'rsrc/js/application/releeph/releeph-request-state-change.js' => 'a0b57eb8', 401 401 'rsrc/js/application/releeph/releeph-request-typeahead.js' => 'de2e896f', 402 - 'rsrc/js/application/repository/repository-crossreference.js' => '3975b470', 402 + 'rsrc/js/application/repository/repository-crossreference.js' => 'bea81850', 403 403 'rsrc/js/application/search/behavior-reorder-queries.js' => 'e9581f08', 404 404 'rsrc/js/application/slowvote/behavior-slowvote-embed.js' => '887ad43f', 405 405 'rsrc/js/application/transactions/behavior-show-older-transactions.js' => 'dbbf48b6', ··· 636 636 'javelin-behavior-remarkup-preview' => 'f7379f45', 637 637 'javelin-behavior-reorder-applications' => '76b9fc3e', 638 638 'javelin-behavior-reorder-columns' => 'e1d25dfb', 639 - 'javelin-behavior-repository-crossreference' => '3975b470', 639 + 'javelin-behavior-repository-crossreference' => 'bea81850', 640 640 'javelin-behavior-scrollbar' => '834a1173', 641 641 'javelin-behavior-search-reorder-queries' => 'e9581f08', 642 642 'javelin-behavior-select-on-click' => '4e3e79a6', ··· 652 652 'javelin-color' => '7e41274a', 653 653 'javelin-cookie' => '62dfea03', 654 654 'javelin-diffusion-locate-file-source' => 'b42eddc7', 655 - 'javelin-dom' => '6f7962d5', 655 + 'javelin-dom' => '147805fa', 656 656 'javelin-dynval' => 'f6555212', 657 657 'javelin-event' => '85ea0626', 658 658 'javelin-fx' => '54b612ba', ··· 821 821 'sprite-menu-css' => '9ef76324', 822 822 'sprite-projects-css' => 'b0d9e24f', 823 823 'sprite-tokens-css' => '1706b943', 824 - 'syntax-highlighting-css' => '6b7b24d9', 824 + 'syntax-highlighting-css' => '9fd11da8', 825 825 'tokens-css' => '3d0f239e', 826 826 'typeahead-browse-css' => 'd8581d2c', 827 827 'unhandled-exception-css' => '37d4f9a2', ··· 918 918 'javelin-uri', 919 919 'phabricator-textareautils', 920 920 ), 921 + '147805fa' => array( 922 + 'javelin-magical-init', 923 + 'javelin-install', 924 + 'javelin-util', 925 + 'javelin-vector', 926 + 'javelin-stratcom', 927 + ), 921 928 '1499a8cb' => array( 922 929 'javelin-behavior', 923 930 'javelin-stratcom', ··· 1061 1068 ), 1062 1069 '331b1611' => array( 1063 1070 'javelin-install', 1064 - ), 1065 - '3975b470' => array( 1066 - 'javelin-behavior', 1067 - 'javelin-dom', 1068 - 'javelin-stratcom', 1069 - 'javelin-uri', 1070 1071 ), 1071 1072 '3ab51e2c' => array( 1072 1073 'javelin-behavior', ··· 1380 1381 'javelin-util', 1381 1382 'javelin-stratcom', 1382 1383 ), 1383 - '6f7962d5' => array( 1384 - 'javelin-magical-init', 1385 - 'javelin-install', 1386 - 'javelin-util', 1387 - 'javelin-vector', 1388 - 'javelin-stratcom', 1389 - ), 1390 1384 '70baed2f' => array( 1391 1385 'javelin-install', 1392 1386 'javelin-dom', ··· 1791 1785 'javelin-dom', 1792 1786 'javelin-util', 1793 1787 'phabricator-shaped-request', 1788 + ), 1789 + 'bea81850' => array( 1790 + 'javelin-behavior', 1791 + 'javelin-dom', 1792 + 'javelin-stratcom', 1793 + 'javelin-uri', 1794 1794 ), 1795 1795 'c1700f6f' => array( 1796 1796 'javelin-install',
+5 -4
webroot/rsrc/css/core/syntax.css
··· 131 131 .remarkup-code .rbw_i { color: indigo; } 132 132 .remarkup-code .rbw_v { color: violet; } 133 133 134 - .repository-crossreference .remarkup-code .nc, 135 - .repository-crossreference .remarkup-code .na, 136 - .repository-crossreference .remarkup-code .nf { 134 + .repository-crossreference .remarkup-code .crossreference-item { 135 + background: lightyellow; 136 + border-bottom: 1px dotted #bbddbb; 137 + } 138 + .crossreference-cursor { 137 139 cursor: help; 138 - border-bottom: 1px dotted #bbddbb; 139 140 } 140 141 141 142 .remarkup-code .invisible {
+1 -1
webroot/rsrc/externals/javelin/lib/DOM.js
··· 716 716 node.className += ' '+className; 717 717 } else if (has && !add) { 718 718 node.className = node.className.replace( 719 - new RegExp('(^|\\s)' + className + '(?:\\s|$)', 'g'), ' '); 719 + new RegExp('(^|\\s)' + className + '(?:\\s|$)', 'g'), ' ').trim(); 720 720 } 721 721 }, 722 722
+85 -35
webroot/rsrc/js/application/repository/repository-crossreference.js
··· 6 6 * javelin-uri 7 7 */ 8 8 9 - JX.behavior('repository-crossreference', function(config) { 9 + JX.behavior('repository-crossreference', function(config, statics) { 10 10 11 - // NOTE: Pretty much everything in this file is a worst practice. We're 12 - // constrained by the markup generated by the syntax highlighters. 11 + var highlighted; 12 + var linked = []; 13 + 14 + var isMac = navigator.platform.indexOf('Mac') > -1; 15 + var signalKey = isMac ? 91 /*COMMAND*/ : 17 /*CTRL*/; 16 + function isSignalkey(event) { 17 + return isMac ? 18 + event.getRawEvent().metaKey : 19 + event.getRawEvent().ctrlKey; 20 + } 21 + 22 + var classHighlight = 'crossreference-item'; 23 + var classMouseCursor = 'crossreference-cursor'; 24 + 25 + // TODO maybe move the dictionary part of this list to the server? 26 + var class_map = { 27 + nc : 'class', 28 + nf : 'function', 29 + na : null, 30 + nb : 'builtin', 31 + n : null, 32 + }; 13 33 14 34 function link(element, lang) { 15 35 JX.DOM.alterClass(element, 'repository-crossreference', true); 36 + linked.push(element); 16 37 JX.DOM.listen( 17 38 element, 18 - 'click', 39 + ['mouseover', 'mouseout', 'click'], 19 40 'tag:span', 20 41 function(e) { 21 - var target = e.getTarget(); 22 - var map = {nc : 'class', nf : 'function', na : null}; 23 - while (target !== document.body) { 24 - if (JX.DOM.isNode(target, 'span') && (target.className in map)) { 25 - var timeout = function() { 26 - if (window.getSelection && !window.getSelection().isCollapsed) { 27 - return; 28 - } 29 - var symbol = target.textContent || target.innerText; 30 - var query = { 31 - lang : lang, 32 - repositories : config.repositories.join(','), 33 - jump : true 34 - }; 35 - if (map[target.className]) { 36 - query.type = map[target.className]; 37 - } 38 - if (target.hasAttribute('data-symbol-context')) { 39 - query.context = target.getAttribute('data-symbol-context'); 40 - } 41 - if (target.hasAttribute('data-symbol-name')) { 42 - symbol = target.getAttribute('data-symbol-name'); 43 - } 44 - var uri = JX.$U('/diffusion/symbol/' + symbol + '/'); 45 - uri.addQueryParams(query); 46 - window.open(uri); 47 - }; 48 - setTimeout(timeout, 250); 49 - e.kill(); 50 - break; 42 + if (e.getType() === 'mouseout') { 43 + highlighted && JX.DOM.alterClass(highlighted, classHighlight, false); 44 + highlighted = null; 45 + return; 46 + } 47 + if (!isSignalkey(e)) { 48 + return; 49 + } 50 + if (e.getType() === 'mouseover') { 51 + var target = e.getTarget(); 52 + while (target !== document.body) { 53 + if (JX.DOM.isNode(target, 'span') && 54 + (target.className in class_map)) { 55 + highlighted = target; 56 + JX.DOM.alterClass(highlighted, classHighlight, true); 57 + break; 58 + } 59 + target = target.parentNode; 51 60 } 52 - target = target.parentNode; 61 + } else if (e.getType() === 'click') { 62 + openSearch(highlighted, lang); 53 63 } 54 64 }); 55 65 } 56 66 67 + function openSearch(target, lang) { 68 + var symbol = target.textContent || target.innerText; 69 + var query = { 70 + lang : lang, 71 + repositories : config.repositories.join(','), 72 + jump : true 73 + }; 74 + var c = target.className; 75 + c = c.replace(classHighlight, '').trim(); 76 + if (class_map[c]) { 77 + query.type = class_map[c]; 78 + } 79 + if (target.hasAttribute('data-symbol-context')) { 80 + query.context = target.getAttribute('data-symbol-context'); 81 + } 82 + if (target.hasAttribute('data-symbol-name')) { 83 + symbol = target.getAttribute('data-symbol-name'); 84 + } 85 + var uri = JX.$U('/diffusion/symbol/' + symbol + '/'); 86 + uri.addQueryParams(query); 87 + window.open(uri); 88 + } 89 + 57 90 function linkAll() { 58 91 var blocks = JX.DOM.scry(document.body, 'div', 'remarkup-code-block'); 59 92 for (var i = 0; i < blocks.length; ++i) { ··· 77 110 linkAll(e.getData().container); 78 111 }); 79 112 113 + JX.Stratcom.listen( 114 + ['keydown', 'keyup'], 115 + null, 116 + function(e) { 117 + if (e.getRawEvent().keyCode !== signalKey) { 118 + return; 119 + } 120 + statics.active = (e.getType() === 'keydown'); 121 + linked.forEach(function(element) { 122 + JX.DOM.alterClass(element, classMouseCursor, statics.active); 123 + }); 124 + 125 + if (!statics.active) { 126 + highlighted && JX.DOM.alterClass(highlighted, classHighlight, false); 127 + highlighted = null; 128 + } 129 + }); 80 130 });