1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-20 01:08:50 +02:00

Stabilize scroll position as diffs load

Summary:
Try to lock the screen to whatever the user is looking at as we load changesets.

Notably, this improves the use case of taking a known action on a diff. Currently, you have to wait for everything to load or the comments keep getting scrolled down. After this change, the comments stay in the same place on screen.

Test Plan:
Raised the autoload changeset limit from 100 to 1000, looked at a 220 changeset diff.

  - Reloaded it while scrolled at the top; normal behavior (no scrolling).
  - Reloaded it, scrolled to the bottom. Comment area now stable.
  - Reloaded it, kind of scrolled around the middle? Behavior seemed stable/reasonable. This one is kind of heursitic so it's hard to say I'm getting it totally right or not, but it's less important than the "bottom" case.

Reviewers: vrana, btrahan, chad, dctrwatson

Reviewed By: btrahan

CC: aran

Differential Revision: https://secure.phabricator.com/D4774
This commit is contained in:
epriestley 2013-02-01 10:52:07 -08:00
parent 2ce4d2c53a
commit e0dbc57521
2 changed files with 91 additions and 48 deletions

View file

@ -1305,7 +1305,7 @@ celerity_register_resource_map(array(
),
'javelin-behavior-differential-populate' =>
array(
'uri' => '/res/71effec4/rsrc/js/application/differential/behavior-populate.js',
'uri' => '/res/526c2615/rsrc/js/application/differential/behavior-populate.js',
'type' => 'js',
'requires' =>
array(
@ -1315,7 +1315,8 @@ celerity_register_resource_map(array(
3 => 'javelin-dom',
4 => 'javelin-stratcom',
5 => 'javelin-behavior-device',
6 => 'phabricator-tooltip',
6 => 'javelin-vector',
7 => 'phabricator-tooltip',
),
'disk' => '/rsrc/js/application/differential/behavior-populate.js',
),
@ -1850,7 +1851,7 @@ celerity_register_resource_map(array(
),
'javelin-behavior-pholio-mock-view' =>
array(
'uri' => '/res/e7946465/rsrc/js/application/pholio/behavior-pholio-mock-view.js',
'uri' => '/res/10fbdca1/rsrc/js/application/pholio/behavior-pholio-mock-view.js',
'type' => 'js',
'requires' =>
array(
@ -2038,7 +2039,7 @@ celerity_register_resource_map(array(
),
'javelin-event' =>
array(
'uri' => '/res/fdb41aa9/rsrc/js/javelin/core/Event.js',
'uri' => '/res/3815b473/rsrc/js/javelin/core/Event.js',
'type' => 'js',
'requires' =>
array(
@ -3504,7 +3505,7 @@ celerity_register_resource_map(array(
'uri' => '/res/pkg/ec01d039/differential.pkg.css',
'type' => 'css',
),
'9dae5f20' =>
'1b2c991b' =>
array(
'name' => 'differential.pkg.js',
'symbols' =>
@ -3529,7 +3530,7 @@ celerity_register_resource_map(array(
17 => 'javelin-behavior-differential-toggle-files',
18 => 'javelin-behavior-differential-user-select',
),
'uri' => '/res/pkg/9dae5f20/differential.pkg.js',
'uri' => '/res/pkg/1b2c991b/differential.pkg.js',
'type' => 'js',
),
'c8ce2d88' =>
@ -3555,7 +3556,7 @@ celerity_register_resource_map(array(
'uri' => '/res/pkg/f96657b8/diffusion.pkg.js',
'type' => 'js',
),
'5f5e63ce' =>
'fbeded59' =>
array(
'name' => 'javelin.pkg.js',
'symbols' =>
@ -3580,7 +3581,7 @@ celerity_register_resource_map(array(
17 => 'javelin-typeahead-ondemand-source',
18 => 'javelin-tokenizer',
),
'uri' => '/res/pkg/5f5e63ce/javelin.pkg.js',
'uri' => '/res/pkg/fbeded59/javelin.pkg.js',
'type' => 'js',
),
'e30a3fa8' =>
@ -3629,7 +3630,7 @@ celerity_register_resource_map(array(
'aphront-typeahead-control-css' => '6ea96b26',
'differential-changeset-view-css' => 'ec01d039',
'differential-core-view-css' => 'ec01d039',
'differential-inline-comment-editor' => '9dae5f20',
'differential-inline-comment-editor' => '1b2c991b',
'differential-local-commits-view-css' => 'ec01d039',
'differential-results-table-css' => 'ec01d039',
'differential-revision-add-comment-css' => 'ec01d039',
@ -3643,29 +3644,29 @@ celerity_register_resource_map(array(
'global-drag-and-drop-css' => '6ea96b26',
'inline-comment-summary-css' => 'ec01d039',
'javelin-aphlict' => '8a3f0fbd',
'javelin-behavior' => '5f5e63ce',
'javelin-behavior' => 'fbeded59',
'javelin-behavior-aphlict-dropdown' => '8a3f0fbd',
'javelin-behavior-aphlict-listen' => '8a3f0fbd',
'javelin-behavior-aphront-basic-tokenizer' => '8a3f0fbd',
'javelin-behavior-aphront-drag-and-drop' => '9dae5f20',
'javelin-behavior-aphront-drag-and-drop-textarea' => '9dae5f20',
'javelin-behavior-aphront-drag-and-drop' => '1b2c991b',
'javelin-behavior-aphront-drag-and-drop-textarea' => '1b2c991b',
'javelin-behavior-aphront-form-disable-on-submit' => '8a3f0fbd',
'javelin-behavior-audit-preview' => 'f96657b8',
'javelin-behavior-dark-console' => '8edbada5',
'javelin-behavior-dark-console-ajax' => '8edbada5',
'javelin-behavior-device' => '8a3f0fbd',
'javelin-behavior-differential-accept-with-errors' => '9dae5f20',
'javelin-behavior-differential-add-reviewers-and-ccs' => '9dae5f20',
'javelin-behavior-differential-comment-jump' => '9dae5f20',
'javelin-behavior-differential-diff-radios' => '9dae5f20',
'javelin-behavior-differential-dropdown-menus' => '9dae5f20',
'javelin-behavior-differential-edit-inline-comments' => '9dae5f20',
'javelin-behavior-differential-feedback-preview' => '9dae5f20',
'javelin-behavior-differential-keyboard-navigation' => '9dae5f20',
'javelin-behavior-differential-populate' => '9dae5f20',
'javelin-behavior-differential-show-more' => '9dae5f20',
'javelin-behavior-differential-toggle-files' => '9dae5f20',
'javelin-behavior-differential-user-select' => '9dae5f20',
'javelin-behavior-differential-accept-with-errors' => '1b2c991b',
'javelin-behavior-differential-add-reviewers-and-ccs' => '1b2c991b',
'javelin-behavior-differential-comment-jump' => '1b2c991b',
'javelin-behavior-differential-diff-radios' => '1b2c991b',
'javelin-behavior-differential-dropdown-menus' => '1b2c991b',
'javelin-behavior-differential-edit-inline-comments' => '1b2c991b',
'javelin-behavior-differential-feedback-preview' => '1b2c991b',
'javelin-behavior-differential-keyboard-navigation' => '1b2c991b',
'javelin-behavior-differential-populate' => '1b2c991b',
'javelin-behavior-differential-show-more' => '1b2c991b',
'javelin-behavior-differential-toggle-files' => '1b2c991b',
'javelin-behavior-differential-user-select' => '1b2c991b',
'javelin-behavior-diffusion-commit-graph' => 'f96657b8',
'javelin-behavior-diffusion-pull-lastmodified' => 'f96657b8',
'javelin-behavior-error-log' => '8edbada5',
@ -3682,34 +3683,34 @@ celerity_register_resource_map(array(
'javelin-behavior-phabricator-home-reveal-tiles' => '8a3f0fbd',
'javelin-behavior-phabricator-keyboard-shortcuts' => '8a3f0fbd',
'javelin-behavior-phabricator-nav' => '8a3f0fbd',
'javelin-behavior-phabricator-object-selector' => '9dae5f20',
'javelin-behavior-phabricator-object-selector' => '1b2c991b',
'javelin-behavior-phabricator-oncopy' => '8a3f0fbd',
'javelin-behavior-phabricator-remarkup-assist' => '8a3f0fbd',
'javelin-behavior-phabricator-search-typeahead' => '8a3f0fbd',
'javelin-behavior-phabricator-tooltips' => '8a3f0fbd',
'javelin-behavior-phabricator-watch-anchor' => '8a3f0fbd',
'javelin-behavior-refresh-csrf' => '8a3f0fbd',
'javelin-behavior-repository-crossreference' => '9dae5f20',
'javelin-behavior-repository-crossreference' => '1b2c991b',
'javelin-behavior-toggle-class' => '8a3f0fbd',
'javelin-behavior-workflow' => '8a3f0fbd',
'javelin-dom' => '5f5e63ce',
'javelin-event' => '5f5e63ce',
'javelin-install' => '5f5e63ce',
'javelin-json' => '5f5e63ce',
'javelin-mask' => '5f5e63ce',
'javelin-request' => '5f5e63ce',
'javelin-resource' => '5f5e63ce',
'javelin-stratcom' => '5f5e63ce',
'javelin-tokenizer' => '5f5e63ce',
'javelin-typeahead' => '5f5e63ce',
'javelin-typeahead-normalizer' => '5f5e63ce',
'javelin-typeahead-ondemand-source' => '5f5e63ce',
'javelin-typeahead-preloaded-source' => '5f5e63ce',
'javelin-typeahead-source' => '5f5e63ce',
'javelin-uri' => '5f5e63ce',
'javelin-util' => '5f5e63ce',
'javelin-vector' => '5f5e63ce',
'javelin-workflow' => '5f5e63ce',
'javelin-dom' => 'fbeded59',
'javelin-event' => 'fbeded59',
'javelin-install' => 'fbeded59',
'javelin-json' => 'fbeded59',
'javelin-mask' => 'fbeded59',
'javelin-request' => 'fbeded59',
'javelin-resource' => 'fbeded59',
'javelin-stratcom' => 'fbeded59',
'javelin-tokenizer' => 'fbeded59',
'javelin-typeahead' => 'fbeded59',
'javelin-typeahead-normalizer' => 'fbeded59',
'javelin-typeahead-ondemand-source' => 'fbeded59',
'javelin-typeahead-preloaded-source' => 'fbeded59',
'javelin-typeahead-source' => 'fbeded59',
'javelin-uri' => 'fbeded59',
'javelin-util' => 'fbeded59',
'javelin-vector' => 'fbeded59',
'javelin-workflow' => 'fbeded59',
'lightbox-attachment-css' => '6ea96b26',
'maniphest-task-summary-css' => 'e30a3fa8',
'maniphest-transaction-detail-css' => 'e30a3fa8',
@ -3719,7 +3720,7 @@ celerity_register_resource_map(array(
'phabricator-core-css' => '6ea96b26',
'phabricator-crumbs-view-css' => '6ea96b26',
'phabricator-directory-css' => '6ea96b26',
'phabricator-drag-and-drop-file-upload' => '9dae5f20',
'phabricator-drag-and-drop-file-upload' => '1b2c991b',
'phabricator-dropdown-menu' => '8a3f0fbd',
'phabricator-file-upload' => '8a3f0fbd',
'phabricator-filetree-view-css' => '6ea96b26',
@ -3741,7 +3742,7 @@ celerity_register_resource_map(array(
'phabricator-prefab' => '8a3f0fbd',
'phabricator-project-tag-css' => 'e30a3fa8',
'phabricator-remarkup-css' => '6ea96b26',
'phabricator-shaped-request' => '9dae5f20',
'phabricator-shaped-request' => '1b2c991b',
'phabricator-side-menu-view-css' => '6ea96b26',
'phabricator-standard-page-view' => '6ea96b26',
'phabricator-textareautils' => '8a3f0fbd',

View file

@ -6,13 +6,55 @@
* javelin-dom
* javelin-stratcom
* javelin-behavior-device
* javelin-vector
* phabricator-tooltip
*/
JX.behavior('differential-populate', function(config) {
function onresponse(target, response) {
JX.DOM.replace(JX.$(target), JX.$H(response.changeset));
function onresponse(target_id, response) {
// As we populate the diff, we try to hold the document scroll position
// steady, so that, e.g., users who want to leave a comment on a diff with a
// large number of changes don't constantly have the text area scrolled off
// the bottom of the screen until the entire diff loads.
//
// There are two three major cases here:
//
// - If we're near the top of the document, never scroll.
// - If we're near the bottom of the document, always scroll.
// - Otherwise, scroll if the changes were above the midline of the
// viewport.
var target = JX.$(target_id);
var old_pos = JX.Vector.getScroll();
var old_view = JX.Vector.getViewport();
var old_dim = JX.Vector.getDocument();
// Number of pixels away from the top or bottom of the document which
// count as "nearby".
var sticky = 480;
var near_top = (old_pos.y <= sticky);
var near_bot = ((old_pos.y + old_view.y) >= (old_dim.y - sticky));
var target_pos = JX.Vector.getPos(target);
var target_dim = JX.Vector.getDim(target);
var target_mid = (target_pos.y + (target_dim.y / 2));
var view_mid = (old_pos.y + (old_view.y / 2));
var above_mid = (target_mid < view_mid);
JX.DOM.replace(target, JX.$H(response.changeset));
if (!near_top) {
if (near_bot || above_mid) {
// Figure out how much taller the document got.
var delta = (JX.Vector.getDocument().y - old_dim.y);
window.scrollTo(old_pos.x, old_pos.y + delta);
}
}
if (response.coverage) {
for (var k in response.coverage) {
try {