mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
Render remarkup in feed in a mostly reasonable way
Summary: Fixes T4057. This sort of sidesteps the trickiest (but very rare) case of things like embedded slowvotes. We might be able to refine that later. In the common bad case (macros, large images) it gets reasonable results by using `overflow: hidden` with `max-height`. We use `PhabriatorMarkupEngine::summarize()` to try to just render the first paragraph. Test Plan: {F195093} Reviewers: chad, btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T4057 Differential Revision: https://secure.phabricator.com/D10355
This commit is contained in:
parent
d13d6963dd
commit
69b0ac724a
7 changed files with 141 additions and 9 deletions
|
@ -125,7 +125,7 @@ return array(
|
|||
'rsrc/css/phui/phui-box.css' => '7b3a2eed',
|
||||
'rsrc/css/phui/phui-button.css' => 'c7412aa1',
|
||||
'rsrc/css/phui/phui-document.css' => 'a5615198',
|
||||
'rsrc/css/phui/phui-feed-story.css' => 'e2c9bc83',
|
||||
'rsrc/css/phui/phui-feed-story.css' => '55dc7732',
|
||||
'rsrc/css/phui/phui-fontkit.css' => 'fff25cfa',
|
||||
'rsrc/css/phui/phui-form-view.css' => 'a2d72756',
|
||||
'rsrc/css/phui/phui-form.css' => 'b78ec020',
|
||||
|
@ -771,7 +771,7 @@ return array(
|
|||
'phui-calendar-list-css' => 'c1d0ca59',
|
||||
'phui-calendar-month-css' => 'a92e47d2',
|
||||
'phui-document-view-css' => 'a5615198',
|
||||
'phui-feed-story-css' => 'e2c9bc83',
|
||||
'phui-feed-story-css' => '55dc7732',
|
||||
'phui-font-icon-base-css' => 'eb84f033',
|
||||
'phui-fontkit-css' => 'fff25cfa',
|
||||
'phui-form-css' => 'b78ec020',
|
||||
|
|
|
@ -4376,7 +4376,10 @@ phutil_register_library_map(array(
|
|||
'PhabricatorFeedPublicStreamController' => 'PhabricatorFeedController',
|
||||
'PhabricatorFeedQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorFeedSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhabricatorFeedStory' => 'PhabricatorPolicyInterface',
|
||||
'PhabricatorFeedStory' => array(
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorMarkupInterface',
|
||||
),
|
||||
'PhabricatorFeedStoryAggregate' => 'PhabricatorFeedStory',
|
||||
'PhabricatorFeedStoryAudit' => 'PhabricatorFeedStory',
|
||||
'PhabricatorFeedStoryCommit' => 'PhabricatorFeedStory',
|
||||
|
|
|
@ -8,7 +8,10 @@
|
|||
* @task load Loading Stories
|
||||
* @task policy Policy Implementation
|
||||
*/
|
||||
abstract class PhabricatorFeedStory implements PhabricatorPolicyInterface {
|
||||
abstract class PhabricatorFeedStory
|
||||
implements
|
||||
PhabricatorPolicyInterface,
|
||||
PhabricatorMarkupInterface {
|
||||
|
||||
private $data;
|
||||
private $hasViewed;
|
||||
|
@ -19,6 +22,7 @@ abstract class PhabricatorFeedStory implements PhabricatorPolicyInterface {
|
|||
private $handles = array();
|
||||
private $objects = array();
|
||||
private $projectPHIDs = array();
|
||||
private $markupFieldOutput = array();
|
||||
|
||||
/* -( Loading Stories )---------------------------------------------------- */
|
||||
|
||||
|
@ -150,9 +154,46 @@ abstract class PhabricatorFeedStory implements PhabricatorPolicyInterface {
|
|||
$stories[$key]->setHandles($story_handles);
|
||||
}
|
||||
|
||||
// Load and process story markup blocks.
|
||||
|
||||
$engine = new PhabricatorMarkupEngine();
|
||||
$engine->setViewer($viewer);
|
||||
foreach ($stories as $story) {
|
||||
foreach ($story->getFieldStoryMarkupFields() as $field) {
|
||||
$engine->addObject($story, $field);
|
||||
}
|
||||
}
|
||||
|
||||
$engine->process();
|
||||
|
||||
foreach ($stories as $story) {
|
||||
foreach ($story->getFieldStoryMarkupFields() as $field) {
|
||||
$story->setMarkupFieldOutput(
|
||||
$field,
|
||||
$engine->getOutput($story, $field));
|
||||
}
|
||||
}
|
||||
|
||||
return $stories;
|
||||
}
|
||||
|
||||
public function setMarkupFieldOutput($field, $output) {
|
||||
$this->markupFieldOutput[$field] = $output;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMarkupFieldOutput($field) {
|
||||
if (!array_key_exists($field, $this->markupFieldOutput)) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Trying to retrieve markup field key "%s", but this feed story '.
|
||||
'did not request it be rendered.',
|
||||
$field));
|
||||
}
|
||||
|
||||
return $this->markupFieldOutput[$field];
|
||||
}
|
||||
|
||||
public function setHovercard($hover) {
|
||||
$this->hovercard = $hover;
|
||||
return $this;
|
||||
|
@ -374,6 +415,10 @@ abstract class PhabricatorFeedStory implements PhabricatorPolicyInterface {
|
|||
return $this->projectPHIDs;
|
||||
}
|
||||
|
||||
public function getFieldStoryMarkupFields() {
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorPolicyInterface Implementation )-------------------------- */
|
||||
|
||||
|
@ -425,4 +470,31 @@ abstract class PhabricatorFeedStory implements PhabricatorPolicyInterface {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorMarkupInterface Implementation )--------------------------- */
|
||||
|
||||
|
||||
public function getMarkupFieldKey($field) {
|
||||
return 'feed:'.$this->getChronologicalKey().':'.$field;
|
||||
}
|
||||
|
||||
public function newMarkupEngine($field) {
|
||||
return PhabricatorMarkupEngine::newMarkupEngine(array());
|
||||
}
|
||||
|
||||
public function getMarkupText($field) {
|
||||
throw new PhutilMethodNotImplementedException();
|
||||
}
|
||||
|
||||
public function didMarkupText(
|
||||
$field,
|
||||
$output,
|
||||
PhutilMarkupEngine $engine) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function shouldUseMarkupCache($field) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,35 @@ class PhabricatorApplicationTransactionFeedStory
|
|||
return $this->getObject($this->getPrimaryTransactionPHID());
|
||||
}
|
||||
|
||||
public function getFieldStoryMarkupFields() {
|
||||
$xaction_phids = $this->getValue('transactionPHIDs');
|
||||
|
||||
$fields = array();
|
||||
foreach ($xaction_phids as $xaction_phid) {
|
||||
$xaction = $this->getObject($xaction_phid);
|
||||
foreach ($xaction->getMarkupFieldsForFeed($this) as $field) {
|
||||
$fields[] = $field;
|
||||
}
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
public function getMarkupText($field) {
|
||||
$xaction_phids = $this->getValue('transactionPHIDs');
|
||||
|
||||
foreach ($xaction_phids as $xaction_phid) {
|
||||
$xaction = $this->getObject($xaction_phid);
|
||||
foreach ($xaction->getMarkupFieldsForFeed($this) as $xaction_field) {
|
||||
if ($xaction_field == $field) {
|
||||
return $xaction->getMarkupTextForFeed($this, $field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function renderView() {
|
||||
$view = $this->newStoryView();
|
||||
|
||||
|
|
|
@ -788,6 +788,31 @@ abstract class PhabricatorApplicationTransaction
|
|||
return $this->getTitle();
|
||||
}
|
||||
|
||||
public function getMarkupFieldsForFeed(PhabricatorFeedStory $story) {
|
||||
$fields = array();
|
||||
|
||||
switch ($this->getTransactionType()) {
|
||||
case PhabricatorTransactions::TYPE_COMMENT:
|
||||
$text = $this->getComment()->getContent();
|
||||
if (strlen($text)) {
|
||||
$fields[] = 'comment/'.$this->getID();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
public function getMarkupTextForFeed(PhabricatorFeedStory $story, $field) {
|
||||
switch ($this->getTransactionType()) {
|
||||
case PhabricatorTransactions::TYPE_COMMENT:
|
||||
$text = $this->getComment()->getContent();
|
||||
return PhabricatorMarkupEngine::summarize($text);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getBodyForFeed(PhabricatorFeedStory $story) {
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
|
@ -797,10 +822,12 @@ abstract class PhabricatorApplicationTransaction
|
|||
switch ($this->getTransactionType()) {
|
||||
case PhabricatorTransactions::TYPE_COMMENT:
|
||||
$text = $this->getComment()->getContent();
|
||||
$body = phutil_escape_html_newlines(
|
||||
phutil_utf8_shorten($text, 128));
|
||||
if (strlen($text)) {
|
||||
$body = $story->getMarkupFieldOutput('comment/'.$this->getID());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $body;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ final class PhabricatorNavigationRemarkupRule extends PhutilRemarkupRule {
|
|||
|
||||
public function apply($text) {
|
||||
return preg_replace_callback(
|
||||
'@{nav\b((?:[^}\\\\]+|\\\\.)+)}$@m',
|
||||
'@{nav\b((?:[^}\\\\]+|\\\\.)*)}@m',
|
||||
array($this, 'markupNavigation'),
|
||||
$text);
|
||||
}
|
||||
|
@ -99,5 +99,4 @@ final class PhabricatorNavigationRemarkupRule extends PhutilRemarkupRule {
|
|||
return $this->getEngine()->storeText($out);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -28,9 +28,11 @@
|
|||
}
|
||||
|
||||
.phui-feed-story-body {
|
||||
padding: 0 8px 8px;
|
||||
margin: 0 8px 8px;
|
||||
color: {$darkgreytext};
|
||||
word-break: break-word;
|
||||
max-height: 300px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.phui-feed-story-foot {
|
||||
|
|
Loading…
Reference in a new issue