Make inline comment preview and submission mostly work on EditEngine
Summary: Ref T11114. This comments nearly working on EditEngine. Only significant issue I caught is that the "View" link doesn't render properly because it depends on JS which is tricky to hook up. I'll clean that up in a future diff.
Test Plan: {F2279201}
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T11114
Differential Revision: https://secure.phabricator.com/D17116
			
			
This commit is contained in:
		@@ -13,7 +13,7 @@ return array(
 | 
			
		||||
    'core.pkg.js' => '28e8cda8',
 | 
			
		||||
    'darkconsole.pkg.js' => 'e7393ebb',
 | 
			
		||||
    'differential.pkg.css' => 'a4ba74b5',
 | 
			
		||||
    'differential.pkg.js' => '634399e9',
 | 
			
		||||
    'differential.pkg.js' => '40b18f35',
 | 
			
		||||
    'diffusion.pkg.css' => '91c5d3a6',
 | 
			
		||||
    'diffusion.pkg.js' => '84c8f8fd',
 | 
			
		||||
    'favicon.ico' => '30672e08',
 | 
			
		||||
@@ -397,7 +397,7 @@ return array(
 | 
			
		||||
    'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '453c5375',
 | 
			
		||||
    'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => 'd4eecc63',
 | 
			
		||||
    'rsrc/js/application/differential/ChangesetViewManager.js' => 'a2828756',
 | 
			
		||||
    'rsrc/js/application/differential/DifferentialInlineCommentEditor.js' => '64a5550f',
 | 
			
		||||
    'rsrc/js/application/differential/DifferentialInlineCommentEditor.js' => '2e3f9738',
 | 
			
		||||
    'rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js' => 'e10f8e18',
 | 
			
		||||
    'rsrc/js/application/differential/behavior-comment-jump.js' => '4fdb476d',
 | 
			
		||||
    'rsrc/js/application/differential/behavior-comment-preview.js' => 'b064af76',
 | 
			
		||||
@@ -453,7 +453,7 @@ return array(
 | 
			
		||||
    'rsrc/js/application/search/behavior-reorder-profile-menu-items.js' => 'e2e0a072',
 | 
			
		||||
    'rsrc/js/application/search/behavior-reorder-queries.js' => 'e9581f08',
 | 
			
		||||
    'rsrc/js/application/slowvote/behavior-slowvote-embed.js' => '887ad43f',
 | 
			
		||||
    'rsrc/js/application/transactions/behavior-comment-actions.js' => '1be09f3f',
 | 
			
		||||
    'rsrc/js/application/transactions/behavior-comment-actions.js' => 'c23ecb0b',
 | 
			
		||||
    'rsrc/js/application/transactions/behavior-reorder-configs.js' => 'd7a74243',
 | 
			
		||||
    'rsrc/js/application/transactions/behavior-reorder-fields.js' => 'b59e1e96',
 | 
			
		||||
    'rsrc/js/application/transactions/behavior-show-older-transactions.js' => '94c65b72',
 | 
			
		||||
@@ -575,7 +575,7 @@ return array(
 | 
			
		||||
    'd3' => 'a11a5ff2',
 | 
			
		||||
    'differential-changeset-view-css' => 'b158cc46',
 | 
			
		||||
    'differential-core-view-css' => '5b7b8ff4',
 | 
			
		||||
    'differential-inline-comment-editor' => '64a5550f',
 | 
			
		||||
    'differential-inline-comment-editor' => '2e3f9738',
 | 
			
		||||
    'differential-revision-add-comment-css' => 'c47f8c40',
 | 
			
		||||
    'differential-revision-comment-css' => '14b8565a',
 | 
			
		||||
    'differential-revision-history-css' => '0e8eb855',
 | 
			
		||||
@@ -609,7 +609,7 @@ return array(
 | 
			
		||||
    'javelin-behavior-bulk-job-reload' => 'edf8a145',
 | 
			
		||||
    'javelin-behavior-calendar-month-view' => 'fe33e256',
 | 
			
		||||
    'javelin-behavior-choose-control' => '327a00d1',
 | 
			
		||||
    'javelin-behavior-comment-actions' => '1be09f3f',
 | 
			
		||||
    'javelin-behavior-comment-actions' => 'c23ecb0b',
 | 
			
		||||
    'javelin-behavior-config-reorder-fields' => 'b6993408',
 | 
			
		||||
    'javelin-behavior-conpherence-menu' => '7524fcfa',
 | 
			
		||||
    'javelin-behavior-conpherence-participant-pane' => '8604caa8',
 | 
			
		||||
@@ -1083,15 +1083,6 @@ return array(
 | 
			
		||||
      'javelin-request',
 | 
			
		||||
      'javelin-uri',
 | 
			
		||||
    ),
 | 
			
		||||
    '1be09f3f' => array(
 | 
			
		||||
      'javelin-behavior',
 | 
			
		||||
      'javelin-stratcom',
 | 
			
		||||
      'javelin-workflow',
 | 
			
		||||
      'javelin-dom',
 | 
			
		||||
      'phuix-form-control-view',
 | 
			
		||||
      'phuix-icon-view',
 | 
			
		||||
      'javelin-behavior-phabricator-gesture',
 | 
			
		||||
    ),
 | 
			
		||||
    '1def2711' => array(
 | 
			
		||||
      'javelin-install',
 | 
			
		||||
      'javelin-dom',
 | 
			
		||||
@@ -1156,6 +1147,14 @@ return array(
 | 
			
		||||
      'javelin-install',
 | 
			
		||||
      'javelin-event',
 | 
			
		||||
    ),
 | 
			
		||||
    '2e3f9738' => array(
 | 
			
		||||
      'javelin-dom',
 | 
			
		||||
      'javelin-util',
 | 
			
		||||
      'javelin-stratcom',
 | 
			
		||||
      'javelin-install',
 | 
			
		||||
      'javelin-request',
 | 
			
		||||
      'javelin-workflow',
 | 
			
		||||
    ),
 | 
			
		||||
    '2ee659ce' => array(
 | 
			
		||||
      'javelin-install',
 | 
			
		||||
    ),
 | 
			
		||||
@@ -1421,14 +1420,6 @@ return array(
 | 
			
		||||
      'javelin-workflow',
 | 
			
		||||
      'javelin-dom',
 | 
			
		||||
    ),
 | 
			
		||||
    '64a5550f' => array(
 | 
			
		||||
      'javelin-dom',
 | 
			
		||||
      'javelin-util',
 | 
			
		||||
      'javelin-stratcom',
 | 
			
		||||
      'javelin-install',
 | 
			
		||||
      'javelin-request',
 | 
			
		||||
      'javelin-workflow',
 | 
			
		||||
    ),
 | 
			
		||||
    '680ea2c8' => array(
 | 
			
		||||
      'javelin-install',
 | 
			
		||||
      'javelin-dom',
 | 
			
		||||
@@ -1956,6 +1947,15 @@ return array(
 | 
			
		||||
      'javelin-install',
 | 
			
		||||
      'javelin-dom',
 | 
			
		||||
    ),
 | 
			
		||||
    'c23ecb0b' => array(
 | 
			
		||||
      'javelin-behavior',
 | 
			
		||||
      'javelin-stratcom',
 | 
			
		||||
      'javelin-workflow',
 | 
			
		||||
      'javelin-dom',
 | 
			
		||||
      'phuix-form-control-view',
 | 
			
		||||
      'phuix-icon-view',
 | 
			
		||||
      'javelin-behavior-phabricator-gesture',
 | 
			
		||||
    ),
 | 
			
		||||
    'c587b80f' => array(
 | 
			
		||||
      'javelin-install',
 | 
			
		||||
    ),
 | 
			
		||||
 
 | 
			
		||||
@@ -379,7 +379,6 @@ phutil_register_library_map(array(
 | 
			
		||||
    'DifferentialChangesetTwoUpTestRenderer' => 'applications/differential/render/DifferentialChangesetTwoUpTestRenderer.php',
 | 
			
		||||
    'DifferentialChangesetViewController' => 'applications/differential/controller/DifferentialChangesetViewController.php',
 | 
			
		||||
    'DifferentialCloseConduitAPIMethod' => 'applications/differential/conduit/DifferentialCloseConduitAPIMethod.php',
 | 
			
		||||
    'DifferentialCommentPreviewController' => 'applications/differential/controller/DifferentialCommentPreviewController.php',
 | 
			
		||||
    'DifferentialCommitMessageCustomField' => 'applications/differential/field/DifferentialCommitMessageCustomField.php',
 | 
			
		||||
    'DifferentialCommitMessageField' => 'applications/differential/field/DifferentialCommitMessageField.php',
 | 
			
		||||
    'DifferentialCommitMessageParser' => 'applications/differential/parser/DifferentialCommitMessageParser.php',
 | 
			
		||||
@@ -457,7 +456,6 @@ phutil_register_library_map(array(
 | 
			
		||||
    'DifferentialInlineComment' => 'applications/differential/storage/DifferentialInlineComment.php',
 | 
			
		||||
    'DifferentialInlineCommentEditController' => 'applications/differential/controller/DifferentialInlineCommentEditController.php',
 | 
			
		||||
    'DifferentialInlineCommentMailView' => 'applications/differential/mail/DifferentialInlineCommentMailView.php',
 | 
			
		||||
    'DifferentialInlineCommentPreviewController' => 'applications/differential/controller/DifferentialInlineCommentPreviewController.php',
 | 
			
		||||
    'DifferentialInlineCommentQuery' => 'applications/differential/query/DifferentialInlineCommentQuery.php',
 | 
			
		||||
    'DifferentialJIRAIssuesCommitMessageField' => 'applications/differential/field/DifferentialJIRAIssuesCommitMessageField.php',
 | 
			
		||||
    'DifferentialJIRAIssuesField' => 'applications/differential/customfield/DifferentialJIRAIssuesField.php',
 | 
			
		||||
@@ -1641,6 +1639,7 @@ phutil_register_library_map(array(
 | 
			
		||||
    'PHUIDiffGraphViewTestCase' => 'infrastructure/diff/view/__tests__/PHUIDiffGraphViewTestCase.php',
 | 
			
		||||
    'PHUIDiffInlineCommentDetailView' => 'infrastructure/diff/view/PHUIDiffInlineCommentDetailView.php',
 | 
			
		||||
    'PHUIDiffInlineCommentEditView' => 'infrastructure/diff/view/PHUIDiffInlineCommentEditView.php',
 | 
			
		||||
    'PHUIDiffInlineCommentPreviewListView' => 'infrastructure/diff/view/PHUIDiffInlineCommentPreviewListView.php',
 | 
			
		||||
    'PHUIDiffInlineCommentRowScaffold' => 'infrastructure/diff/view/PHUIDiffInlineCommentRowScaffold.php',
 | 
			
		||||
    'PHUIDiffInlineCommentTableScaffold' => 'infrastructure/diff/view/PHUIDiffInlineCommentTableScaffold.php',
 | 
			
		||||
    'PHUIDiffInlineCommentUndoView' => 'infrastructure/diff/view/PHUIDiffInlineCommentUndoView.php',
 | 
			
		||||
@@ -5029,7 +5028,6 @@ phutil_register_library_map(array(
 | 
			
		||||
    'DifferentialChangesetTwoUpTestRenderer' => 'DifferentialChangesetTestRenderer',
 | 
			
		||||
    'DifferentialChangesetViewController' => 'DifferentialController',
 | 
			
		||||
    'DifferentialCloseConduitAPIMethod' => 'DifferentialConduitAPIMethod',
 | 
			
		||||
    'DifferentialCommentPreviewController' => 'DifferentialController',
 | 
			
		||||
    'DifferentialCommitMessageCustomField' => 'DifferentialCommitMessageField',
 | 
			
		||||
    'DifferentialCommitMessageField' => 'Phobject',
 | 
			
		||||
    'DifferentialCommitMessageParser' => 'Phobject',
 | 
			
		||||
@@ -5120,7 +5118,6 @@ phutil_register_library_map(array(
 | 
			
		||||
    ),
 | 
			
		||||
    'DifferentialInlineCommentEditController' => 'PhabricatorInlineCommentController',
 | 
			
		||||
    'DifferentialInlineCommentMailView' => 'DifferentialMailView',
 | 
			
		||||
    'DifferentialInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController',
 | 
			
		||||
    'DifferentialInlineCommentQuery' => 'PhabricatorOffsetPagedQuery',
 | 
			
		||||
    'DifferentialJIRAIssuesCommitMessageField' => 'DifferentialCommitMessageCustomField',
 | 
			
		||||
    'DifferentialJIRAIssuesField' => 'DifferentialStoredCustomField',
 | 
			
		||||
@@ -6484,6 +6481,7 @@ phutil_register_library_map(array(
 | 
			
		||||
    'PHUIDiffGraphViewTestCase' => 'PhabricatorTestCase',
 | 
			
		||||
    'PHUIDiffInlineCommentDetailView' => 'PHUIDiffInlineCommentView',
 | 
			
		||||
    'PHUIDiffInlineCommentEditView' => 'PHUIDiffInlineCommentView',
 | 
			
		||||
    'PHUIDiffInlineCommentPreviewListView' => 'AphrontView',
 | 
			
		||||
    'PHUIDiffInlineCommentRowScaffold' => 'AphrontView',
 | 
			
		||||
    'PHUIDiffInlineCommentTableScaffold' => 'AphrontView',
 | 
			
		||||
    'PHUIDiffInlineCommentUndoView' => 'PHUIDiffInlineCommentView',
 | 
			
		||||
 
 | 
			
		||||
@@ -1,139 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
final class DifferentialCommentPreviewController
 | 
			
		||||
  extends DifferentialController {
 | 
			
		||||
 | 
			
		||||
  public function handleRequest(AphrontRequest $request) {
 | 
			
		||||
    $viewer = $this->getViewer();
 | 
			
		||||
    $id = $request->getURIData('id');
 | 
			
		||||
 | 
			
		||||
    $revision = id(new DifferentialRevisionQuery())
 | 
			
		||||
      ->setViewer($viewer)
 | 
			
		||||
      ->withIDs(array($id))
 | 
			
		||||
      ->executeOne();
 | 
			
		||||
    if (!$revision) {
 | 
			
		||||
      return new Aphront404Response();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $type_comment = PhabricatorTransactions::TYPE_COMMENT;
 | 
			
		||||
    $type_action = DifferentialTransaction::TYPE_ACTION;
 | 
			
		||||
    $type_edge = PhabricatorTransactions::TYPE_EDGE;
 | 
			
		||||
    $type_subscribers = PhabricatorTransactions::TYPE_SUBSCRIBERS;
 | 
			
		||||
 | 
			
		||||
    $xactions = array();
 | 
			
		||||
 | 
			
		||||
    $action = $request->getStr('action');
 | 
			
		||||
    switch ($action) {
 | 
			
		||||
      case DifferentialAction::ACTION_COMMENT:
 | 
			
		||||
      case DifferentialAction::ACTION_ADDREVIEWERS:
 | 
			
		||||
      case DifferentialAction::ACTION_ADDCCS:
 | 
			
		||||
        break;
 | 
			
		||||
      default:
 | 
			
		||||
        $xactions[] = id(new DifferentialTransaction())
 | 
			
		||||
          ->setTransactionType($type_action)
 | 
			
		||||
          ->setNewValue($action);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $edge_reviewer = DifferentialRevisionHasReviewerEdgeType::EDGECONST;
 | 
			
		||||
 | 
			
		||||
    $reviewers = $request->getStrList('reviewers');
 | 
			
		||||
    if (DifferentialAction::allowReviewers($action) && $reviewers) {
 | 
			
		||||
      $faux_edges = array();
 | 
			
		||||
      foreach ($reviewers as $phid) {
 | 
			
		||||
        $faux_edges[$phid] = array(
 | 
			
		||||
          'src' => $revision->getPHID(),
 | 
			
		||||
          'type' => $edge_reviewer,
 | 
			
		||||
          'dst' => $phid,
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      $xactions[] = id(new DifferentialTransaction())
 | 
			
		||||
        ->setTransactionType($type_edge)
 | 
			
		||||
        ->setMetadataValue('edge:type', $edge_reviewer)
 | 
			
		||||
        ->setOldValue(array())
 | 
			
		||||
        ->setNewValue($faux_edges);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $ccs = $request->getStrList('ccs');
 | 
			
		||||
    if ($ccs) {
 | 
			
		||||
      $xactions[] = id(new DifferentialTransaction())
 | 
			
		||||
        ->setTransactionType($type_subscribers)
 | 
			
		||||
        ->setOldValue(array())
 | 
			
		||||
        ->setNewValue(array_fuse($ccs));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Add a comment transaction if there's nothing, so we'll generate a
 | 
			
		||||
    // nonempty result.
 | 
			
		||||
    if (strlen($request->getStr('content')) || !$xactions) {
 | 
			
		||||
      $xactions[] = id(new DifferentialTransaction())
 | 
			
		||||
        ->setTransactionType($type_comment)
 | 
			
		||||
        ->attachComment(
 | 
			
		||||
          id(new ManiphestTransactionComment())
 | 
			
		||||
            ->setContent($request->getStr('content')));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    foreach ($xactions as $xaction) {
 | 
			
		||||
      $xaction->setAuthorPHID($viewer->getPHID());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $engine = new PhabricatorMarkupEngine();
 | 
			
		||||
    $engine->setViewer($request->getUser());
 | 
			
		||||
    foreach ($xactions as $xaction) {
 | 
			
		||||
      if ($xaction->hasComment()) {
 | 
			
		||||
        $engine->addObject(
 | 
			
		||||
          $xaction->getComment(),
 | 
			
		||||
          PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    $engine->process();
 | 
			
		||||
 | 
			
		||||
    $phids = mpull($xactions, 'getRequiredHandlePHIDs');
 | 
			
		||||
    $phids = array_mergev($phids);
 | 
			
		||||
 | 
			
		||||
    $handles = id(new PhabricatorHandleQuery())
 | 
			
		||||
      ->setViewer($viewer)
 | 
			
		||||
      ->withPHIDs($phids)
 | 
			
		||||
      ->execute();
 | 
			
		||||
 | 
			
		||||
    foreach ($xactions as $xaction) {
 | 
			
		||||
      $xaction->setHandles($handles);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $view = id(new DifferentialTransactionView())
 | 
			
		||||
      ->setUser($viewer)
 | 
			
		||||
      ->setTransactions($xactions)
 | 
			
		||||
      ->setIsPreview(true);
 | 
			
		||||
 | 
			
		||||
    $metadata = array(
 | 
			
		||||
      'reviewers' => $reviewers,
 | 
			
		||||
      'ccs' => $ccs,
 | 
			
		||||
    );
 | 
			
		||||
    if ($action != DifferentialAction::ACTION_COMMENT) {
 | 
			
		||||
      $metadata['action'] = $action;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $draft_key = 'differential-comment-'.$id;
 | 
			
		||||
    $draft = id(new PhabricatorDraft())
 | 
			
		||||
      ->setAuthorPHID($viewer->getPHID())
 | 
			
		||||
      ->setDraftKey($draft_key)
 | 
			
		||||
      ->setDraft($request->getStr('content'))
 | 
			
		||||
      ->setMetadata($metadata)
 | 
			
		||||
      ->replaceOrDelete();
 | 
			
		||||
    if ($draft->isDeleted()) {
 | 
			
		||||
      DifferentialDraft::deleteHasDraft(
 | 
			
		||||
        $viewer->getPHID(),
 | 
			
		||||
        $revision->getPHID(),
 | 
			
		||||
        $draft_key);
 | 
			
		||||
    } else {
 | 
			
		||||
      DifferentialDraft::markHasDraft(
 | 
			
		||||
        $viewer->getPHID(),
 | 
			
		||||
        $revision->getPHID(),
 | 
			
		||||
        $draft_key);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return id(new AphrontAjaxResponse())
 | 
			
		||||
      ->setContent((string)phutil_implode_html('', $view->buildEvents()));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,44 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
final class DifferentialInlineCommentPreviewController
 | 
			
		||||
extends PhabricatorInlineCommentPreviewController {
 | 
			
		||||
 | 
			
		||||
  protected function loadInlineComments() {
 | 
			
		||||
    $viewer = $this->getViewer();
 | 
			
		||||
 | 
			
		||||
    $revision = id(new DifferentialRevisionQuery())
 | 
			
		||||
      ->setViewer($viewer)
 | 
			
		||||
      ->withIDs(array($this->getRevisionID()))
 | 
			
		||||
      ->executeOne();
 | 
			
		||||
    if (!$revision) {
 | 
			
		||||
      return array();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return id(new DifferentialInlineCommentQuery())
 | 
			
		||||
      ->setViewer($this->getViewer())
 | 
			
		||||
      ->withDrafts(true)
 | 
			
		||||
      ->withAuthorPHIDs(array($viewer->getPHID()))
 | 
			
		||||
      ->withRevisionPHIDs(array($revision->getPHID()))
 | 
			
		||||
      ->needHidden(true)
 | 
			
		||||
      ->execute();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function loadObjectOwnerPHID() {
 | 
			
		||||
    $viewer = $this->getViewer();
 | 
			
		||||
 | 
			
		||||
    $revision = id(new DifferentialRevisionQuery())
 | 
			
		||||
      ->setViewer($viewer)
 | 
			
		||||
      ->withIDs(array($this->getRevisionID()))
 | 
			
		||||
      ->executeOne();
 | 
			
		||||
    if (!$revision) {
 | 
			
		||||
      return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return $revision->getAuthorPHID();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  private function getRevisionID() {
 | 
			
		||||
    return $this->getRequest()->getURIData('id');
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -247,4 +247,52 @@ final class DifferentialRevisionEditEngine
 | 
			
		||||
    return isset($fields[$key]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function newAutomaticCommentTransactions($object) {
 | 
			
		||||
    $viewer = $this->getViewer();
 | 
			
		||||
    $xactions = array();
 | 
			
		||||
 | 
			
		||||
    $inlines = DifferentialTransactionQuery::loadUnsubmittedInlineComments(
 | 
			
		||||
      $viewer,
 | 
			
		||||
      $object);
 | 
			
		||||
    $inlines = msort($inlines, 'getID');
 | 
			
		||||
 | 
			
		||||
    foreach ($inlines as $inline) {
 | 
			
		||||
      $xactions[] = id(new DifferentialTransaction())
 | 
			
		||||
        ->setTransactionType(DifferentialTransaction::TYPE_INLINE)
 | 
			
		||||
        ->attachComment($inline);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return $xactions;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function newCommentPreviewContent($object, array $xactions) {
 | 
			
		||||
    $viewer = $this->getViewer();
 | 
			
		||||
    $type_inline = DifferentialTransaction::TYPE_INLINE;
 | 
			
		||||
 | 
			
		||||
    $inlines = array();
 | 
			
		||||
    foreach ($xactions as $xaction) {
 | 
			
		||||
      if ($xaction->getTransactionType() === $type_inline) {
 | 
			
		||||
        $inlines[] = $xaction->getComment();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $content = array();
 | 
			
		||||
 | 
			
		||||
    if ($inlines) {
 | 
			
		||||
      $inline_preview = id(new PHUIDiffInlineCommentPreviewListView())
 | 
			
		||||
        ->setViewer($viewer)
 | 
			
		||||
        ->setInlineComments($inlines);
 | 
			
		||||
 | 
			
		||||
      $content[] = phutil_tag(
 | 
			
		||||
        'div',
 | 
			
		||||
        array(
 | 
			
		||||
          'id' => 'inline-comment-preview',
 | 
			
		||||
        ),
 | 
			
		||||
        $inline_preview);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return $content;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,7 @@ final class DifferentialTransactionComment
 | 
			
		||||
 | 
			
		||||
  private $replyToComment = self::ATTACHABLE;
 | 
			
		||||
  private $isHidden = self::ATTACHABLE;
 | 
			
		||||
  private $changeset = self::ATTACHABLE;
 | 
			
		||||
 | 
			
		||||
  public function getApplicationTransactionObject() {
 | 
			
		||||
    return new DifferentialTransaction();
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
final class DifferentialTransactionView
 | 
			
		||||
  extends PhabricatorApplicationTransactionView {
 | 
			
		||||
 | 
			
		||||
  private $changesets;
 | 
			
		||||
  private $changesets = array();
 | 
			
		||||
  private $revision;
 | 
			
		||||
  private $rightDiff;
 | 
			
		||||
  private $leftDiff;
 | 
			
		||||
@@ -93,6 +93,13 @@ final class DifferentialTransactionView
 | 
			
		||||
      $out[] = parent::renderTransactionContent($xaction);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we're rendering a preview, we show the inline comments in a separate
 | 
			
		||||
    // section underneath the main transaction preview, so we skip rendering
 | 
			
		||||
    // them in the preview body.
 | 
			
		||||
    if ($this->getIsPreview()) {
 | 
			
		||||
      return $out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!$group) {
 | 
			
		||||
      return $out;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1783,6 +1783,11 @@ abstract class PhabricatorEditEngine
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $auto_xactions = $this->newAutomaticCommentTransactions($object);
 | 
			
		||||
    foreach ($auto_xactions as $xaction) {
 | 
			
		||||
      $xactions[] = $xaction;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (strlen($comment_text) || !$xactions) {
 | 
			
		||||
      $xactions[] = id(clone $template)
 | 
			
		||||
        ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
 | 
			
		||||
@@ -1814,10 +1819,13 @@ abstract class PhabricatorEditEngine
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ($request->isAjax() && $is_preview) {
 | 
			
		||||
      $preview_content = $this->newCommentPreviewContent($object, $xactions);
 | 
			
		||||
 | 
			
		||||
      return id(new PhabricatorApplicationTransactionResponse())
 | 
			
		||||
        ->setViewer($viewer)
 | 
			
		||||
        ->setTransactions($xactions)
 | 
			
		||||
        ->setIsPreview($is_preview);
 | 
			
		||||
        ->setIsPreview($is_preview)
 | 
			
		||||
        ->setPreviewContent($preview_content);
 | 
			
		||||
    } else {
 | 
			
		||||
      return id(new AphrontRedirectResponse())
 | 
			
		||||
        ->setURI($view_uri);
 | 
			
		||||
@@ -2164,6 +2172,14 @@ abstract class PhabricatorEditEngine
 | 
			
		||||
    return array();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function newAutomaticCommentTransactions($object) {
 | 
			
		||||
    return array();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function newCommentPreviewContent($object, array $xactions) {
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -(  Form Pages  )--------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@ final class PhabricatorApplicationTransactionResponse
 | 
			
		||||
  private $transactions;
 | 
			
		||||
  private $isPreview;
 | 
			
		||||
  private $transactionView;
 | 
			
		||||
  private $previewContent;
 | 
			
		||||
 | 
			
		||||
  public function setTransactionView($transaction_view) {
 | 
			
		||||
    $this->transactionView = $transaction_view;
 | 
			
		||||
@@ -46,6 +47,15 @@ final class PhabricatorApplicationTransactionResponse
 | 
			
		||||
    return $this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function setPreviewContent($preview_content) {
 | 
			
		||||
    $this->previewContent = $preview_content;
 | 
			
		||||
    return $this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function getPreviewContent() {
 | 
			
		||||
    return $this->previewContent;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function reduceProxyResponse() {
 | 
			
		||||
    if ($this->transactionView) {
 | 
			
		||||
      $view = $this->transactionView;
 | 
			
		||||
@@ -75,7 +85,8 @@ final class PhabricatorApplicationTransactionResponse
 | 
			
		||||
 | 
			
		||||
    $content = array(
 | 
			
		||||
      'xactions' => $xactions,
 | 
			
		||||
      'spacer'   => PHUITimelineView::renderSpacer(),
 | 
			
		||||
      'spacer' => PHUITimelineView::renderSpacer(),
 | 
			
		||||
      'previewContent' => hsprintf('%s', $this->getPreviewContent()),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return $this->getProxy()->setContent($content);
 | 
			
		||||
 
 | 
			
		||||
@@ -55,6 +55,10 @@ class PhabricatorApplicationTransactionView extends AphrontView {
 | 
			
		||||
    return $this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function getIsPreview() {
 | 
			
		||||
    return $this->isPreview;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function setShowEditActions($show_edit_actions) {
 | 
			
		||||
    $this->showEditActions = $show_edit_actions;
 | 
			
		||||
    return $this;
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,67 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
final class PHUIDiffInlineCommentPreviewListView
 | 
			
		||||
  extends AphrontView {
 | 
			
		||||
 | 
			
		||||
  private $inlineComments = array();
 | 
			
		||||
  private $ownerPHID;
 | 
			
		||||
 | 
			
		||||
  public function setInlineComments(array $comments) {
 | 
			
		||||
    assert_instances_of($comments, 'PhabricatorApplicationTransactionComment');
 | 
			
		||||
    $this->inlineComments = $comments;
 | 
			
		||||
    return $this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function getInlineComments() {
 | 
			
		||||
    return $this->inlineComments;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function setOwnerPHID($owner_phid) {
 | 
			
		||||
    $this->ownerPHID = $owner_phid;
 | 
			
		||||
    return $this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function getOwnerPHID() {
 | 
			
		||||
    return $this->ownerPHID;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function render() {
 | 
			
		||||
    $viewer = $this->getViewer();
 | 
			
		||||
 | 
			
		||||
    $inlines = $this->getInlineComments();
 | 
			
		||||
    foreach ($inlines as $key => $inline) {
 | 
			
		||||
      $inlines[$key] = DifferentialInlineComment::newFromModernComment(
 | 
			
		||||
        $inline);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $engine = new PhabricatorMarkupEngine();
 | 
			
		||||
    $engine->setViewer($viewer);
 | 
			
		||||
    foreach ($inlines as $inline) {
 | 
			
		||||
      $engine->addObject(
 | 
			
		||||
        $inline,
 | 
			
		||||
        PhabricatorInlineCommentInterface::MARKUP_FIELD_BODY);
 | 
			
		||||
    }
 | 
			
		||||
    $engine->process();
 | 
			
		||||
 | 
			
		||||
    $owner_phid = $this->getOwnerPHID();
 | 
			
		||||
 | 
			
		||||
    $handles = $viewer->loadHandles(array($viewer->getPHID()));
 | 
			
		||||
    $handles = iterator_to_array($handles);
 | 
			
		||||
 | 
			
		||||
    $views = array();
 | 
			
		||||
    foreach ($inlines as $inline) {
 | 
			
		||||
      $views[] = id(new PHUIDiffInlineCommentDetailView())
 | 
			
		||||
        ->setUser($viewer)
 | 
			
		||||
        ->setInlineComment($inline)
 | 
			
		||||
        ->setMarkupEngine($engine)
 | 
			
		||||
        ->setHandles($handles)
 | 
			
		||||
        ->setEditable(false)
 | 
			
		||||
        ->setPreview(true)
 | 
			
		||||
        ->setCanMarkDone(false)
 | 
			
		||||
        ->setObjectOwnerPHID($owner_phid);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return $views;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -183,7 +183,7 @@ JX.install('DifferentialInlineCommentEditor', {
 | 
			
		||||
 | 
			
		||||
      this._completed = true;
 | 
			
		||||
 | 
			
		||||
      JX.Stratcom.invoke('differential-inline-comment-update');
 | 
			
		||||
      this._didUpdate();
 | 
			
		||||
      this.invoke('done');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -335,7 +335,15 @@ JX.install('DifferentialInlineCommentEditor', {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _didUpdate: function() {
 | 
			
		||||
      JX.Stratcom.invoke('differential-inline-comment-update');
 | 
			
		||||
      // After making changes to inline comments, refresh the transaction
 | 
			
		||||
      // preview at the bottom of the page.
 | 
			
		||||
 | 
			
		||||
      // TODO: This isn't the cleanest way to find the preview form, but
 | 
			
		||||
      // rendering no longer has direct access to it.
 | 
			
		||||
      var forms = JX.DOM.scry(document.body, 'form', 'transaction-append');
 | 
			
		||||
      if (forms.length) {
 | 
			
		||||
        JX.DOM.invoke(forms[0], 'shouldRefresh');
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  },
 | 
			
		||||
 
 | 
			
		||||
@@ -149,7 +149,10 @@ JX.behavior('comment-actions', function(config) {
 | 
			
		||||
    } else {
 | 
			
		||||
      JX.DOM.setContent(
 | 
			
		||||
        JX.$(config.timelineID),
 | 
			
		||||
        JX.$H(response.xactions.join('')));
 | 
			
		||||
        [
 | 
			
		||||
          JX.$H(response.xactions.join('')),
 | 
			
		||||
          JX.$H(response.previewContent)
 | 
			
		||||
        ]);
 | 
			
		||||
      JX.DOM.show(panel);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user