diff --git a/src/infrastructure/diff/PhabricatorInlineCommentController.php b/src/infrastructure/diff/PhabricatorInlineCommentController.php index 7bb547a756..09f3528ff3 100644 --- a/src/infrastructure/diff/PhabricatorInlineCommentController.php +++ b/src/infrastructure/diff/PhabricatorInlineCommentController.php @@ -1,249 +1,250 @@ commentID; } public function getOperation() { return $this->operation; } public function getCommentText() { return $this->commentText; } public function getLineLength() { return $this->lineLength; } public function getLineNumber() { return $this->lineNumber; } public function getIsOnRight() { return $this->isOnRight; } public function getChangesetID() { return $this->changesetID; } public function getIsNewFile() { return $this->isNewFile; } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $this->readRequestParameters(); switch ($this->getOperation()) { case 'delete': $inline = $this->loadCommentForEdit($this->getCommentID()); if ($request->isFormPost()) { $this->deleteComment($inline); return $this->buildEmptyResponse(); } $dialog = new AphrontDialogView(); $dialog->setUser($user); $dialog->setSubmitURI($request->getRequestURI()); $dialog->setTitle(pht('Really delete this comment?')); $dialog->addHiddenInput('id', $this->getCommentID()); $dialog->addHiddenInput('op', 'delete'); $dialog->appendChild( phutil_tag('p', array(), pht('Delete this inline comment?'))); $dialog->addCancelButton('#'); $dialog->addSubmitButton(pht('Delete')); return id(new AphrontDialogResponse())->setDialog($dialog); case 'edit': $inline = $this->loadCommentForEdit($this->getCommentID()); $text = $this->getCommentText(); if ($request->isFormPost()) { if (strlen($text)) { $inline->setContent($text); $this->saveComment($inline); return $this->buildRenderedCommentResponse( $inline, $this->getIsOnRight()); } else { $this->deleteComment($inline); return $this->buildEmptyResponse(); } } $edit_dialog = $this->buildEditDialog(); $edit_dialog->setTitle(pht('Edit Inline Comment')); $edit_dialog->addHiddenInput('id', $this->getCommentID()); $edit_dialog->addHiddenInput('op', 'edit'); $edit_dialog->appendChild( $this->renderTextArea( nonempty($text, $inline->getContent()))); return id(new AphrontAjaxResponse()) ->setContent($edit_dialog->render()); case 'create': $text = $this->getCommentText(); if (!$request->isFormPost() || !strlen($text)) { return $this->buildEmptyResponse(); } $inline = $this->createComment() ->setChangesetID($this->getChangesetID()) ->setAuthorPHID($user->getPHID()) ->setLineNumber($this->getLineNumber()) ->setLineLength($this->getLineLength()) ->setIsNewFile($this->getIsNewFile()) ->setContent($text); $this->saveComment($inline); return $this->buildRenderedCommentResponse( $inline, $this->getIsOnRight()); case 'reply': default: $edit_dialog = $this->buildEditDialog(); if ($this->getOperation() == 'reply') { $inline = $this->loadComment($this->getCommentID()); $edit_dialog->setTitle(pht('Reply to Inline Comment')); $changeset = $inline->getChangesetID(); $is_new = $inline->getIsNewFile(); $number = $inline->getLineNumber(); $length = $inline->getLineLength(); } else { $edit_dialog->setTitle(pht('New Inline Comment')); $changeset = $this->getChangesetID(); $is_new = $this->getIsNewFile(); $number = $this->getLineNumber(); $length = $this->getLineLength(); } $edit_dialog->addHiddenInput('op', 'create'); $edit_dialog->addHiddenInput('changeset', $changeset); $edit_dialog->addHiddenInput('is_new', $is_new); $edit_dialog->addHiddenInput('number', $number); $edit_dialog->addHiddenInput('length', $length); $text_area = $this->renderTextArea($this->getCommentText()); $edit_dialog->appendChild($text_area); return id(new AphrontAjaxResponse()) ->setContent($edit_dialog->render()); } } private function readRequestParameters() { $request = $this->getRequest(); // NOTE: This isn't necessarily a DifferentialChangeset ID, just an // application identifier for the changeset. In Diffusion, it's a Path ID. $this->changesetID = $request->getInt('changeset'); $this->isNewFile = (int)$request->getBool('is_new'); $this->isOnRight = $request->getBool('on_right'); $this->lineNumber = $request->getInt('number'); $this->lineLength = $request->getInt('length'); $this->commentText = $request->getStr('text'); $this->commentID = $request->getInt('id'); $this->operation = $request->getStr('op'); } private function buildEditDialog() { $request = $this->getRequest(); $user = $request->getUser(); $edit_dialog = new DifferentialInlineCommentEditView(); $edit_dialog->setUser($user); $edit_dialog->setSubmitURI($request->getRequestURI()); $edit_dialog->setOnRight($this->getIsOnRight()); $edit_dialog->setNumber($this->getLineNumber()); $edit_dialog->setLength($this->getLineLength()); return $edit_dialog; } private function buildEmptyResponse() { return id(new AphrontAjaxResponse()) ->setContent( array( 'markup' => '', )); } private function buildRenderedCommentResponse( PhabricatorInlineCommentInterface $inline, $on_right) { $request = $this->getRequest(); $user = $request->getUser(); $engine = new PhabricatorMarkupEngine(); $engine->setViewer($user); $engine->addObject( $inline, PhabricatorInlineCommentInterface::MARKUP_FIELD_BODY); $engine->process(); $phids = array($user->getPHID()); $handles = $this->loadViewerHandles($phids); $view = new DifferentialInlineCommentView(); $view->setInlineComment($inline); $view->setOnRight($on_right); $view->setBuildScaffolding(true); $view->setMarkupEngine($engine); $view->setHandles($handles); $view->setEditable(true); return id(new AphrontAjaxResponse()) ->setContent( array( 'inlineCommentID' => $inline->getID(), 'markup' => $view->render(), )); } private function renderTextArea($text) { return id(new PhabricatorRemarkupControl()) ->setUser($this->getRequest()->getUser()) ->setSigil('differential-inline-comment-edit-textarea') ->setName('text') - ->setValue($text); + ->setValue($text) + ->setDisableFullScreen(true); } } diff --git a/src/view/form/control/PhabricatorRemarkupControl.php b/src/view/form/control/PhabricatorRemarkupControl.php index ff550299f0..3d37c7d671 100644 --- a/src/view/form/control/PhabricatorRemarkupControl.php +++ b/src/view/form/control/PhabricatorRemarkupControl.php @@ -1,204 +1,213 @@ disableMacro = $disable; return $this; } + public function setDisableFullScreen($disable) { + $this->disableFullScreen = $disable; + return $this; + } + protected function renderInput() { $id = $this->getID(); if (!$id) { $id = celerity_generate_unique_node_id(); $this->setID($id); } // We need to have this if previews render images, since Ajax can not // currently ship JS or CSS. require_celerity_resource('lightbox-attachment-css'); Javelin::initBehavior( 'aphront-drag-and-drop-textarea', array( 'target' => $id, 'activatedClass' => 'aphront-textarea-drag-and-drop', 'uri' => '/file/dropupload/', )); Javelin::initBehavior( 'phabricator-remarkup-assist', array( 'pht' => array( 'bold text' => pht('bold text'), 'italic text' => pht('italic text'), 'monospaced text' => pht('monospaced text'), 'List Item' => pht('List Item'), 'data' => pht('data'), 'name' => pht('name'), 'URL' => pht('URL'), ), )); Javelin::initBehavior('phabricator-tooltips', array()); $actions = array( 'fa-bold' => array( 'tip' => pht('Bold'), ), 'fa-italic' => array( 'tip' => pht('Italics'), ), 'fa-text-width' => array( 'tip' => pht('Monospaced'), ), 'fa-link' => array( 'tip' => pht('Link'), ), array( 'spacer' => true, ), 'fa-list-ul' => array( 'tip' => pht('Bulleted List'), ), 'fa-list-ol' => array( 'tip' => pht('Numbered List'), ), 'fa-code' => array( 'tip' => pht('Code Block'), ), 'fa-table' => array( 'tip' => pht('Table'), ), 'fa-cloud-upload' => array( 'tip' => pht('Upload File'), ), ); if (!$this->disableMacro and function_exists('imagettftext')) { $actions[] = array( 'spacer' => true, ); $actions['fa-meh-o'] = array( 'tip' => pht('Meme'), ); } $actions['fa-life-bouy'] = array( 'tip' => pht('Help'), 'align' => 'right', 'href' => PhabricatorEnv::getDoclink('Remarkup Reference'), ); - $actions[] = array( - 'spacer' => true, - 'align' => 'right', - ); + if (!$this->disableFullScreen) { + $actions[] = array( + 'spacer' => true, + 'align' => 'right', + ); - $actions['fa-arrows-alt'] = array( - 'tip' => pht('Fullscreen Mode'), - 'align' => 'right', - ); + $actions['fa-arrows-alt'] = array( + 'tip' => pht('Fullscreen Mode'), + 'align' => 'right', + ); + } $buttons = array(); foreach ($actions as $action => $spec) { $classes = array(); if (idx($spec, 'align') == 'right') { $classes[] = 'remarkup-assist-right'; } if (idx($spec, 'spacer')) { $classes[] = 'remarkup-assist-separator'; $buttons[] = phutil_tag( 'span', array( 'class' => implode(' ', $classes), ), ''); continue; } else { $classes[] = 'remarkup-assist-button'; } $href = idx($spec, 'href', '#'); if ($href == '#') { $meta = array('action' => $action); $mustcapture = true; $target = null; } else { $meta = array(); $mustcapture = null; $target = '_blank'; } $content = null; $tip = idx($spec, 'tip'); if ($tip) { $meta['tip'] = $tip; $content = javelin_tag( 'span', array( 'aural' => true, ), $tip); } $buttons[] = javelin_tag( 'a', array( 'class' => implode(' ', $classes), 'href' => $href, 'sigil' => 'remarkup-assist has-tooltip', 'meta' => $meta, 'mustcapture' => $mustcapture, 'target' => $target, 'tabindex' => -1, ), phutil_tag( 'div', array( 'class' => 'remarkup-assist phui-icon-view phui-font-fa bluegrey '.$action, ), $content)); } $buttons = phutil_tag( 'div', array( 'class' => 'remarkup-assist-bar', ), $buttons); $monospaced_textareas = null; $monospaced_textareas_class = null; $user = $this->getUser(); if ($user) { $monospaced_textareas = $user ->loadPreferences() ->getPreference( PhabricatorUserPreferences::PREFERENCE_MONOSPACED_TEXTAREAS); if ($monospaced_textareas == 'enabled') { $monospaced_textareas_class = 'PhabricatorMonospaced'; } } $this->setCustomClass( 'remarkup-assist-textarea '.$monospaced_textareas_class); return javelin_tag( 'div', array( 'sigil' => 'remarkup-assist-control', ), array( $buttons, parent::renderInput(), )); } }