@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Move Differential to EditEngine comments

Summary:
Ref T11114. This is a transitional change that breaks a bunch of stuff. I'll hold it until I've restored features.

This stuff works:

- Commenting.
- Subscribers/tags/reviewers.
- Pinning.
- Drafts.

This stuff does not work yet:

- Preview of inline comments.
- Probably submitting inlines, whatsoever.
- Comment-area warnings like "There are failing tests."
- All meaningful actions (accept, reject, etc).

Test Plan: Commented on a revision. Essentially nothing else works yet.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T11114

Differential Revision: https://secure.phabricator.com/D17106

+8 -535
-4
src/__phutil_library_map__.php
··· 348 348 'DarkConsoleXHProfPluginAPI' => 'applications/console/plugin/xhprof/DarkConsoleXHProfPluginAPI.php', 349 349 'DifferentialAction' => 'applications/differential/constants/DifferentialAction.php', 350 350 'DifferentialActionEmailCommand' => 'applications/differential/command/DifferentialActionEmailCommand.php', 351 - 'DifferentialAddCommentView' => 'applications/differential/view/DifferentialAddCommentView.php', 352 351 'DifferentialAdjustmentMapTestCase' => 'applications/differential/storage/__tests__/DifferentialAdjustmentMapTestCase.php', 353 352 'DifferentialAffectedPath' => 'applications/differential/storage/DifferentialAffectedPath.php', 354 353 'DifferentialAsanaRepresentationField' => 'applications/differential/customfield/DifferentialAsanaRepresentationField.php', ··· 381 380 'DifferentialChangesetViewController' => 'applications/differential/controller/DifferentialChangesetViewController.php', 382 381 'DifferentialCloseConduitAPIMethod' => 'applications/differential/conduit/DifferentialCloseConduitAPIMethod.php', 383 382 'DifferentialCommentPreviewController' => 'applications/differential/controller/DifferentialCommentPreviewController.php', 384 - 'DifferentialCommentSaveController' => 'applications/differential/controller/DifferentialCommentSaveController.php', 385 383 'DifferentialCommitMessageCustomField' => 'applications/differential/field/DifferentialCommitMessageCustomField.php', 386 384 'DifferentialCommitMessageField' => 'applications/differential/field/DifferentialCommitMessageField.php', 387 385 'DifferentialCommitMessageParser' => 'applications/differential/parser/DifferentialCommitMessageParser.php', ··· 4982 4980 'DarkConsoleXHProfPluginAPI' => 'Phobject', 4983 4981 'DifferentialAction' => 'Phobject', 4984 4982 'DifferentialActionEmailCommand' => 'MetaMTAEmailTransactionCommand', 4985 - 'DifferentialAddCommentView' => 'AphrontView', 4986 4983 'DifferentialAdjustmentMapTestCase' => 'PhutilTestCase', 4987 4984 'DifferentialAffectedPath' => 'DifferentialDAO', 4988 4985 'DifferentialAsanaRepresentationField' => 'DifferentialCustomField', ··· 5018 5015 'DifferentialChangesetViewController' => 'DifferentialController', 5019 5016 'DifferentialCloseConduitAPIMethod' => 'DifferentialConduitAPIMethod', 5020 5017 'DifferentialCommentPreviewController' => 'DifferentialController', 5021 - 'DifferentialCommentSaveController' => 'DifferentialController', 5022 5018 'DifferentialCommitMessageCustomField' => 'DifferentialCommitMessageField', 5023 5019 'DifferentialCommitMessageField' => 'Phobject', 5024 5020 'DifferentialCommitMessageParser' => 'Phobject',
-143
src/applications/differential/controller/DifferentialCommentSaveController.php
··· 1 - <?php 2 - 3 - final class DifferentialCommentSaveController 4 - extends DifferentialController { 5 - 6 - public function handleRequest(AphrontRequest $request) { 7 - $viewer = $this->getViewer(); 8 - $id = $request->getURIData('id'); 9 - 10 - if (!$request->isFormPost()) { 11 - return new Aphront400Response(); 12 - } 13 - 14 - $revision = id(new DifferentialRevisionQuery()) 15 - ->setViewer($viewer) 16 - ->withIDs(array($id)) 17 - ->needReviewerStatus(true) 18 - ->needReviewerAuthority(true) 19 - ->executeOne(); 20 - if (!$revision) { 21 - return new Aphront404Response(); 22 - } 23 - 24 - $type_action = DifferentialTransaction::TYPE_ACTION; 25 - $type_subscribers = PhabricatorTransactions::TYPE_SUBSCRIBERS; 26 - $type_edge = PhabricatorTransactions::TYPE_EDGE; 27 - $type_comment = PhabricatorTransactions::TYPE_COMMENT; 28 - $type_inline = DifferentialTransaction::TYPE_INLINE; 29 - 30 - $edge_reviewer = DifferentialRevisionHasReviewerEdgeType::EDGECONST; 31 - 32 - $xactions = array(); 33 - 34 - $action = $request->getStr('action'); 35 - switch ($action) { 36 - case DifferentialAction::ACTION_COMMENT: 37 - case DifferentialAction::ACTION_ADDREVIEWERS: 38 - case DifferentialAction::ACTION_ADDCCS: 39 - // These transaction types have no direct effect, they just 40 - // accompany other transaction types which can have an effect. 41 - break; 42 - default: 43 - $xactions[] = id(new DifferentialTransaction()) 44 - ->setTransactionType($type_action) 45 - ->setNewValue($request->getStr('action')); 46 - break; 47 - } 48 - 49 - $ccs = $request->getArr('ccs'); 50 - if ($ccs) { 51 - $xactions[] = id(new DifferentialTransaction()) 52 - ->setTransactionType($type_subscribers) 53 - ->setNewValue(array('+' => $ccs)); 54 - } 55 - 56 - $current_reviewers = mpull( 57 - $revision->getReviewerStatus(), 58 - null, 59 - 'getReviewerPHID'); 60 - 61 - $reviewer_edges = array(); 62 - $add_reviewers = $request->getArr('reviewers'); 63 - foreach ($add_reviewers as $reviewer_phid) { 64 - if (isset($current_reviewers[$reviewer_phid])) { 65 - continue; 66 - } 67 - $reviewer = new DifferentialReviewerProxy( 68 - $reviewer_phid, 69 - array( 70 - 'status' => DifferentialReviewerStatus::STATUS_ADDED, 71 - )); 72 - $reviewer_edges[$reviewer_phid] = array( 73 - 'data' => $reviewer->getEdgeData(), 74 - ); 75 - } 76 - 77 - if ($add_reviewers) { 78 - $xactions[] = id(new DifferentialTransaction()) 79 - ->setTransactionType($type_edge) 80 - ->setMetadataValue('edge:type', $edge_reviewer) 81 - ->setNewValue(array('+' => $reviewer_edges)); 82 - } 83 - 84 - $inlines = DifferentialTransactionQuery::loadUnsubmittedInlineComments( 85 - $viewer, 86 - $revision); 87 - foreach ($inlines as $inline) { 88 - $xactions[] = id(new DifferentialTransaction()) 89 - ->setTransactionType($type_inline) 90 - ->attachComment($inline); 91 - } 92 - 93 - // NOTE: If there are no other transactions, add an empty comment 94 - // transaction so that we'll raise a more user-friendly error message, 95 - // to the effect of "you can not post an empty comment". 96 - $no_xactions = !$xactions; 97 - 98 - $comment = $request->getStr('comment'); 99 - if (strlen($comment) || $no_xactions) { 100 - $xactions[] = id(new DifferentialTransaction()) 101 - ->setTransactionType($type_comment) 102 - ->attachComment( 103 - id(new DifferentialTransactionComment()) 104 - ->setRevisionPHID($revision->getPHID()) 105 - ->setContent($comment)); 106 - } 107 - 108 - 109 - $editor = id(new DifferentialTransactionEditor()) 110 - ->setActor($viewer) 111 - ->setContentSourceFromRequest($request) 112 - ->setContinueOnMissingFields(true) 113 - ->setContinueOnNoEffect($request->isContinueRequest()); 114 - 115 - $revision_uri = '/D'.$revision->getID(); 116 - 117 - try { 118 - $editor->applyTransactions($revision, $xactions); 119 - } catch (PhabricatorApplicationTransactionNoEffectException $ex) { 120 - return id(new PhabricatorApplicationTransactionNoEffectResponse()) 121 - ->setCancelURI($revision_uri) 122 - ->setException($ex); 123 - } catch (PhabricatorApplicationTransactionValidationException $ex) { 124 - return id(new PhabricatorApplicationTransactionValidationResponse()) 125 - ->setCancelURI($revision_uri) 126 - ->setException($ex); 127 - } 128 - 129 - $user = $request->getUser(); 130 - $draft = id(new PhabricatorDraft())->loadOneWhere( 131 - 'authorPHID = %s AND draftKey = %s', 132 - $user->getPHID(), 133 - 'differential-comment-'.$revision->getID()); 134 - if ($draft) { 135 - $draft->delete(); 136 - } 137 - DifferentialDraft::deleteAllDrafts($user->getPHID(), $revision->getPHID()); 138 - 139 - return id(new AphrontRedirectResponse()) 140 - ->setURI('/D'.$revision->getID()); 141 - } 142 - 143 - }
+3 -187
src/applications/differential/controller/DifferentialRevisionViewController.php
··· 390 390 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 391 391 ->addTabGroup($tab_group); 392 392 393 - $comment_form = null; 394 - if (!$viewer_is_anonymous) { 395 - $comment_form = $this->buildCommentForm($revision, $field_list); 396 - } 397 - 398 393 $signatures = DifferentialRequiredSignaturesField::loadForRevision( 399 394 $revision); 400 395 $missing_signatures = false; ··· 426 421 ); 427 422 } 428 423 429 - if ($comment_form) { 430 - $footer[] = $comment_form; 431 - } else { 432 - // TODO: For now, just use this to get "Login to Comment". 433 - $footer[] = id(new PhabricatorApplicationTransactionCommentView()) 434 - ->setUser($viewer) 435 - ->setRequestURI($request->getRequestURI()); 436 - } 424 + $footer[] = id(new DifferentialRevisionEditEngine()) 425 + ->setViewer($viewer) 426 + ->buildEditEngineCommentView($revision); 437 427 438 428 $object_id = 'D'.$revision->getID(); 439 429 $operations_box = $this->buildOperationsBox($revision); ··· 458 448 ->build($changesets); 459 449 } 460 450 461 - // Haunt Mode 462 - $pane_id = celerity_generate_unique_node_id(); 463 - Javelin::initBehavior( 464 - 'differential-keyboard-navigation', 465 - array( 466 - 'haunt' => $pane_id, 467 - )); 468 451 Javelin::initBehavior('differential-user-select'); 469 452 470 453 $view = id(new PHUITwoColumnView()) 471 454 ->setHeader($header) 472 455 ->setSubheader($subheader) 473 456 ->setCurtain($curtain) 474 - ->setID($pane_id) 475 457 ->setMainColumn(array( 476 458 $operations_box, 477 459 $info_view, ··· 611 593 } 612 594 613 595 return $curtain; 614 - } 615 - 616 - private function buildCommentForm( 617 - DifferentialRevision $revision, 618 - $field_list) { 619 - 620 - $viewer = $this->getViewer(); 621 - 622 - $draft = id(new PhabricatorDraft())->loadOneWhere( 623 - 'authorPHID = %s AND draftKey = %s', 624 - $viewer->getPHID(), 625 - 'differential-comment-'.$revision->getID()); 626 - 627 - $reviewers = array(); 628 - $ccs = array(); 629 - if ($draft) { 630 - $reviewers = idx($draft->getMetadata(), 'reviewers', array()); 631 - $ccs = idx($draft->getMetadata(), 'ccs', array()); 632 - if ($reviewers || $ccs) { 633 - $handles = $this->loadViewerHandles(array_merge($reviewers, $ccs)); 634 - $reviewers = array_select_keys($handles, $reviewers); 635 - $ccs = array_select_keys($handles, $ccs); 636 - } 637 - } 638 - 639 - $comment_form = id(new DifferentialAddCommentView()) 640 - ->setRevision($revision); 641 - 642 - $review_warnings = array(); 643 - foreach ($field_list->getFields() as $field) { 644 - $review_warnings[] = $field->getWarningsForDetailView(); 645 - } 646 - $review_warnings = array_mergev($review_warnings); 647 - 648 - if ($review_warnings) { 649 - $review_warnings_panel = id(new PHUIInfoView()) 650 - ->setSeverity(PHUIInfoView::SEVERITY_WARNING) 651 - ->setErrors($review_warnings); 652 - $comment_form->setInfoView($review_warnings_panel); 653 - } 654 - 655 - $action_uri = $this->getApplicationURI( 656 - 'comment/save/'.$revision->getID().'/'); 657 - 658 - $comment_form->setActions($this->getRevisionCommentActions($revision)) 659 - ->setActionURI($action_uri) 660 - ->setUser($viewer) 661 - ->setDraft($draft) 662 - ->setReviewers(mpull($reviewers, 'getFullName', 'getPHID')) 663 - ->setCCs(mpull($ccs, 'getFullName', 'getPHID')); 664 - 665 - // TODO: This just makes the "Z" key work. Generalize this and remove 666 - // it at some point. 667 - $comment_form = phutil_tag( 668 - 'div', 669 - array( 670 - 'class' => 'differential-add-comment-panel', 671 - ), 672 - $comment_form); 673 - return $comment_form; 674 - } 675 - 676 - private function getRevisionCommentActions(DifferentialRevision $revision) { 677 - $actions = array( 678 - DifferentialAction::ACTION_COMMENT => true, 679 - ); 680 - 681 - $viewer = $this->getViewer(); 682 - $viewer_phid = $viewer->getPHID(); 683 - $viewer_is_owner = ($viewer_phid == $revision->getAuthorPHID()); 684 - $viewer_is_reviewer = in_array($viewer_phid, $revision->getReviewers()); 685 - $status = $revision->getStatus(); 686 - 687 - $viewer_has_accepted = false; 688 - $viewer_has_rejected = false; 689 - $status_accepted = DifferentialReviewerStatus::STATUS_ACCEPTED; 690 - $status_rejected = DifferentialReviewerStatus::STATUS_REJECTED; 691 - foreach ($revision->getReviewerStatus() as $reviewer) { 692 - if ($reviewer->getReviewerPHID() == $viewer_phid) { 693 - if ($reviewer->getStatus() == $status_accepted) { 694 - $viewer_has_accepted = true; 695 - } 696 - if ($reviewer->getStatus() == $status_rejected) { 697 - $viewer_has_rejected = true; 698 - } 699 - break; 700 - } 701 - } 702 - 703 - $allow_self_accept = PhabricatorEnv::getEnvConfig( 704 - 'differential.allow-self-accept'); 705 - $always_allow_abandon = PhabricatorEnv::getEnvConfig( 706 - 'differential.always-allow-abandon'); 707 - $always_allow_close = PhabricatorEnv::getEnvConfig( 708 - 'differential.always-allow-close'); 709 - $allow_reopen = PhabricatorEnv::getEnvConfig( 710 - 'differential.allow-reopen'); 711 - 712 - if ($viewer_is_owner) { 713 - switch ($status) { 714 - case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW: 715 - $actions[DifferentialAction::ACTION_ACCEPT] = $allow_self_accept; 716 - $actions[DifferentialAction::ACTION_ABANDON] = true; 717 - $actions[DifferentialAction::ACTION_RETHINK] = true; 718 - break; 719 - case ArcanistDifferentialRevisionStatus::NEEDS_REVISION: 720 - case ArcanistDifferentialRevisionStatus::CHANGES_PLANNED: 721 - $actions[DifferentialAction::ACTION_ACCEPT] = $allow_self_accept; 722 - $actions[DifferentialAction::ACTION_ABANDON] = true; 723 - $actions[DifferentialAction::ACTION_REQUEST] = true; 724 - break; 725 - case ArcanistDifferentialRevisionStatus::ACCEPTED: 726 - $actions[DifferentialAction::ACTION_ABANDON] = true; 727 - $actions[DifferentialAction::ACTION_REQUEST] = true; 728 - $actions[DifferentialAction::ACTION_RETHINK] = true; 729 - $actions[DifferentialAction::ACTION_CLOSE] = true; 730 - break; 731 - case ArcanistDifferentialRevisionStatus::CLOSED: 732 - break; 733 - case ArcanistDifferentialRevisionStatus::ABANDONED: 734 - $actions[DifferentialAction::ACTION_RECLAIM] = true; 735 - break; 736 - } 737 - } else { 738 - switch ($status) { 739 - case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW: 740 - $actions[DifferentialAction::ACTION_ABANDON] = $always_allow_abandon; 741 - $actions[DifferentialAction::ACTION_ACCEPT] = true; 742 - $actions[DifferentialAction::ACTION_REJECT] = true; 743 - $actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer; 744 - break; 745 - case ArcanistDifferentialRevisionStatus::NEEDS_REVISION: 746 - case ArcanistDifferentialRevisionStatus::CHANGES_PLANNED: 747 - $actions[DifferentialAction::ACTION_ABANDON] = $always_allow_abandon; 748 - $actions[DifferentialAction::ACTION_ACCEPT] = true; 749 - $actions[DifferentialAction::ACTION_REJECT] = !$viewer_has_rejected; 750 - $actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer; 751 - break; 752 - case ArcanistDifferentialRevisionStatus::ACCEPTED: 753 - $actions[DifferentialAction::ACTION_ABANDON] = $always_allow_abandon; 754 - $actions[DifferentialAction::ACTION_ACCEPT] = !$viewer_has_accepted; 755 - $actions[DifferentialAction::ACTION_REJECT] = true; 756 - $actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer; 757 - break; 758 - case ArcanistDifferentialRevisionStatus::CLOSED: 759 - case ArcanistDifferentialRevisionStatus::ABANDONED: 760 - break; 761 - } 762 - if ($status != ArcanistDifferentialRevisionStatus::CLOSED) { 763 - $actions[DifferentialAction::ACTION_CLAIM] = true; 764 - $actions[DifferentialAction::ACTION_CLOSE] = $always_allow_close; 765 - } 766 - } 767 - 768 - $actions[DifferentialAction::ACTION_ADDREVIEWERS] = true; 769 - $actions[DifferentialAction::ACTION_ADDCCS] = true; 770 - $actions[DifferentialAction::ACTION_REOPEN] = $allow_reopen && 771 - ($status == ArcanistDifferentialRevisionStatus::CLOSED); 772 - 773 - $actions = array_keys(array_filter($actions)); 774 - $actions_dict = array(); 775 - foreach ($actions as $action) { 776 - $actions_dict[$action] = DifferentialAction::getActionVerb($action); 777 - } 778 - 779 - return $actions_dict; 780 596 } 781 597 782 598 private function loadHistoryDiffStatus(array $diffs) {
+5
src/applications/differential/editor/DifferentialRevisionEditEngine.php
··· 73 73 return $object->getURI(); 74 74 } 75 75 76 + protected function getEditorURI() { 77 + return $this->getApplication()->getApplicationURI('revision/edit/'); 78 + } 79 + 76 80 public function setDiff(DifferentialDiff $diff) { 77 81 $this->diff = $diff; 78 82 return $this; ··· 176 180 ->setUseEdgeTransactions(true) 177 181 ->setTransactionType( 178 182 DifferentialRevisionReviewersTransaction::TRANSACTIONTYPE) 183 + ->setCommentActionLabel(pht('Edit Reviewers')) 179 184 ->setDescription(pht('Reviewers for this revision.')) 180 185 ->setConduitDescription(pht('Change the reviewers for this revision.')) 181 186 ->setConduitTypeDescription(pht('New reviewers.'))
-201
src/applications/differential/view/DifferentialAddCommentView.php
··· 1 - <?php 2 - 3 - final class DifferentialAddCommentView extends AphrontView { 4 - 5 - private $revision; 6 - private $actions; 7 - private $actionURI; 8 - private $draft; 9 - private $reviewers = array(); 10 - private $ccs = array(); 11 - private $errorView; 12 - 13 - public function setInfoView(PHUIInfoView $error_view) { 14 - $this->errorView = $error_view; 15 - return $this; 16 - } 17 - 18 - public function getErrorView() { 19 - return $this->errorView; 20 - } 21 - 22 - public function setRevision($revision) { 23 - $this->revision = $revision; 24 - return $this; 25 - } 26 - 27 - public function setActions(array $actions) { 28 - $this->actions = $actions; 29 - return $this; 30 - } 31 - 32 - public function setActionURI($uri) { 33 - $this->actionURI = $uri; 34 - return $this; 35 - } 36 - 37 - public function setDraft(PhabricatorDraft $draft = null) { 38 - $this->draft = $draft; 39 - return $this; 40 - } 41 - 42 - public function setReviewers(array $names) { 43 - $this->reviewers = $names; 44 - return $this; 45 - } 46 - 47 - public function setCCs(array $names) { 48 - $this->ccs = $names; 49 - return $this; 50 - } 51 - 52 - public function render() { 53 - $viewer = $this->getViewer(); 54 - 55 - $this->requireResource('differential-revision-add-comment-css'); 56 - $revision = $this->revision; 57 - 58 - $action = null; 59 - if ($this->draft) { 60 - $action = idx($this->draft->getMetadata(), 'action'); 61 - } 62 - 63 - $enable_reviewers = DifferentialAction::allowReviewers($action); 64 - $enable_ccs = ($action == DifferentialAction::ACTION_ADDCCS); 65 - $add_reviewers_labels = array( 66 - 'add_reviewers' => pht('Add Reviewers'), 67 - 'request_review' => pht('Add Reviewers'), 68 - 'resign' => pht('Suggest Reviewers'), 69 - ); 70 - 71 - $mailable_source = new PhabricatorMetaMTAMailableDatasource(); 72 - 73 - // TODO: This should be a reviewers datasource, but it's a mess. 74 - $reviewer_source = new PhabricatorMetaMTAMailableDatasource(); 75 - 76 - $form = new AphrontFormView(); 77 - $form 78 - ->setWorkflow(true) 79 - ->setViewer($viewer) 80 - ->setAction($this->actionURI) 81 - ->addHiddenInput('revision_id', $revision->getID()) 82 - ->appendChild( 83 - id(new AphrontFormSelectControl()) 84 - ->setLabel(pht('Action')) 85 - ->setName('action') 86 - ->setValue($action) 87 - ->setID('comment-action') 88 - ->setOptions($this->actions)) 89 - ->appendControl( 90 - id(new AphrontFormTokenizerControl()) 91 - ->setLabel($enable_reviewers ? $add_reviewers_labels[$action] : 92 - $add_reviewers_labels['add_reviewers']) 93 - ->setName('reviewers') 94 - ->setControlID('add-reviewers') 95 - ->setControlStyle($enable_reviewers ? null : 'display: none') 96 - ->setID('add-reviewers-tokenizer') 97 - ->setDisableBehavior(true) 98 - ->setDatasource($reviewer_source)) 99 - ->appendControl( 100 - id(new AphrontFormTokenizerControl()) 101 - ->setLabel(pht('Add Subscribers')) 102 - ->setName('ccs') 103 - ->setControlID('add-ccs') 104 - ->setControlStyle($enable_ccs ? null : 'display: none') 105 - ->setID('add-ccs-tokenizer') 106 - ->setDisableBehavior(true) 107 - ->setDatasource($mailable_source)) 108 - ->appendChild( 109 - id(new PhabricatorRemarkupControl()) 110 - ->setName('comment') 111 - ->setID('comment-content') 112 - ->setLabel(pht('Comment')) 113 - ->setValue($this->draft ? $this->draft->getDraft() : null) 114 - ->setViewer($viewer)) 115 - ->appendChild( 116 - id(new AphrontFormSubmitControl()) 117 - ->setValue(pht('Submit'))); 118 - 119 - Javelin::initBehavior( 120 - 'differential-add-reviewers-and-ccs', 121 - array( 122 - 'dynamic' => array( 123 - 'add-reviewers-tokenizer' => array( 124 - 'actions' => array( 125 - 'request_review' => 1, 126 - 'add_reviewers' => 1, 127 - 'resign' => 1, 128 - ), 129 - 'src' => $reviewer_source->getDatasourceURI(), 130 - 'value' => $this->reviewers, 131 - 'row' => 'add-reviewers', 132 - 'labels' => $add_reviewers_labels, 133 - 'placeholder' => $reviewer_source->getPlaceholderText(), 134 - ), 135 - 'add-ccs-tokenizer' => array( 136 - 'actions' => array('add_ccs' => 1), 137 - 'src' => $mailable_source->getDatasourceURI(), 138 - 'value' => $this->ccs, 139 - 'row' => 'add-ccs', 140 - 'placeholder' => $mailable_source->getPlaceholderText(), 141 - ), 142 - ), 143 - 'select' => 'comment-action', 144 - )); 145 - 146 - $diff = $revision->loadActiveDiff(); 147 - $rev_id = $revision->getID(); 148 - 149 - Javelin::initBehavior( 150 - 'differential-feedback-preview', 151 - array( 152 - 'uri' => '/differential/comment/preview/'.$rev_id.'/', 153 - 'preview' => 'comment-preview', 154 - 'action' => 'comment-action', 155 - 'content' => 'comment-content', 156 - 'previewTokenizers' => array( 157 - 'reviewers' => 'add-reviewers-tokenizer', 158 - 'ccs' => 'add-ccs-tokenizer', 159 - ), 160 - 161 - 'inlineuri' => '/differential/comment/inline/preview/'.$rev_id.'/', 162 - 'inline' => 'inline-comment-preview', 163 - )); 164 - 165 - $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business'); 166 - $header_text = $is_serious 167 - ? pht('Add Comment') 168 - : pht('Leap Into Action!'); 169 - 170 - $header = id(new PHUIHeaderView()) 171 - ->setHeader($header_text); 172 - 173 - $anchor = id(new PhabricatorAnchorView()) 174 - ->setAnchorName('comment') 175 - ->setNavigationMarker(true); 176 - 177 - $loading = phutil_tag( 178 - 'span', 179 - array('class' => 'aphront-panel-preview-loading-text'), 180 - pht('Loading comment preview...')); 181 - 182 - $preview = phutil_tag_div( 183 - 'aphront-panel-preview aphront-panel-flush', 184 - array( 185 - phutil_tag('div', array('id' => 'comment-preview'), $loading), 186 - phutil_tag('div', array('id' => 'inline-comment-preview')), 187 - )); 188 - 189 - 190 - $comment_box = id(new PHUIObjectBoxView()) 191 - ->setHeader($header) 192 - ->appendChild($anchor) 193 - ->appendChild($form); 194 - 195 - if ($this->errorView) { 196 - $comment_box->setInfoView($this->errorView); 197 - } 198 - 199 - return array($comment_box, $preview); 200 - } 201 - }