@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

Move PhrictionContent from RemarkupInterface (deprecated) to PHUIRemarkupView

Summary:
Depends on D19092. Ref T13077. This modernizes markup rendering for PhrictionContent.

This is a little messy because table of contents generation isn't straightforward.

Test Plan: Viewed Phriction documents with and without 3+ headers, saw ToC vs no ToC. Edited/previewed documents. Grepped for affected symbols. Checked DarkConsole for sensible cache behavior.

Maniphest Tasks: T13077

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

+99 -92
+1 -4
src/__phutil_library_map__.php
··· 10755 10755 'PhrictionChangeType' => 'PhrictionConstants', 10756 10756 'PhrictionConduitAPIMethod' => 'ConduitAPIMethod', 10757 10757 'PhrictionConstants' => 'Phobject', 10758 - 'PhrictionContent' => array( 10759 - 'PhrictionDAO', 10760 - 'PhabricatorMarkupInterface', 10761 - ), 10758 + 'PhrictionContent' => 'PhrictionDAO', 10762 10759 'PhrictionContentPHIDType' => 'PhabricatorPHIDType', 10763 10760 'PhrictionContentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 10764 10761 'PhrictionController' => 'PhabricatorController',
+9 -4
src/applications/phriction/controller/PhrictionDocumentController.php
··· 97 97 if ($current_status == PhrictionChangeType::CHANGE_EDIT || 98 98 $current_status == PhrictionChangeType::CHANGE_MOVE_HERE) { 99 99 100 - $core_content = $content->renderContent($viewer); 101 - $toc = $this->getToc($content); 100 + $remarkup_view = $content->newRemarkupView($viewer); 101 + 102 + $core_content = $remarkup_view->render(); 103 + 104 + $toc = $remarkup_view->getTableOfContents(); 105 + $toc = $this->getToc($toc); 102 106 103 107 } else if ($current_status == PhrictionChangeType::CHANGE_DELETE) { 104 108 $notice = new PHUIInfoView(); ··· 474 478 return $this->slug; 475 479 } 476 480 477 - protected function getToc(PhrictionContent $content) { 478 - $toc = $content->getRenderedTableOfContents(); 481 + protected function getToc($toc) { 482 + 479 483 if ($toc) { 480 484 $toc = phutil_tag_div('phui-document-toc-content', array( 481 485 phutil_tag_div( ··· 484 488 $toc, 485 489 )); 486 490 } 491 + 487 492 return $toc; 488 493 } 489 494
+5 -79
src/applications/phriction/storage/PhrictionContent.php
··· 1 1 <?php 2 2 3 - /** 4 - * @task markup Markup Interface 5 - */ 6 3 final class PhrictionContent 7 - extends PhrictionDAO 8 - implements PhabricatorMarkupInterface { 9 - 10 - const MARKUP_FIELD_BODY = 'markup:body'; 4 + extends PhrictionDAO { 11 5 12 6 protected $id; 13 7 protected $documentID; ··· 21 15 22 16 protected $changeType; 23 17 protected $changeRef; 24 - 25 - private $renderedTableOfContents; 26 - 27 - public function renderContent(PhabricatorUser $viewer) { 28 - return PhabricatorMarkupEngine::renderOneObject( 29 - $this, 30 - self::MARKUP_FIELD_BODY, 31 - $viewer, 32 - $this); 33 - } 34 18 35 19 protected function getConfiguration() { 36 20 return array( ··· 66 50 return PhrictionContentPHIDType::TYPECONST; 67 51 } 68 52 69 - 70 - /* -( Markup Interface )--------------------------------------------------- */ 71 - 72 - 73 - /** 74 - * @task markup 75 - */ 76 - public function getMarkupFieldKey($field) { 77 - $content = $this->getMarkupText($field); 78 - return PhabricatorMarkupEngine::digestRemarkupContent($this, $content); 79 - } 80 - 81 - 82 - /** 83 - * @task markup 84 - */ 85 - public function getMarkupText($field) { 86 - return $this->getContent(); 87 - } 88 - 89 - 90 - /** 91 - * @task markup 92 - */ 93 - public function newMarkupEngine($field) { 94 - return PhabricatorMarkupEngine::newPhrictionMarkupEngine(); 95 - } 96 - 97 - 98 - /** 99 - * @task markup 100 - */ 101 - public function didMarkupText( 102 - $field, 103 - $output, 104 - PhutilMarkupEngine $engine) { 105 - 106 - $this->renderedTableOfContents = 107 - PhutilRemarkupHeaderBlockRule::renderTableOfContents($engine); 108 - 109 - return phutil_tag( 110 - 'div', 111 - array( 112 - 'class' => 'phabricator-remarkup', 113 - ), 114 - $output); 53 + public function newRemarkupView(PhabricatorUser $viewer) { 54 + return id(new PHUIRemarkupView($viewer, $this->getContent())) 55 + ->setRemarkupOption(PHUIRemarkupView::OPTION_GENERATE_TOC, true) 56 + ->setGenerateTableOfContents(true); 115 57 } 116 - 117 - /** 118 - * @task markup 119 - */ 120 - public function getRenderedTableOfContents() { 121 - return $this->renderedTableOfContents; 122 - } 123 - 124 - 125 - /** 126 - * @task markup 127 - */ 128 - public function shouldUseMarkupCache($field) { 129 - return (bool)$this->getID(); 130 - } 131 - 132 58 133 59 }
+37
src/infrastructure/markup/PhabricatorMarkupOneOff.php
··· 12 12 private $engineRuleset; 13 13 private $engine; 14 14 private $disableCache; 15 + private $contentCacheFragment; 16 + 17 + private $generateTableOfContents; 18 + private $tableOfContents; 15 19 16 20 public function setEngineRuleset($engine_ruleset) { 17 21 $this->engineRuleset = $engine_ruleset; ··· 54 58 return $this->disableCache; 55 59 } 56 60 61 + public function setGenerateTableOfContents($generate) { 62 + $this->generateTableOfContents = $generate; 63 + return $this; 64 + } 65 + 66 + public function getGenerateTableOfContents() { 67 + return $this->generateTableOfContents; 68 + } 69 + 70 + public function getTableOfContents() { 71 + return $this->tableOfContents; 72 + } 73 + 74 + public function setContentCacheFragment($fragment) { 75 + $this->contentCacheFragment = $fragment; 76 + return $this; 77 + } 78 + 79 + public function getContentCacheFragment() { 80 + return $this->contentCacheFragment; 81 + } 82 + 57 83 public function getMarkupFieldKey($field) { 84 + $fragment = $this->getContentCacheFragment(); 85 + if ($fragment !== null) { 86 + return $fragment; 87 + } 88 + 58 89 return PhabricatorHash::digestForIndex($this->getContent()).':oneoff'; 59 90 } 60 91 ··· 81 112 $output, 82 113 PhutilMarkupEngine $engine) { 83 114 115 + if ($this->getGenerateTableOfContents()) { 116 + $toc = PhutilRemarkupHeaderBlockRule::renderTableOfContents($engine); 117 + $this->tableOfContents = $toc; 118 + } 119 + 84 120 require_celerity_resource('phabricator-remarkup-css'); 121 + 85 122 return phutil_tag( 86 123 'div', 87 124 array(
+47 -5
src/infrastructure/markup/view/PHUIRemarkupView.php
··· 14 14 private $corpus; 15 15 private $contextObject; 16 16 private $options; 17 + private $oneoff; 18 + private $generateTableOfContents; 17 19 18 20 // TODO: In the long run, rules themselves should define available options. 19 21 // For now, just define constants here so we can more easily replace things 20 22 // later once this is cleaned up. 21 23 const OPTION_PRESERVE_LINEBREAKS = 'preserve-linebreaks'; 24 + const OPTION_GENERATE_TOC = 'header.generate-toc'; 22 25 23 26 public function __construct(PhabricatorUser $viewer, $corpus) { 24 27 $this->setUser($viewer); ··· 46 49 return $this; 47 50 } 48 51 52 + public function setGenerateTableOfContents($generate) { 53 + $this->generateTableOfContents = $generate; 54 + return $this; 55 + } 56 + 57 + public function getGenerateTableOfContents() { 58 + return $this->generateTableOfContents; 59 + } 60 + 61 + public function getTableOfContents() { 62 + return $this->oneoff->getTableOfContents(); 63 + } 64 + 49 65 public function render() { 50 66 $viewer = $this->getViewer(); 51 67 $corpus = $this->corpus; ··· 54 70 $options = $this->options; 55 71 56 72 $oneoff = id(new PhabricatorMarkupOneOff()) 57 - ->setContent($corpus); 73 + ->setContent($corpus) 74 + ->setContentCacheFragment($this->getContentCacheFragment()); 58 75 59 76 if ($options) { 60 77 $oneoff->setEngine($this->getEngine()); ··· 62 79 $oneoff->setPreserveLinebreaks(true); 63 80 } 64 81 82 + $generate_toc = $this->getGenerateTableOfContents(); 83 + $oneoff->setGenerateTableOfContents($generate_toc); 84 + $this->oneoff = $oneoff; 85 + 65 86 $content = PhabricatorMarkupEngine::renderOneObject( 66 87 $oneoff, 67 88 'default', ··· 76 97 $viewer = $this->getViewer(); 77 98 78 99 $viewer_key = $viewer->getCacheFragment(); 79 - 80 - ksort($options); 81 - $engine_key = serialize($options); 82 - $engine_key = PhabricatorHash::digestForIndex($engine_key); 100 + $engine_key = $this->getEngineCacheFragment(); 83 101 84 102 $cache = PhabricatorCaches::getRequestCache(); 85 103 $cache_key = "remarkup.engine({$viewer_key}, {$engine_key})"; ··· 91 109 } 92 110 93 111 return $engine; 112 + } 113 + 114 + private function getEngineCacheFragment() { 115 + $options = $this->options; 116 + 117 + ksort($options); 118 + 119 + $engine_key = serialize($options); 120 + $engine_key = PhabricatorHash::digestForIndex($engine_key); 121 + 122 + return $engine_key; 123 + } 124 + 125 + private function getContentCacheFragment() { 126 + $corpus = $this->corpus; 127 + 128 + $content_fragment = PhabricatorHash::digestForIndex($corpus); 129 + $options_fragment = array( 130 + 'toc' => $this->getGenerateTableOfContents(), 131 + ); 132 + $options_fragment = serialize($options_fragment); 133 + $options_fragment = PhabricatorHash::digestForIndex($options_fragment); 134 + 135 + return "remarkup({$content_fragment}, {$options_fragment})"; 94 136 } 95 137 96 138 }