diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -8,10 +8,10 @@ return array( 'names' => array( 'core.pkg.css' => '9a9b59ca', - 'core.pkg.js' => '348d5193', + 'core.pkg.js' => '493cc6e6', 'darkconsole.pkg.js' => '8ab24e01', 'differential.pkg.css' => '3500921f', - 'differential.pkg.js' => 'c0506961', + 'differential.pkg.js' => '890046d3', 'diffusion.pkg.css' => '591664fa', 'diffusion.pkg.js' => '0115b37c', 'maniphest.pkg.css' => '68d4dd3d', @@ -442,7 +442,7 @@ 'rsrc/js/application/uiexample/gesture-example.js' => '558829c2', 'rsrc/js/application/uiexample/notification-example.js' => '8ce821c5', 'rsrc/js/core/Busy.js' => '59a7976a', - 'rsrc/js/core/DragAndDropFileUpload.js' => '7fa4b248', + 'rsrc/js/core/DragAndDropFileUpload.js' => '07de8873', 'rsrc/js/core/DraggableList.js' => 'a16ec1c6', 'rsrc/js/core/FileUpload.js' => '477359c8', 'rsrc/js/core/Hovercard.js' => '7e8468ae', @@ -468,7 +468,7 @@ 'rsrc/js/core/behavior-file-tree.js' => '88236f00', 'rsrc/js/core/behavior-form.js' => '5c54cbf3', 'rsrc/js/core/behavior-gesture.js' => '3ab51e2c', - 'rsrc/js/core/behavior-global-drag-and-drop.js' => 'bbdf75ca', + 'rsrc/js/core/behavior-global-drag-and-drop.js' => '3f6075ff', 'rsrc/js/core/behavior-high-security-warning.js' => '8fc1c918', 'rsrc/js/core/behavior-history-install.js' => '7ee2b591', 'rsrc/js/core/behavior-hovercard.js' => 'f36e01af', @@ -593,7 +593,7 @@ 'javelin-behavior-durable-column' => '657c2b50', 'javelin-behavior-error-log' => '6882e80a', 'javelin-behavior-fancy-datepicker' => 'c51ae228', - 'javelin-behavior-global-drag-and-drop' => 'bbdf75ca', + 'javelin-behavior-global-drag-and-drop' => '3f6075ff', 'javelin-behavior-herald-rule-editor' => '7ebaeed3', 'javelin-behavior-high-security-warning' => '8fc1c918', 'javelin-behavior-history-install' => '7ee2b591', @@ -726,7 +726,7 @@ 'phabricator-core-css' => '76e8ee93', 'phabricator-countdown-css' => '86b7b0a0', 'phabricator-dashboard-css' => '17937d22', - 'phabricator-drag-and-drop-file-upload' => '7fa4b248', + 'phabricator-drag-and-drop-file-upload' => '07de8873', 'phabricator-draggable-list' => 'a16ec1c6', 'phabricator-fatal-config-template-css' => '8e6c6fcd', 'phabricator-feed-css' => 'b513b5f4', @@ -869,6 +869,14 @@ 'phabricator-shaped-request', 'conpherence-thread-manager', ), + '07de8873' => array( + 'javelin-install', + 'javelin-util', + 'javelin-request', + 'javelin-dom', + 'javelin-uri', + 'phabricator-file-upload', + ), '08883e8b' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1080,6 +1088,13 @@ 'javelin-dom', 'phortune-credit-card-form', ), + '3f6075ff' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-uri', + 'javelin-mask', + 'phabricator-drag-and-drop-file-upload', + ), '40a6a403' => array( 'javelin-install', 'javelin-dom', @@ -1413,14 +1428,6 @@ 'javelin-behavior', 'javelin-history', ), - '7fa4b248' => array( - 'javelin-install', - 'javelin-util', - 'javelin-request', - 'javelin-dom', - 'javelin-uri', - 'phabricator-file-upload', - ), 82439934 => array( 'javelin-behavior', 'javelin-dom', @@ -1722,13 +1729,6 @@ 'javelin-stratcom', 'javelin-dom', ), - 'bbdf75ca' => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-uri', - 'javelin-mask', - 'phabricator-drag-and-drop-file-upload', - ), 'bd4c8dca' => array( 'javelin-install', 'javelin-util', diff --git a/src/applications/base/controller/PhabricatorController.php b/src/applications/base/controller/PhabricatorController.php --- a/src/applications/base/controller/PhabricatorController.php +++ b/src/applications/base/controller/PhabricatorController.php @@ -57,6 +57,10 @@ return false; } + public function isGlobalDragAndDropUploadEnabled() { + return false; + } + public function willBeginExecution() { $request = $this->getRequest(); diff --git a/src/applications/files/controller/PhabricatorFileListController.php b/src/applications/files/controller/PhabricatorFileListController.php --- a/src/applications/files/controller/PhabricatorFileListController.php +++ b/src/applications/files/controller/PhabricatorFileListController.php @@ -2,19 +2,17 @@ final class PhabricatorFileListController extends PhabricatorFileController { - private $key; - public function shouldAllowPublic() { return true; } - public function willProcessRequest(array $data) { - $this->key = idx($data, 'key'); + public function isGlobalDragAndDropUploadEnabled() { + return true; } - public function processRequest() { + public function handleRequest(AphrontRequest $request) { $controller = id(new PhabricatorApplicationSearchController()) - ->setQueryKey($this->key) + ->setQueryKey($request->getURIData('key')) ->setSearchEngine(new PhabricatorFileSearchEngine()) ->setNavigation($this->buildSideNavView()); diff --git a/src/applications/files/controller/PhabricatorFileUploadController.php b/src/applications/files/controller/PhabricatorFileUploadController.php --- a/src/applications/files/controller/PhabricatorFileUploadController.php +++ b/src/applications/files/controller/PhabricatorFileUploadController.php @@ -2,8 +2,11 @@ final class PhabricatorFileUploadController extends PhabricatorFileController { - public function processRequest() { - $request = $this->getRequest(); + public function isGlobalDragAndDropUploadEnabled() { + return true; + } + + public function handleRequest(AphrontRequest $request) { $viewer = $request->getUser(); $file = PhabricatorFile::initializeNewFile(); diff --git a/src/applications/files/view/PhabricatorGlobalUploadTargetView.php b/src/applications/files/view/PhabricatorGlobalUploadTargetView.php --- a/src/applications/files/view/PhabricatorGlobalUploadTargetView.php +++ b/src/applications/files/view/PhabricatorGlobalUploadTargetView.php @@ -1,5 +1,16 @@ only = idx($data, 'only'); + public function isGlobalDragAndDropUploadEnabled() { + return true; } - public function processRequest() { - $user = $this->getRequest()->getUser(); + public function handleRequest(AphrontRequest $request) { + $user = $request->getUser(); $dashboard = PhabricatorDashboardInstall::getDashboard( $user, @@ -42,7 +41,7 @@ $content = $this->buildMainResponse($projects); } - if (!$this->only) { + if (!$request->getURIData('only')) { $nav = $this->buildNav(); $nav->appendChild( array( diff --git a/src/view/page/PhabricatorStandardPageView.php b/src/view/page/PhabricatorStandardPageView.php --- a/src/view/page/PhabricatorStandardPageView.php +++ b/src/view/page/PhabricatorStandardPageView.php @@ -605,6 +605,7 @@ private function buildQuicksandConfig() { $viewer = $this->getRequest()->getUser(); + $controller = $this->getController(); $dropdown_query = id(new AphlictDropdownDataQuery()) ->setViewer($viewer); @@ -624,7 +625,7 @@ $rendered_dropdowns[$application_class] = $application->buildMainMenuExtraNodes( $viewer, - $this->getController()); + $controller); } $console_config = null; @@ -638,6 +639,7 @@ $dropdown_query->getNotificationData(), $dropdown_query->getConpherenceData(), ), + 'globalDragAndDrop' => $controller->isGlobalDragAndDropUploadEnabled(), 'aphlictDropdowns' => $rendered_dropdowns, 'consoleConfig' => $console_config, ) + $this->buildAphlictListenConfigData(); diff --git a/webroot/rsrc/js/core/DragAndDropFileUpload.js b/webroot/rsrc/js/core/DragAndDropFileUpload.js --- a/webroot/rsrc/js/core/DragAndDropFileUpload.js +++ b/webroot/rsrc/js/core/DragAndDropFileUpload.js @@ -40,6 +40,17 @@ members : { _node : null, _depth : 0, + _isEnabled: false, + + setIsEnabled: function(bool) { + this._isEnabled = bool; + return this; + }, + + getIsEnabled: function() { + return this._isEnabled; + }, + _updateDepth : function(delta) { if (this._depth === 0 && delta > 0) { this.invoke('didBeginDrag'); @@ -54,6 +65,7 @@ start : function() { + // TODO: move this to JX.DOM.contains()? function contains(container, child) { do { @@ -73,6 +85,9 @@ 'click', null, JX.bind(this, function (e) { + if (!this.getIsEnabled()) { + return; + } if (this._depth) { e.kill(); // Force depth to 0. @@ -87,6 +102,10 @@ 'dragenter', null, JX.bind(this, function(e) { + if (!this.getIsEnabled()) { + return; + } + if (contains(this._node, e.getTarget())) { this._updateDepth(1); } @@ -97,6 +116,10 @@ 'dragleave', null, JX.bind(this, function(e) { + if (!this.getIsEnabled()) { + return; + } + if (contains(this._node, e.getTarget())) { this._updateDepth(-1); } @@ -106,18 +129,26 @@ this._node, 'dragover', null, - function(e) { + JX.bind(this, function(e) { + if (!this.getIsEnabled()) { + return; + } + // NOTE: We must set this, or Chrome refuses to drop files from the // download shelf. e.getRawEvent().dataTransfer.dropEffect = 'copy'; e.kill(); - }); + })); JX.DOM.listen( this._node, 'drop', null, JX.bind(this, function(e) { + if (!this.getIsEnabled()) { + return; + } + e.kill(); var files = e.getRawEvent().dataTransfer.files; @@ -135,6 +166,10 @@ 'paste', null, JX.bind(this, function(e) { + if (!this.getIsEnabled()) { + return; + } + var clipboard = e.getRawEvent().clipboardData; if (!clipboard) { return; @@ -168,6 +203,8 @@ } })); } + + this.setIsEnabled(true); }, _sendRequest : function(spec) { diff --git a/webroot/rsrc/js/core/behavior-global-drag-and-drop.js b/webroot/rsrc/js/core/behavior-global-drag-and-drop.js --- a/webroot/rsrc/js/core/behavior-global-drag-and-drop.js +++ b/webroot/rsrc/js/core/behavior-global-drag-and-drop.js @@ -7,64 +7,102 @@ * phabricator-drag-and-drop-file-upload */ -JX.behavior('global-drag-and-drop', function(config) { +JX.behavior('global-drag-and-drop', function(config, statics) { if (!JX.PhabricatorDragAndDropFileUpload.isSupported()) { return; } - var pending = 0; - var files = []; - var errors = false; + function init() { + statics.pending = 0; + statics.files = []; + statics.errors = false; + statics.enabled = true; - if (config.ifSupported) { - JX.$(config.ifSupported).style.display = ''; + if (config.ifSupported) { + JX.$(config.ifSupported).style.display = ''; + } + + var page = JX.$('phabricator-standard-page'); + statics.drop = new JX.PhabricatorDragAndDropFileUpload(page) + .setURI(config.uploadURI) + .setViewPolicy(config.viewPolicy) + .setChunkThreshold(config.chunkThreshold); + + install_extra_listeners(); + + statics.drop.start(); + + return true; } - var page = JX.$('phabricator-standard-page'); - var drop = new JX.PhabricatorDragAndDropFileUpload(page) - .setURI(config.uploadURI) - .setViewPolicy(config.viewPolicy) - .setChunkThreshold(config.chunkThreshold); - - drop.listen('didBeginDrag', function() { - JX.Mask.show('global-upload-mask'); - JX.DOM.show(JX.$(config.instructions)); - }); - - drop.listen('didEndDrag', function() { - JX.Mask.hide('global-upload-mask'); - JX.DOM.hide(JX.$(config.instructions)); - }); - - drop.listen('willUpload', function() { - pending++; - }); - - drop.listen('didUpload', function(f) { - files.push(f); - - pending--; - if (pending === 0 && !errors) { - // If whatever the user dropped in has finished uploading, send them to - // their uploads. - var uri; - uri = JX.$U(config.browseURI); - var ids = []; - for (var ii = 0; ii < files.length; ii++) { - ids.push(files[ii].getID()); + function install_extra_listeners() { + statics.drop.listen('didBeginDrag', function() { + if (!statics.enabled) { + return; } - uri.setQueryParam('h', ids.join(',')); + JX.Mask.show('global-upload-mask'); + JX.DOM.show(JX.$(config.instructions)); + }); - files = []; + statics.drop.listen('didEndDrag', function() { + if (!statics.enabled) { + return; + } + JX.Mask.hide('global-upload-mask'); + JX.DOM.hide(JX.$(config.instructions)); + }); - uri.go(); - } - }); + statics.drop.listen('willUpload', function() { + if (!statics.enabled) { + return; + } + statics.pending++; + }); + + statics.drop.listen('didUpload', function(f) { + if (!statics.enabled) { + return; + } + statics.files.push(f); + + statics.pending--; + if (statics.pending === 0 && !statics.errors) { + // If whatever the user dropped in has finished uploading, send them to + // their uploads. + var uri; + uri = JX.$U(config.browseURI); + var ids = []; + for (var ii = 0; ii < statics.files.length; ii++) { + ids.push(statics.files[ii].getID()); + } + uri.setQueryParam('h', ids.join(',')); + + statics.files = []; + + uri.go(); + } + }); + + statics.drop.listen('didError', function() { + if (!statics.enabled) { + return; + } + statics.pending--; + statics.errors = true; + }); + } + + statics.init = statics.init || init(); - drop.listen('didError', function() { - pending--; - errors = true; - }); + JX.Stratcom.listen( + 'quicksand-redraw', + null, + function (e) { + e.kill(); - drop.start(); + var data = e.getData(); + var toggle = data.newResponse.globalDragAndDrop; + statics.enabled = toggle; + statics.drop.setIsEnabled(toggle); + }); });