Path: blob/master/src/applications/files/document/render/PhabricatorDocumentRenderingEngine.php
12242 views
<?php12abstract class PhabricatorDocumentRenderingEngine3extends Phobject {45private $request;6private $controller;7private $activeEngine;8private $ref;910final public function setRequest(AphrontRequest $request) {11$this->request = $request;12return $this;13}1415final public function getRequest() {16if (!$this->request) {17throw new PhutilInvalidStateException('setRequest');18}1920return $this->request;21}2223final public function setController(PhabricatorController $controller) {24$this->controller = $controller;25return $this;26}2728final public function getController() {29if (!$this->controller) {30throw new PhutilInvalidStateException('setController');31}3233return $this->controller;34}3536final protected function getActiveEngine() {37return $this->activeEngine;38}3940final protected function getRef() {41return $this->ref;42}4344final public function newDocumentView(PhabricatorDocumentRef $ref) {45$request = $this->getRequest();46$viewer = $request->getViewer();4748$engines = PhabricatorDocumentEngine::getEnginesForRef($viewer, $ref);4950$engine_key = $this->getSelectedDocumentEngineKey();51if (!isset($engines[$engine_key])) {52$engine_key = head_key($engines);53}54$engine = $engines[$engine_key];5556$lines = $this->getSelectedLineRange();57if ($lines) {58$engine->setHighlightedLines(range($lines[0], $lines[1]));59}6061$encode_setting = $request->getStr('encode');62if (phutil_nonempty_string($encode_setting)) {63$engine->setEncodingConfiguration($encode_setting);64}6566$highlight_setting = $request->getStr('highlight');67if (phutil_nonempty_string($highlight_setting)) {68$engine->setHighlightingConfiguration($highlight_setting);69}7071$blame_setting = ($request->getStr('blame') !== 'off');72$engine->setBlameConfiguration($blame_setting);7374$views = array();75foreach ($engines as $candidate_key => $candidate_engine) {76$label = $candidate_engine->getViewAsLabel($ref);77if ($label === null) {78continue;79}8081$view_uri = $this->newRefViewURI($ref, $candidate_engine);8283$view_icon = $candidate_engine->getViewAsIconIcon($ref);84$view_color = $candidate_engine->getViewAsIconColor($ref);85$loading = $candidate_engine->newLoadingContent($ref);8687$views[] = array(88'viewKey' => $candidate_engine->getDocumentEngineKey(),89'icon' => $view_icon,90'color' => $view_color,91'name' => $label,92'engineURI' => $this->newRefRenderURI($ref, $candidate_engine),93'viewURI' => $view_uri,94'loadingMarkup' => hsprintf('%s', $loading),95'canEncode' => $candidate_engine->canConfigureEncoding($ref),96'canHighlight' => $candidate_engine->canConfigureHighlighting($ref),97'canBlame' => $candidate_engine->canBlame($ref),98);99}100101$viewport_id = celerity_generate_unique_node_id();102$control_id = celerity_generate_unique_node_id();103$icon = $engine->newDocumentIcon($ref);104105$config = array(106'controlID' => $control_id,107);108109$this->willStageRef($ref);110111if ($engine->shouldRenderAsync($ref)) {112$content = $engine->newLoadingContent($ref);113$config['next'] = 'render';114} else {115$this->willRenderRef($ref);116$content = $engine->newDocument($ref);117118if ($engine->canBlame($ref)) {119$config['next'] = 'blame';120}121}122123Javelin::initBehavior('document-engine', $config);124125$viewport = phutil_tag(126'div',127array(128'id' => $viewport_id,129),130$content);131132$meta = array(133'viewportID' => $viewport_id,134'viewKey' => $engine->getDocumentEngineKey(),135'views' => $views,136'encode' => array(137'icon' => 'fa-font',138'name' => pht('Change Text Encoding...'),139'uri' => '/services/encoding/',140'value' => $encode_setting,141),142'highlight' => array(143'icon' => 'fa-lightbulb-o',144'name' => pht('Highlight As...'),145'uri' => '/services/highlight/',146'value' => $highlight_setting,147),148'blame' => array(149'icon' => 'fa-backward',150'hide' => pht('Hide Blame'),151'show' => pht('Show Blame'),152'uri' => $ref->getBlameURI(),153'enabled' => $blame_setting,154'value' => null,155),156'coverage' => array(157'labels' => array(158// TODO: Modularize this properly, see T13125.159array(160'C' => pht('Covered'),161'U' => pht('Not Covered'),162'N' => pht('Not Executable'),163'X' => pht('Not Reachable'),164),165),166),167);168169$view_button = id(new PHUIButtonView())170->setTag('a')171->setText(pht('View Options'))172->setIcon('fa-file-image-o')173->setColor(PHUIButtonView::GREY)174->setID($control_id)175->setMetadata($meta)176->setDropdown(true)177->addSigil('document-engine-view-dropdown');178179$header = id(new PHUIHeaderView())180->setHeaderIcon($icon)181->setHeader($ref->getName())182->addActionLink($view_button);183184return id(new PHUIObjectBoxView())185->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)186->setHeader($header)187->appendChild($viewport);188}189190final public function newRenderResponse(PhabricatorDocumentRef $ref) {191$this->willStageRef($ref);192$this->willRenderRef($ref);193194$request = $this->getRequest();195$viewer = $request->getViewer();196197$engines = PhabricatorDocumentEngine::getEnginesForRef($viewer, $ref);198$engine_key = $this->getSelectedDocumentEngineKey();199if (!isset($engines[$engine_key])) {200return $this->newErrorResponse(201pht(202'The engine ("%s") is unknown, or unable to render this document.',203$engine_key));204}205$engine = $engines[$engine_key];206207$this->activeEngine = $engine;208209$encode_setting = $request->getStr('encode');210if (phutil_nonempty_string($encode_setting)) {211$engine->setEncodingConfiguration($encode_setting);212}213214$highlight_setting = $request->getStr('highlight');215if (phutil_nonempty_string($highlight_setting)) {216$engine->setHighlightingConfiguration($highlight_setting);217}218219$blame_setting = ($request->getStr('blame') !== 'off');220$engine->setBlameConfiguration($blame_setting);221222try {223$content = $engine->newDocument($ref);224} catch (Exception $ex) {225return $this->newErrorResponse($ex->getMessage());226}227228return $this->newContentResponse($content);229}230231public function newErrorResponse($message) {232$container = phutil_tag(233'div',234array(235'class' => 'document-engine-error',236),237array(238id(new PHUIIconView())239->setIcon('fa-exclamation-triangle red'),240' ',241$message,242));243244return $this->newContentResponse($container);245}246247private function newContentResponse($content) {248$request = $this->getRequest();249$viewer = $request->getViewer();250$controller = $this->getController();251252if ($request->isAjax()) {253return id(new AphrontAjaxResponse())254->setContent(255array(256'markup' => hsprintf('%s', $content),257));258}259260$crumbs = $this->newCrumbs();261$crumbs->setBorder(true);262263$content_frame = id(new PHUIObjectBoxView())264->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)265->appendChild($content);266267$page_frame = id(new PHUITwoColumnView())268->setFooter($content_frame);269270$title = array();271$ref = $this->getRef();272if ($ref) {273$title = array(274$ref->getName(),275pht('Standalone'),276);277} else {278$title = pht('Document');279}280281return $controller->newPage()282->setCrumbs($crumbs)283->setTitle($title)284->appendChild($page_frame);285}286287protected function newCrumbs() {288$engine = $this->getActiveEngine();289$controller = $this->getController();290291$crumbs = $controller->buildApplicationCrumbsForEditEngine();292293$ref = $this->getRef();294295$this->addApplicationCrumbs($crumbs, $ref);296297if ($ref) {298$label = $engine->getViewAsLabel($ref);299if ($label) {300$crumbs->addTextCrumb($label);301}302}303304return $crumbs;305}306307public function getRefViewURI(308PhabricatorDocumentRef $ref,309PhabricatorDocumentEngine $engine) {310return $this->newRefViewURI($ref, $engine);311}312313abstract protected function newRefViewURI(314PhabricatorDocumentRef $ref,315PhabricatorDocumentEngine $engine);316317abstract protected function newRefRenderURI(318PhabricatorDocumentRef $ref,319PhabricatorDocumentEngine $engine);320321protected function getSelectedDocumentEngineKey() {322return $this->getRequest()->getURIData('engineKey');323}324325protected function getSelectedLineRange() {326return $this->getRequest()->getURILineRange('lines', 1000);327}328329protected function addApplicationCrumbs(330PHUICrumbsView $crumbs,331PhabricatorDocumentRef $ref = null) {332return;333}334335protected function willStageRef(PhabricatorDocumentRef $ref) {336return;337}338339protected function willRenderRef(PhabricatorDocumentRef $ref) {340return;341}342343}344345346