From aa2089ba68045617a42d6df6ab5e64974cbe8c33 Mon Sep 17 00:00:00 2001 From: epriestley Date: Sat, 26 Dec 2015 13:00:01 -0800 Subject: [PATCH] Support field previews in EditEngine Summary: Ref T10004. This primarily supports moving Phame to EditEngine. Test Plan: {F1045166} Reviewers: chad Reviewed By: chad Maniphest Tasks: T10004 Differential Revision: https://secure.phabricator.com/D14887 --- resources/celerity/map.php | 40 +++++++++---------- .../PhabricatorManiphestApplication.php | 7 ---- .../maniphest/editor/ManiphestEditEngine.php | 5 ++- ...onTransactionRemarkupPreviewController.php | 4 +- .../editengine/PhabricatorEditEngine.php | 25 +++++++++++- .../editfield/PhabricatorEditField.php | 22 ++++++++++ .../behavior-phabricator-remarkup-assist.js | 2 +- .../rsrc/js/core/behavior-remarkup-preview.js | 14 ++++++- 8 files changed, 85 insertions(+), 34 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index d09165b13a..73daecb1fd 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -8,7 +8,7 @@ return array( 'names' => array( 'core.pkg.css' => 'a419cf4b', - 'core.pkg.js' => '400453e4', + 'core.pkg.js' => '57dff7df', 'darkconsole.pkg.js' => 'e7393ebb', 'differential.pkg.css' => '2de124c9', 'differential.pkg.js' => '64e69521', @@ -487,9 +487,9 @@ return array( 'rsrc/js/core/behavior-object-selector.js' => '49b73b36', 'rsrc/js/core/behavior-oncopy.js' => '2926fff2', 'rsrc/js/core/behavior-phabricator-nav.js' => '56a1ca03', - 'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => 'ecddcbe2', + 'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => 'b60b6d9b', 'rsrc/js/core/behavior-refresh-csrf.js' => 'ab2f381b', - 'rsrc/js/core/behavior-remarkup-preview.js' => 'f7379f45', + 'rsrc/js/core/behavior-remarkup-preview.js' => '4b700e9e', 'rsrc/js/core/behavior-reorder-applications.js' => '76b9fc3e', 'rsrc/js/core/behavior-reveal-content.js' => '60821bc7', 'rsrc/js/core/behavior-scrollbar.js' => '834a1173', @@ -640,7 +640,7 @@ return array( 'javelin-behavior-phabricator-notification-example' => '8ce821c5', 'javelin-behavior-phabricator-object-selector' => '49b73b36', 'javelin-behavior-phabricator-oncopy' => '2926fff2', - 'javelin-behavior-phabricator-remarkup-assist' => 'ecddcbe2', + 'javelin-behavior-phabricator-remarkup-assist' => 'b60b6d9b', 'javelin-behavior-phabricator-reveal-content' => '60821bc7', 'javelin-behavior-phabricator-search-typeahead' => '048330fa', 'javelin-behavior-phabricator-show-older-transactions' => 'dbbf48b6', @@ -662,7 +662,7 @@ return array( 'javelin-behavior-releeph-preview-branch' => 'b2b4fbaf', 'javelin-behavior-releeph-request-state-change' => 'a0b57eb8', 'javelin-behavior-releeph-request-typeahead' => 'de2e896f', - 'javelin-behavior-remarkup-preview' => 'f7379f45', + 'javelin-behavior-remarkup-preview' => '4b700e9e', 'javelin-behavior-reorder-applications' => '76b9fc3e', 'javelin-behavior-reorder-columns' => 'e1d25dfb', 'javelin-behavior-repository-crossreference' => 'e5339c43', @@ -1125,6 +1125,12 @@ return array( 'javelin-request', 'javelin-util', ), + '4b700e9e' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-util', + 'phabricator-shaped-request', + ), '4e3e79a6' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1721,6 +1727,15 @@ return array( 'javelin-dom', 'javelin-util', ), + 'b60b6d9b' => array( + 'javelin-behavior', + 'javelin-stratcom', + 'javelin-dom', + 'phabricator-phtize', + 'phabricator-textareautils', + 'javelin-workflow', + 'javelin-vector', + ), 'b65559c0' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1960,15 +1975,6 @@ return array( 'phabricator-phtize', 'javelin-dom', ), - 'ecddcbe2' => array( - 'javelin-behavior', - 'javelin-stratcom', - 'javelin-dom', - 'phabricator-phtize', - 'phabricator-textareautils', - 'javelin-workflow', - 'javelin-vector', - ), 'edd1ba66' => array( 'javelin-behavior', 'javelin-stratcom', @@ -2005,12 +2011,6 @@ return array( 'javelin-util', 'javelin-reactor', ), - 'f7379f45' => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-util', - 'phabricator-shaped-request', - ), 'f7fc67ec' => array( 'javelin-install', 'javelin-typeahead', diff --git a/src/applications/maniphest/application/PhabricatorManiphestApplication.php b/src/applications/maniphest/application/PhabricatorManiphestApplication.php index c0d0a4d7ef..3fcbbf49f0 100644 --- a/src/applications/maniphest/application/PhabricatorManiphestApplication.php +++ b/src/applications/maniphest/application/PhabricatorManiphestApplication.php @@ -52,13 +52,6 @@ final class PhabricatorManiphestApplication extends PhabricatorApplication { 'task/' => array( $this->getEditRoutePattern('edit/') => 'ManiphestTaskEditController', - 'descriptionpreview/' - => 'PhabricatorMarkupPreviewController', - ), - 'transaction/' => array( - 'save/' => 'ManiphestTransactionSaveController', - 'preview/(?P[1-9]\d*)/' - => 'ManiphestTransactionPreviewController', ), 'export/(?P[^/]+)/' => 'ManiphestExportController', 'subpriority/' => 'ManiphestSubpriorityController', diff --git a/src/applications/maniphest/editor/ManiphestEditEngine.php b/src/applications/maniphest/editor/ManiphestEditEngine.php index aac21ea7ac..b7e3cee965 100644 --- a/src/applications/maniphest/editor/ManiphestEditEngine.php +++ b/src/applications/maniphest/editor/ManiphestEditEngine.php @@ -156,7 +156,10 @@ final class ManiphestEditEngine ->setConduitDescription(pht('Update the task description.')) ->setConduitTypeDescription(pht('New task description.')) ->setTransactionType(ManiphestTransaction::TYPE_DESCRIPTION) - ->setValue($object->getDescription()), + ->setValue($object->getDescription()) + ->setPreviewPanel( + id(new PHUIRemarkupPreviewPanel()) + ->setHeader(pht('Description Preview'))), ); } diff --git a/src/applications/transactions/controller/PhabricatorApplicationTransactionRemarkupPreviewController.php b/src/applications/transactions/controller/PhabricatorApplicationTransactionRemarkupPreviewController.php index 4ba8345d5c..2714be02c4 100644 --- a/src/applications/transactions/controller/PhabricatorApplicationTransactionRemarkupPreviewController.php +++ b/src/applications/transactions/controller/PhabricatorApplicationTransactionRemarkupPreviewController.php @@ -10,9 +10,9 @@ final class PhabricatorApplicationTransactionRemarkupPreviewController public function handleRequest(AphrontRequest $request) { $viewer = $this->getViewer(); - $corpus = $request->getStr('corpus'); + $text = $request->getStr('text'); - $remarkup = new PHUIRemarkupView($viewer, $corpus); + $remarkup = new PHUIRemarkupView($viewer, $text); $content = array( 'content' => hsprintf('%s', $remarkup), diff --git a/src/applications/transactions/editengine/PhabricatorEditEngine.php b/src/applications/transactions/editengine/PhabricatorEditEngine.php index 2e96e60dd0..041bb05393 100644 --- a/src/applications/transactions/editengine/PhabricatorEditEngine.php +++ b/src/applications/transactions/editengine/PhabricatorEditEngine.php @@ -962,6 +962,28 @@ abstract class PhabricatorEditEngine $header_text = $this->getObjectEditTitleText($object); } + $show_preview = !$request->isAjax(); + + if ($show_preview) { + $previews = array(); + foreach ($fields as $field) { + $preview = $field->getPreviewPanel(); + if (!$preview) { + continue; + } + + $control_id = $field->getControlID(); + + $preview + ->setControlID($control_id) + ->setPreviewURI('/transactions/remarkuppreview/'); + + $previews[] = $preview; + } + } else { + $previews = array(); + } + $form = $this->buildEditForm($object, $fields); if ($request->isAjax()) { @@ -998,7 +1020,8 @@ abstract class PhabricatorEditEngine return $controller->newPage() ->setTitle($header_text) ->setCrumbs($crumbs) - ->appendChild($box); + ->appendChild($box) + ->appendChild($previews); } protected function newEditResponse( diff --git a/src/applications/transactions/editfield/PhabricatorEditField.php b/src/applications/transactions/editfield/PhabricatorEditField.php index 9d1b976299..1216370819 100644 --- a/src/applications/transactions/editfield/PhabricatorEditField.php +++ b/src/applications/transactions/editfield/PhabricatorEditField.php @@ -14,6 +14,8 @@ abstract class PhabricatorEditField extends Phobject { private $metadata = array(); private $editTypeKey; private $isRequired; + private $previewPanel; + private $controlID; private $description; private $conduitDescription; @@ -251,6 +253,15 @@ abstract class PhabricatorEditField extends Phobject { return $this->commentActionValue; } + public function setPreviewPanel(PHUIRemarkupPreviewPanel $preview_panel) { + $this->previewPanel = $preview_panel; + return $this; + } + + public function getPreviewPanel() { + return $this->previewPanel; + } + protected function newControl() { throw new PhutilMethodNotImplementedException(); } @@ -285,6 +296,13 @@ abstract class PhabricatorEditField extends Phobject { return $control; } + public function getControlID() { + if (!$this->controlID) { + $this->controlID = celerity_generate_unique_node_id(); + } + return $this->controlID; + } + protected function renderControl() { $control = $this->buildControl(); if ($control === null) { @@ -308,6 +326,10 @@ abstract class PhabricatorEditField extends Phobject { $control->setDisabled($disabled); + if ($this->controlID) { + $control->setID($this->controlID); + } + return $control; } diff --git a/webroot/rsrc/js/core/behavior-phabricator-remarkup-assist.js b/webroot/rsrc/js/core/behavior-phabricator-remarkup-assist.js index 293c44ed9b..9dabffeb10 100644 --- a/webroot/rsrc/js/core/behavior-phabricator-remarkup-assist.js +++ b/webroot/rsrc/js/core/behavior-phabricator-remarkup-assist.js @@ -254,7 +254,7 @@ JX.behavior('phabricator-remarkup-assist', function(config) { var value = area.value; var data = { - corpus: value + text: value }; var onupdate = function(r) { diff --git a/webroot/rsrc/js/core/behavior-remarkup-preview.js b/webroot/rsrc/js/core/behavior-remarkup-preview.js index f703e56266..4e79c48b59 100644 --- a/webroot/rsrc/js/core/behavior-remarkup-preview.js +++ b/webroot/rsrc/js/core/behavior-remarkup-preview.js @@ -8,16 +8,26 @@ JX.behavior('remarkup-preview', function(config) { + // Don't bother with any of this on mobile. + if (JX.Device.getDevice() !== 'desktop') { + return; + } + var preview = JX.$(config.previewID); var control = JX.$(config.controlID); var callback = function(r) { - JX.DOM.setContent(preview, JX.$H(r)); + // This currently accepts responses from two controllers: + // Old: PhabricatorMarkupPreviewController + // New: PhabricatorApplicationTransactionRemarkupPreviewController + // TODO: Swap everything to just the new controller. + + JX.DOM.setContent(preview, JX.$H(r.content || r)); }; var getdata = function() { return { - text : control.value + text: control.value }; };