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

Restore the "buoyant" header in Differential

Summary:
Fixes T1591. This was removed long ago because it was a mess to implement and caused a bunch of weird issues, and also my tolerance for dealing with weird JS issues was much, much lower.

I have now survived the fires of JX.Scrollbar and would love to address 200 small nitpicks about obscure browser behaviors on Linux, so open the floodgates again.

A secondary goal here is to create room to add a global view state menu on the right, with 300 options like "hide all inlines", "hide done inlines", "hide collapsed inlines", "hide ghosts", "show ghosts", "enable filetree", "disable filetree", etc, etc. Not sure how much of this I'll actually do. I have one more experiment I want to try first.

Test Plan: {F4963294}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T1591

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

+171 -41
+41 -41
resources/celerity/map.php
··· 9 9 'names' => array( 10 10 'conpherence.pkg.css' => 'ff161f2d', 11 11 'conpherence.pkg.js' => 'b5b51108', 12 - 'core.pkg.css' => 'a5a2d647', 13 - 'core.pkg.js' => '0f87a6eb', 12 + 'core.pkg.css' => '4937a7d7', 13 + 'core.pkg.js' => 'a0c8fb20', 14 14 'darkconsole.pkg.js' => '1f9a31bc', 15 - 'differential.pkg.css' => '697405d4', 16 - 'differential.pkg.js' => '07c56ffc', 15 + 'differential.pkg.css' => '52b014e7', 16 + 'differential.pkg.js' => '1efe85bf', 17 17 'diffusion.pkg.css' => 'b93d9b8c', 18 18 'diffusion.pkg.js' => '84c8f8fd', 19 19 'favicon.ico' => '30672e08', ··· 64 64 'rsrc/css/application/dashboard/dashboard.css' => 'fe5b1869', 65 65 'rsrc/css/application/diff/inline-comment-summary.css' => '51efda3a', 66 66 'rsrc/css/application/differential/add-comment.css' => 'c47f8c40', 67 - 'rsrc/css/application/differential/changeset-view.css' => '15be1064', 67 + 'rsrc/css/application/differential/changeset-view.css' => 'e7bd2a79', 68 68 'rsrc/css/application/differential/core.css' => '5b7b8ff4', 69 69 'rsrc/css/application/differential/phui-inline-comment.css' => 'ffd1a542', 70 70 'rsrc/css/application/differential/revision-comment.css' => '14b8565a', ··· 116 116 'rsrc/css/core/core.css' => '9f4cb463', 117 117 'rsrc/css/core/remarkup.css' => 'd1a5e11e', 118 118 'rsrc/css/core/syntax.css' => 'cae95e89', 119 - 'rsrc/css/core/z-index.css' => '0233d039', 119 + 'rsrc/css/core/z-index.css' => '9d8f7c4b', 120 120 'rsrc/css/diviner/diviner-shared.css' => '896f1d43', 121 121 'rsrc/css/font/font-awesome.css' => 'e838e088', 122 122 'rsrc/css/font/font-lato.css' => 'c7ccd872', ··· 390 390 'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => '408bf173', 391 391 'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '453c5375', 392 392 'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => 'd4eecc63', 393 - 'rsrc/js/application/diff/DiffChangeset.js' => '731125f3', 394 - 'rsrc/js/application/diff/DiffChangesetList.js' => '59d1ceb1', 393 + 'rsrc/js/application/diff/DiffChangeset.js' => '3268dd83', 394 + 'rsrc/js/application/diff/DiffChangesetList.js' => '0a4f7809', 395 395 'rsrc/js/application/diff/DiffInline.js' => '3337c065', 396 396 'rsrc/js/application/diff/behavior-preview-link.js' => '051c7832', 397 397 'rsrc/js/application/differential/behavior-comment-preview.js' => 'b064af76', ··· 503 503 'rsrc/js/core/behavior-more.js' => 'a80d0378', 504 504 'rsrc/js/core/behavior-object-selector.js' => 'e0ec7f2f', 505 505 'rsrc/js/core/behavior-oncopy.js' => '2926fff2', 506 - 'rsrc/js/core/behavior-phabricator-nav.js' => '08163386', 506 + 'rsrc/js/core/behavior-phabricator-nav.js' => '947753e0', 507 507 'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => 'acd29eee', 508 508 'rsrc/js/core/behavior-read-only-warning.js' => 'ba158207', 509 509 'rsrc/js/core/behavior-refresh-csrf.js' => 'ab2f381b', ··· 565 565 'conpherence-thread-manager' => '4d863052', 566 566 'conpherence-transaction-css' => '85129c68', 567 567 'd3' => 'a11a5ff2', 568 - 'differential-changeset-view-css' => '15be1064', 568 + 'differential-changeset-view-css' => 'e7bd2a79', 569 569 'differential-core-view-css' => '5b7b8ff4', 570 570 'differential-revision-add-comment-css' => 'c47f8c40', 571 571 'differential-revision-comment-css' => '14b8565a', ··· 658 658 'javelin-behavior-phabricator-keyboard-pager' => 'a8da01f0', 659 659 'javelin-behavior-phabricator-keyboard-shortcuts' => '01fca1f0', 660 660 'javelin-behavior-phabricator-line-linker' => '1499a8cb', 661 - 'javelin-behavior-phabricator-nav' => '08163386', 661 + 'javelin-behavior-phabricator-nav' => '947753e0', 662 662 'javelin-behavior-phabricator-notification-example' => '8ce821c5', 663 663 'javelin-behavior-phabricator-object-selector' => 'e0ec7f2f', 664 664 'javelin-behavior-phabricator-oncopy' => '2926fff2', ··· 775 775 'phabricator-darklog' => 'c8e1ffe3', 776 776 'phabricator-darkmessage' => 'c48cccdd', 777 777 'phabricator-dashboard-css' => 'fe5b1869', 778 - 'phabricator-diff-changeset' => '731125f3', 779 - 'phabricator-diff-changeset-list' => '59d1ceb1', 778 + 'phabricator-diff-changeset' => '3268dd83', 779 + 'phabricator-diff-changeset-list' => '0a4f7809', 780 780 'phabricator-diff-inline' => '3337c065', 781 781 'phabricator-drag-and-drop-file-upload' => '58dea2fa', 782 782 'phabricator-draggable-list' => 'bea6e7f4', ··· 816 816 'phabricator-uiexample-reactor-select' => 'a155550f', 817 817 'phabricator-uiexample-reactor-sendclass' => '1def2711', 818 818 'phabricator-uiexample-reactor-sendproperties' => 'b1f0ccee', 819 - 'phabricator-zindex-css' => '0233d039', 819 + 'phabricator-zindex-css' => '9d8f7c4b', 820 820 'phame-css' => 'b3a0b3a3', 821 821 'pholio-css' => 'ca89d380', 822 822 'pholio-edit-css' => '07676f51', ··· 946 946 'javelin-stratcom', 947 947 'javelin-workflow', 948 948 ), 949 - '08163386' => array( 950 - 'javelin-behavior', 951 - 'javelin-behavior-device', 952 - 'javelin-stratcom', 953 - 'javelin-dom', 954 - 'javelin-magical-init', 955 - 'javelin-vector', 956 - 'javelin-request', 957 - 'javelin-util', 958 - ), 959 949 '0825c27a' => array( 960 950 'javelin-behavior', 961 951 'javelin-dom', ··· 982 972 'javelin-workflow', 983 973 'javelin-dom', 984 974 'javelin-router', 975 + ), 976 + '0a4f7809' => array( 977 + 'javelin-install', 985 978 ), 986 979 '0f764c35' => array( 987 980 'javelin-install', ··· 999 992 'javelin-dom', 1000 993 'javelin-history', 1001 994 ), 1002 - '15be1064' => array( 1003 - 'phui-inline-comment-view-css', 1004 - ), 1005 995 '17bb8539' => array( 1006 996 'javelin-behavior', 1007 997 'javelin-stratcom', ··· 1121 1111 'javelin-install', 1122 1112 'javelin-dom', 1123 1113 'javelin-vector', 1114 + ), 1115 + '3268dd83' => array( 1116 + 'javelin-dom', 1117 + 'javelin-util', 1118 + 'javelin-stratcom', 1119 + 'javelin-install', 1120 + 'javelin-workflow', 1121 + 'javelin-router', 1122 + 'javelin-behavior-device', 1123 + 'javelin-vector', 1124 + 'phabricator-diff-inline', 1124 1125 ), 1125 1126 '327a00d1' => array( 1126 1127 'javelin-behavior', ··· 1349 1350 'javelin-vector', 1350 1351 'javelin-dom', 1351 1352 ), 1352 - '59d1ceb1' => array( 1353 - 'javelin-install', 1354 - ), 1355 1353 '5c54cbf3' => array( 1356 1354 'javelin-behavior', 1357 1355 'javelin-stratcom', ··· 1450 1448 'javelin-workflow', 1451 1449 'phabricator-draggable-list', 1452 1450 ), 1453 - '731125f3' => array( 1454 - 'javelin-dom', 1455 - 'javelin-util', 1456 - 'javelin-stratcom', 1457 - 'javelin-install', 1458 - 'javelin-workflow', 1459 - 'javelin-router', 1460 - 'javelin-behavior-device', 1461 - 'javelin-vector', 1462 - 'phabricator-diff-inline', 1463 - ), 1464 1451 '7319e029' => array( 1465 1452 'javelin-behavior', 1466 1453 'javelin-dom', ··· 1618 1605 'javelin-stratcom', 1619 1606 'javelin-workflow', 1620 1607 'javelin-dom', 1608 + ), 1609 + '947753e0' => array( 1610 + 'javelin-behavior', 1611 + 'javelin-behavior-device', 1612 + 'javelin-stratcom', 1613 + 'javelin-dom', 1614 + 'javelin-magical-init', 1615 + 'javelin-vector', 1616 + 'javelin-request', 1617 + 'javelin-util', 1621 1618 ), 1622 1619 '949c0fe5' => array( 1623 1620 'javelin-install', ··· 2126 2123 'javelin-json', 2127 2124 'javelin-workflow', 2128 2125 'javelin-magical-init', 2126 + ), 2127 + 'e7bd2a79' => array( 2128 + 'phui-inline-comment-view-css', 2129 2129 ), 2130 2130 'e9581f08' => array( 2131 2131 'javelin-behavior',
+1
src/applications/differential/view/DifferentialChangesetDetailView.php
··· 183 183 'autoload' => $this->getAutoload(), 184 184 'loaded' => $this->getLoaded(), 185 185 'undoTemplates' => hsprintf('%s', $renderer->renderUndoTemplates()), 186 + 'path' => $display_filename, 186 187 ), 187 188 'class' => $class, 188 189 'id' => $id,
+18
webroot/rsrc/css/application/differential/changeset-view.css
··· 386 386 .differential-review-stage { 387 387 position: relative; 388 388 } 389 + 390 + .diff-banner { 391 + position: fixed; 392 + top: 0; 393 + left: 0; 394 + right: 0; 395 + background: rgba(255, 255, 255, 0.95); 396 + box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1); 397 + border-bottom: 1px solid {$lightgreyborder}; 398 + padding: 12px 18px; 399 + vertical-align: middle; 400 + font-weight: bold; 401 + font-size: {$biggerfontsize}; 402 + } 403 + 404 + .diff-banner .phui-icon-view { 405 + margin-right: 4px; 406 + }
+4
webroot/rsrc/css/core/z-index.css
··· 93 93 z-index: 6; 94 94 } 95 95 96 + .diff-banner { 97 + z-index: 6; 98 + } 99 + 96 100 .conpherence-durable-column { 97 101 z-index: 7; 98 102 }
+14
webroot/rsrc/js/application/diff/DiffChangeset.js
··· 19 19 this._node = node; 20 20 21 21 var data = this._getNodeData(); 22 + 22 23 this._renderURI = data.renderURI; 23 24 this._ref = data.ref; 24 25 this._whitespace = data.whitespace; ··· 29 30 30 31 this._leftID = data.left; 31 32 this._rightID = data.right; 33 + 34 + this._path = data.path; 32 35 33 36 this._inlines = []; 34 37 }, ··· 58 61 _visible: true, 59 62 60 63 _undoNode: null, 64 + _path: null, 61 65 62 66 getLeftChangesetID: function() { 63 67 return this._leftID; ··· 227 231 JX.Router.getInstance().queue(routable); 228 232 }, 229 233 234 + getPath: function() { 235 + return this._path; 236 + }, 230 237 231 238 /** 232 239 * Receive a response to a context request. ··· 426 433 427 434 _getNodeData: function() { 428 435 return JX.Stratcom.getData(this._node); 436 + }, 437 + 438 + getVectors: function() { 439 + return { 440 + pos: JX.$V(this._node), 441 + dim: JX.Vector.getDim(this._node) 442 + }; 429 443 }, 430 444 431 445 _onresponse: function(sequence, response) {
+82
webroot/rsrc/js/application/diff/DiffChangesetList.js
··· 51 51 var onresize = JX.bind(this, this._ifawake, this._onresize); 52 52 JX.Stratcom.listen('resize', null, onresize); 53 53 54 + var onscroll = JX.bind(this, this._ifawake, this._onscroll); 55 + JX.Stratcom.listen('scroll', null, onscroll); 56 + 54 57 var onselect = JX.bind(this, this._ifawake, this._onselect); 55 58 JX.Stratcom.listen( 56 59 'mousedown', ··· 112 115 _rangeActive: false, 113 116 _rangeOrigin: null, 114 117 _rangeTarget: null, 118 + 119 + _bannerNode: null, 115 120 116 121 sleep: function() { 117 122 this._asleep = true; ··· 807 812 this._redrawFocus(); 808 813 this._redrawSelection(); 809 814 this._redrawHover(); 815 + 816 + this._redrawBanner(); 817 + }, 818 + 819 + _onscroll: function() { 820 + this._redrawBanner(); 810 821 }, 811 822 812 823 _onselect: function(e) { ··· 1265 1276 this._rangeTarget = null; 1266 1277 1267 1278 this.resetHover(); 1279 + }, 1280 + 1281 + _redrawBanner: function() { 1282 + var node = this._getBannerNode(); 1283 + var changeset = this._getVisibleChangeset(); 1284 + 1285 + // Don't do anything if nothing has changed. This seems to avoid some 1286 + // flickering issues in Safari, at least. 1287 + if (this._bannerChangeset === changeset) { 1288 + return; 1289 + } 1290 + this._bannerChangeset = changeset; 1291 + 1292 + if (!changeset) { 1293 + JX.DOM.remove(node); 1294 + return; 1295 + } 1296 + 1297 + var icon = new JX.PHUIXIconView() 1298 + .setIcon('fa-file') 1299 + .getNode(); 1300 + JX.DOM.setContent(node, [icon, ' ', changeset.getPath()]); 1301 + 1302 + document.body.appendChild(node); 1303 + }, 1304 + 1305 + _getBannerNode: function() { 1306 + if (!this._bannerNode) { 1307 + var attributes = { 1308 + className: 'diff-banner', 1309 + id: 'diff-banner' 1310 + }; 1311 + 1312 + this._bannerNode = JX.$N('div', attributes); 1313 + } 1314 + 1315 + return this._bannerNode; 1316 + }, 1317 + 1318 + _getVisibleChangeset: function() { 1319 + if (this.isAsleep()) { 1320 + return null; 1321 + } 1322 + 1323 + if (JX.Device.getDevice() != 'desktop') { 1324 + return null; 1325 + } 1326 + 1327 + // Never show the banner if we're very near the top of the page. 1328 + var margin = 480; 1329 + var s = JX.Vector.getScroll(); 1330 + if (s.y < margin) { 1331 + return null; 1332 + } 1333 + 1334 + var v = JX.Vector.getViewport(); 1335 + for (var ii = 0; ii < this._changesets.length; ii++) { 1336 + var changeset = this._changesets[ii]; 1337 + var c = changeset.getVectors(); 1338 + 1339 + // If the changeset starts above the upper half of the screen... 1340 + if (c.pos.y < (s.y + (v.y / 2))) { 1341 + // ...and ends below the lower half of the screen, this is the 1342 + // current visible changeset. 1343 + if ((c.pos.y + c.dim.y) > (s.y + (v.y / 2))) { 1344 + return changeset; 1345 + } 1346 + } 1347 + } 1348 + 1349 + return null; 1268 1350 } 1269 1351 } 1270 1352
+11
webroot/rsrc/js/core/behavior-phabricator-nav.js
··· 130 130 return; 131 131 } 132 132 133 + // When the buoyant header is visible, move the menu down below it. This 134 + // is a bit of a hack. 135 + var banner_height = 0; 136 + try { 137 + var banner = JX.$('diff-banner'); 138 + banner_height = JX.Vector.getDim(banner).y; 139 + } catch (error) { 140 + // Ignore if there's no banner on the page. 141 + } 142 + 133 143 local.style.top = Math.max( 134 144 0, 145 + banner_height, 135 146 JX.$V(content).y - Math.max(0, JX.Vector.getScroll().y)) + 'px'; 136 147 } 137 148