diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -8,7 +8,7 @@ return array( 'names' => array( 'core.pkg.css' => 'b4a7e275', - 'core.pkg.js' => '808ae845', + 'core.pkg.js' => '771b0e84', 'darkconsole.pkg.js' => 'e7393ebb', 'differential.pkg.css' => '2de124c9', 'differential.pkg.js' => 'd0cd0df6', @@ -154,7 +154,7 @@ 'rsrc/css/phui/phui-tag-view.css' => '9d5d4400', 'rsrc/css/phui/phui-timeline-view.css' => '2efceff8', 'rsrc/css/phui/phui-two-column-view.css' => 'c75bfc5b', - 'rsrc/css/phui/workboards/phui-workboard.css' => '2a04b1a8', + 'rsrc/css/phui/workboards/phui-workboard.css' => 'f526057c', 'rsrc/css/phui/workboards/phui-workcard.css' => 'a869098a', 'rsrc/css/phui/workboards/phui-workpanel.css' => 'e1bd8d04', 'rsrc/css/sprite-login.css' => '60e8560e', @@ -447,7 +447,7 @@ 'rsrc/js/application/uiexample/notification-example.js' => '8ce821c5', 'rsrc/js/core/Busy.js' => '59a7976a', 'rsrc/js/core/DragAndDropFileUpload.js' => '81f182b5', - 'rsrc/js/core/DraggableList.js' => '8905523d', + 'rsrc/js/core/DraggableList.js' => '8199fb41', 'rsrc/js/core/FileUpload.js' => '680ea2c8', 'rsrc/js/core/Hovercard.js' => '1bd28176', 'rsrc/js/core/KeyboardShortcut.js' => '1ae869f2', @@ -742,7 +742,7 @@ 'phabricator-countdown-css' => 'e7544472', 'phabricator-dashboard-css' => 'eb458607', 'phabricator-drag-and-drop-file-upload' => '81f182b5', - 'phabricator-draggable-list' => '8905523d', + 'phabricator-draggable-list' => '8199fb41', 'phabricator-fatal-config-template-css' => '8e6c6fcd', 'phabricator-feed-css' => 'ecd4ec57', 'phabricator-file-upload' => '680ea2c8', @@ -831,7 +831,7 @@ 'phui-theme-css' => 'ab7b848c', 'phui-timeline-view-css' => '2efceff8', 'phui-two-column-view-css' => 'c75bfc5b', - 'phui-workboard-view-css' => '2a04b1a8', + 'phui-workboard-view-css' => 'f526057c', 'phui-workcard-view-css' => 'a869098a', 'phui-workpanel-view-css' => 'e1bd8d04', 'phuix-action-list-view' => 'b5c256b8', @@ -1451,6 +1451,14 @@ 'javelin-vector', 'javelin-stratcom', ), + '8199fb41' => array( + 'javelin-install', + 'javelin-dom', + 'javelin-stratcom', + 'javelin-util', + 'javelin-vector', + 'javelin-magical-init', + ), '81f182b5' => array( 'javelin-install', 'javelin-util', @@ -1496,14 +1504,6 @@ 'javelin-stratcom', 'javelin-dom', ), - '8905523d' => array( - 'javelin-install', - 'javelin-dom', - 'javelin-stratcom', - 'javelin-util', - 'javelin-vector', - 'javelin-magical-init', - ), '8a41885b' => array( 'javelin-install', 'javelin-dom', diff --git a/src/view/phui/PHUIWorkboardView.php b/src/view/phui/PHUIWorkboardView.php --- a/src/view/phui/PHUIWorkboardView.php +++ b/src/view/phui/PHUIWorkboardView.php @@ -25,12 +25,13 @@ $view->addColumn($panel); } - $board = phutil_tag( + $board = javelin_tag( 'div', - array( - 'class' => 'phui-workboard-view-shadow', - ), - $view); + array( + 'class' => 'phui-workboard-view-shadow', + 'sigil' => 'lock-scroll-while-dragging', + ), + $view); return $board; } diff --git a/webroot/rsrc/css/phui/workboards/phui-workboard.css b/webroot/rsrc/css/phui/workboards/phui-workboard.css --- a/webroot/rsrc/css/phui/workboards/phui-workboard.css +++ b/webroot/rsrc/css/phui/workboards/phui-workboard.css @@ -12,6 +12,7 @@ .device-desktop .phui-workboard-view-shadow { overflow-x: auto; + overflow-y: hidden; position: absolute; top: 79px; bottom: 0; @@ -70,3 +71,9 @@ .device .project-board-wrapper { margin: 16px; } + +.device-desktop .phui-workpanel-body { + max-height: calc(100vh - 170px); + overflow-y: scroll; + overflow-x: hidden; +} diff --git a/webroot/rsrc/js/core/DraggableList.js b/webroot/rsrc/js/core/DraggableList.js --- a/webroot/rsrc/js/core/DraggableList.js +++ b/webroot/rsrc/js/core/DraggableList.js @@ -310,6 +310,10 @@ return target_list; }, + _getTarget: function() { + return this._target; + }, + _setTarget : function(cur_target) { var ghost = this.getGhostNode(); var target = this._target; @@ -433,8 +437,6 @@ this._cursorOrigin.y - (this._cursorScroll.y - s.y)); } - this._updateAutoscroll(this._cursorPosition); - var p = JX.$V(this._cursorPosition.x, this._cursorPosition.y); var group = this._group; @@ -459,6 +461,8 @@ } } + this._updateAutoscroll(this._cursorPosition); + var f = JX.$V(this._frame); p.x -= f.x; p.y -= f.y; @@ -475,7 +479,7 @@ }, _updateAutoscroll: function(p) { - var container = this._dragging.parentNode; + var container = this._getScrollAnchor().parentNode; var autoscroll = {}; var outer = this.getOuterContainer(); @@ -595,6 +599,22 @@ this.invoke('didEndDrag', dragging); }, + _getScrollAnchor: function() { + // If you drag an item from column "A" into column "B", then move the + // mouse to the top or bottom of the screen, we need to scroll the target + // column (column "B"), not the original column. + + var group = this._group; + for (var ii = 0; ii < group.length; ii++) { + var target = group[ii]._getTarget(); + if (target) { + return group[ii]._ghostNode; + } + } + + return this._dragging; + }, + _onautoscroll: function() { var u = this._autoscroll.up; var d = this._autoscroll.down; @@ -613,20 +633,22 @@ var amount = 12 * (delta / 10); + var anchor = this._getScrollAnchor(); + if (u && (u != d)) { - this._tryScroll(this._dragging, u, 'scrollTop', amount); + this._tryScroll(anchor, u, 'scrollTop', amount); } if (d && (d != u)) { - this._tryScroll(this._dragging, d, 'scrollTop', -amount); + this._tryScroll(anchor, d, 'scrollTop', -amount); } if (l && (l != r)) { - this._tryScroll(this._dragging, l, 'scrollLeft', amount); + this._tryScroll(anchor, l, 'scrollLeft', amount); } if (r && (r != l)) { - this._tryScroll(this._dragging, r, 'scrollLeft', -amount); + this._tryScroll(anchor, r, 'scrollLeft', -amount); } }, @@ -639,19 +661,34 @@ var container = from.parentNode; while (container) { - // Read the current scroll value. - value = container[property]; - // Try to scroll. - container[property] -= amount; - - // If we scrolled it, we're all done. - if (container[property] != value) { - break; + // In Safari, we'll eventually reach `window.document`, which is not + // sufficently node-like to support sigil tests. + var lock; + if (container === window.document) { + lock = false; + } else { + // Some elements may respond to, e.g., `scrollTop` adjustment, even + // though they are not scrollable. This sigil disables adjustment + // for them. + lock = JX.Stratcom.hasSigil(container, 'lock-scroll-while-dragging'); } - if (container == to) { - break; + if (!lock) { + // Read the current scroll value. + value = container[property]; + + // Try to scroll. + container[property] -= amount; + + // If we scrolled it, we're all done. + if (container[property] != value) { + break; + } + + if (container == to) { + break; + } } container = container.parentNode;