mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 16:52:41 +01:00
Pull file Document Engine rendering out of "Files" application controllers
Summary: Ref T13105. This separates document rendering from the Controllers which trigger it so it can be reused elsewhere (notably, in Diffusion). This shouldn't cause any application behavior to change, it just pulls the rendering logic out so it can be reused elsewhere. Test Plan: Viewed various types of files in Files; toggled rendering, highlighting, and encoding. Reviewers: mydeveloperday Reviewed By: mydeveloperday Maniphest Tasks: T13105 Differential Revision: https://secure.phabricator.com/D19301
This commit is contained in:
parent
7d4e25614d
commit
245132a0b2
7 changed files with 344 additions and 219 deletions
|
@ -2819,6 +2819,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorDivinerApplication' => 'applications/diviner/application/PhabricatorDivinerApplication.php',
|
'PhabricatorDivinerApplication' => 'applications/diviner/application/PhabricatorDivinerApplication.php',
|
||||||
'PhabricatorDocumentEngine' => 'applications/files/document/PhabricatorDocumentEngine.php',
|
'PhabricatorDocumentEngine' => 'applications/files/document/PhabricatorDocumentEngine.php',
|
||||||
'PhabricatorDocumentRef' => 'applications/files/document/PhabricatorDocumentRef.php',
|
'PhabricatorDocumentRef' => 'applications/files/document/PhabricatorDocumentRef.php',
|
||||||
|
'PhabricatorDocumentRenderingEngine' => 'applications/files/document/render/PhabricatorDocumentRenderingEngine.php',
|
||||||
'PhabricatorDoorkeeperApplication' => 'applications/doorkeeper/application/PhabricatorDoorkeeperApplication.php',
|
'PhabricatorDoorkeeperApplication' => 'applications/doorkeeper/application/PhabricatorDoorkeeperApplication.php',
|
||||||
'PhabricatorDraft' => 'applications/draft/storage/PhabricatorDraft.php',
|
'PhabricatorDraft' => 'applications/draft/storage/PhabricatorDraft.php',
|
||||||
'PhabricatorDraftDAO' => 'applications/draft/storage/PhabricatorDraftDAO.php',
|
'PhabricatorDraftDAO' => 'applications/draft/storage/PhabricatorDraftDAO.php',
|
||||||
|
@ -3010,6 +3011,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorFileDeleteController' => 'applications/files/controller/PhabricatorFileDeleteController.php',
|
'PhabricatorFileDeleteController' => 'applications/files/controller/PhabricatorFileDeleteController.php',
|
||||||
'PhabricatorFileDeleteTransaction' => 'applications/files/xaction/PhabricatorFileDeleteTransaction.php',
|
'PhabricatorFileDeleteTransaction' => 'applications/files/xaction/PhabricatorFileDeleteTransaction.php',
|
||||||
'PhabricatorFileDocumentController' => 'applications/files/controller/PhabricatorFileDocumentController.php',
|
'PhabricatorFileDocumentController' => 'applications/files/controller/PhabricatorFileDocumentController.php',
|
||||||
|
'PhabricatorFileDocumentRenderingEngine' => 'applications/files/document/render/PhabricatorFileDocumentRenderingEngine.php',
|
||||||
'PhabricatorFileDropUploadController' => 'applications/files/controller/PhabricatorFileDropUploadController.php',
|
'PhabricatorFileDropUploadController' => 'applications/files/controller/PhabricatorFileDropUploadController.php',
|
||||||
'PhabricatorFileEditController' => 'applications/files/controller/PhabricatorFileEditController.php',
|
'PhabricatorFileEditController' => 'applications/files/controller/PhabricatorFileEditController.php',
|
||||||
'PhabricatorFileEditEngine' => 'applications/files/editor/PhabricatorFileEditEngine.php',
|
'PhabricatorFileEditEngine' => 'applications/files/editor/PhabricatorFileEditEngine.php',
|
||||||
|
@ -8401,6 +8403,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorDivinerApplication' => 'PhabricatorApplication',
|
'PhabricatorDivinerApplication' => 'PhabricatorApplication',
|
||||||
'PhabricatorDocumentEngine' => 'Phobject',
|
'PhabricatorDocumentEngine' => 'Phobject',
|
||||||
'PhabricatorDocumentRef' => 'Phobject',
|
'PhabricatorDocumentRef' => 'Phobject',
|
||||||
|
'PhabricatorDocumentRenderingEngine' => 'Phobject',
|
||||||
'PhabricatorDoorkeeperApplication' => 'PhabricatorApplication',
|
'PhabricatorDoorkeeperApplication' => 'PhabricatorApplication',
|
||||||
'PhabricatorDraft' => 'PhabricatorDraftDAO',
|
'PhabricatorDraft' => 'PhabricatorDraftDAO',
|
||||||
'PhabricatorDraftDAO' => 'PhabricatorLiskDAO',
|
'PhabricatorDraftDAO' => 'PhabricatorLiskDAO',
|
||||||
|
@ -8624,6 +8627,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorFileDeleteController' => 'PhabricatorFileController',
|
'PhabricatorFileDeleteController' => 'PhabricatorFileController',
|
||||||
'PhabricatorFileDeleteTransaction' => 'PhabricatorFileTransactionType',
|
'PhabricatorFileDeleteTransaction' => 'PhabricatorFileTransactionType',
|
||||||
'PhabricatorFileDocumentController' => 'PhabricatorFileController',
|
'PhabricatorFileDocumentController' => 'PhabricatorFileController',
|
||||||
|
'PhabricatorFileDocumentRenderingEngine' => 'PhabricatorDocumentRenderingEngine',
|
||||||
'PhabricatorFileDropUploadController' => 'PhabricatorFileController',
|
'PhabricatorFileDropUploadController' => 'PhabricatorFileController',
|
||||||
'PhabricatorFileEditController' => 'PhabricatorFileController',
|
'PhabricatorFileEditController' => 'PhabricatorFileController',
|
||||||
'PhabricatorFileEditEngine' => 'PhabricatorEditEngine',
|
'PhabricatorFileEditEngine' => 'PhabricatorEditEngine',
|
||||||
|
|
|
@ -73,7 +73,7 @@ final class PhabricatorFilesApplication extends PhabricatorApplication {
|
||||||
=> 'PhabricatorFileViewController',
|
=> 'PhabricatorFileViewController',
|
||||||
'/file/' => array(
|
'/file/' => array(
|
||||||
'(query/(?P<queryKey>[^/]+)/)?' => 'PhabricatorFileListController',
|
'(query/(?P<queryKey>[^/]+)/)?' => 'PhabricatorFileListController',
|
||||||
'view/(?P<id>[^/]+)/'.
|
'view/(?P<id>[1-9]\d*)/'.
|
||||||
'(?:(?P<engineKey>[^/]+)/)?'.
|
'(?:(?P<engineKey>[^/]+)/)?'.
|
||||||
'(?:\$(?P<lines>\d+(?:-\d+)?))?'
|
'(?:\$(?P<lines>\d+(?:-\d+)?))?'
|
||||||
=> 'PhabricatorFileViewController',
|
=> 'PhabricatorFileViewController',
|
||||||
|
|
|
@ -3,10 +3,6 @@
|
||||||
final class PhabricatorFileDocumentController
|
final class PhabricatorFileDocumentController
|
||||||
extends PhabricatorFileController {
|
extends PhabricatorFileController {
|
||||||
|
|
||||||
private $file;
|
|
||||||
private $engine;
|
|
||||||
private $ref;
|
|
||||||
|
|
||||||
public function shouldAllowPublic() {
|
public function shouldAllowPublic() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -26,102 +22,14 @@ final class PhabricatorFileDocumentController
|
||||||
'This file ("%s") does not exist or could not be loaded.',
|
'This file ("%s") does not exist or could not be loaded.',
|
||||||
$file_phid));
|
$file_phid));
|
||||||
}
|
}
|
||||||
$this->file = $file;
|
|
||||||
|
|
||||||
$ref = id(new PhabricatorDocumentRef())
|
$ref = id(new PhabricatorDocumentRef())
|
||||||
->setFile($file);
|
->setFile($file);
|
||||||
$this->ref = $ref;
|
|
||||||
|
|
||||||
$engines = PhabricatorDocumentEngine::getEnginesForRef($viewer, $ref);
|
return id(new PhabricatorFileDocumentRenderingEngine())
|
||||||
$engine_key = $request->getURIData('engineKey');
|
->setRequest($request)
|
||||||
if (!isset($engines[$engine_key])) {
|
->setController($this)
|
||||||
return $this->newErrorResponse(
|
->newRenderResponse($ref);
|
||||||
pht(
|
|
||||||
'The engine ("%s") is unknown, or unable to render this document.',
|
|
||||||
$engine_key));
|
|
||||||
}
|
|
||||||
$engine = $engines[$engine_key];
|
|
||||||
$this->engine = $engine;
|
|
||||||
|
|
||||||
$encode_setting = $request->getStr('encode');
|
|
||||||
if (strlen($encode_setting)) {
|
|
||||||
$engine->setEncodingConfiguration($encode_setting);
|
|
||||||
}
|
|
||||||
|
|
||||||
$highlight_setting = $request->getStr('highlight');
|
|
||||||
if (strlen($highlight_setting)) {
|
|
||||||
$engine->setHighlightingConfiguration($highlight_setting);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$content = $engine->newDocument($ref);
|
|
||||||
} catch (Exception $ex) {
|
|
||||||
return $this->newErrorResponse($ex->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->newContentResponse($content);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function newErrorResponse($message) {
|
|
||||||
$container = phutil_tag(
|
|
||||||
'div',
|
|
||||||
array(
|
|
||||||
'class' => 'document-engine-error',
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
id(new PHUIIconView())
|
|
||||||
->setIcon('fa-exclamation-triangle red'),
|
|
||||||
' ',
|
|
||||||
$message,
|
|
||||||
));
|
|
||||||
|
|
||||||
return $this->newContentResponse($container);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private function newContentResponse($content) {
|
|
||||||
$viewer = $this->getViewer();
|
|
||||||
$request = $this->getRequest();
|
|
||||||
|
|
||||||
$file = $this->file;
|
|
||||||
$engine = $this->engine;
|
|
||||||
$ref = $this->ref;
|
|
||||||
|
|
||||||
if ($request->isAjax()) {
|
|
||||||
return id(new AphrontAjaxResponse())
|
|
||||||
->setContent(
|
|
||||||
array(
|
|
||||||
'markup' => hsprintf('%s', $content),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
|
||||||
if ($file) {
|
|
||||||
$crumbs->addTextCrumb($file->getMonogram(), $file->getInfoURI());
|
|
||||||
}
|
|
||||||
|
|
||||||
$label = $engine->getViewAsLabel($ref);
|
|
||||||
if ($label) {
|
|
||||||
$crumbs->addTextCrumb($label);
|
|
||||||
}
|
|
||||||
|
|
||||||
$crumbs->setBorder(true);
|
|
||||||
|
|
||||||
$content_frame = id(new PHUIObjectBoxView())
|
|
||||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
|
||||||
->appendChild($content);
|
|
||||||
|
|
||||||
$page_frame = id(new PHUITwoColumnView())
|
|
||||||
->setFooter($content_frame);
|
|
||||||
|
|
||||||
return $this->newPage()
|
|
||||||
->setCrumbs($crumbs)
|
|
||||||
->setTitle(
|
|
||||||
array(
|
|
||||||
$ref->getName(),
|
|
||||||
pht('Standalone'),
|
|
||||||
))
|
|
||||||
->appendChild($page_frame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -403,122 +403,15 @@ final class PhabricatorFileViewController extends PhabricatorFileController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private function newFileContent(PhabricatorFile $file) {
|
private function newFileContent(PhabricatorFile $file) {
|
||||||
$viewer = $this->getViewer();
|
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
|
|
||||||
$ref = id(new PhabricatorDocumentRef())
|
$ref = id(new PhabricatorDocumentRef())
|
||||||
->setFile($file);
|
->setFile($file);
|
||||||
|
|
||||||
$engines = PhabricatorDocumentEngine::getEnginesForRef($viewer, $ref);
|
$engine = id(new PhabricatorFileDocumentRenderingEngine())
|
||||||
|
->setRequest($request);
|
||||||
|
|
||||||
$engine_key = $request->getURIData('engineKey');
|
return $engine->newDocumentView($ref);
|
||||||
if (!isset($engines[$engine_key])) {
|
|
||||||
$engine_key = head_key($engines);
|
|
||||||
}
|
|
||||||
$engine = $engines[$engine_key];
|
|
||||||
|
|
||||||
$lines = $request->getURILineRange('lines', 1000);
|
|
||||||
if ($lines) {
|
|
||||||
$engine->setHighlightedLines(range($lines[0], $lines[1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
$encode_setting = $request->getStr('encode');
|
|
||||||
if (strlen($encode_setting)) {
|
|
||||||
$engine->setEncodingConfiguration($encode_setting);
|
|
||||||
}
|
|
||||||
|
|
||||||
$highlight_setting = $request->getStr('highlight');
|
|
||||||
if (strlen($highlight_setting)) {
|
|
||||||
$engine->setHighlightingConfiguration($highlight_setting);
|
|
||||||
}
|
|
||||||
|
|
||||||
$views = array();
|
|
||||||
foreach ($engines as $candidate_key => $candidate_engine) {
|
|
||||||
$label = $candidate_engine->getViewAsLabel($ref);
|
|
||||||
if ($label === null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$view_uri = '/file/view/'.$file->getID().'/'.$candidate_key.'/';
|
|
||||||
|
|
||||||
$view_icon = $candidate_engine->getViewAsIconIcon($ref);
|
|
||||||
$view_color = $candidate_engine->getViewAsIconColor($ref);
|
|
||||||
$loading = $candidate_engine->newLoadingContent($ref);
|
|
||||||
|
|
||||||
$views[] = array(
|
|
||||||
'viewKey' => $candidate_engine->getDocumentEngineKey(),
|
|
||||||
'icon' => $view_icon,
|
|
||||||
'color' => $view_color,
|
|
||||||
'name' => $label,
|
|
||||||
'engineURI' => $candidate_engine->getRenderURI($ref),
|
|
||||||
'viewURI' => $view_uri,
|
|
||||||
'loadingMarkup' => hsprintf('%s', $loading),
|
|
||||||
'canEncode' => $candidate_engine->canConfigureEncoding($ref),
|
|
||||||
'canHighlight' => $candidate_engine->CanConfigureHighlighting($ref),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$viewport_id = celerity_generate_unique_node_id();
|
|
||||||
$control_id = celerity_generate_unique_node_id();
|
|
||||||
$icon = $engine->newDocumentIcon($ref);
|
|
||||||
|
|
||||||
if ($engine->shouldRenderAsync($ref)) {
|
|
||||||
$content = $engine->newLoadingContent($ref);
|
|
||||||
$config = array(
|
|
||||||
'renderControlID' => $control_id,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$content = $engine->newDocument($ref);
|
|
||||||
$config = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
Javelin::initBehavior('document-engine', $config);
|
|
||||||
|
|
||||||
$viewport = phutil_tag(
|
|
||||||
'div',
|
|
||||||
array(
|
|
||||||
'id' => $viewport_id,
|
|
||||||
),
|
|
||||||
$content);
|
|
||||||
|
|
||||||
$meta = array(
|
|
||||||
'viewportID' => $viewport_id,
|
|
||||||
'viewKey' => $engine->getDocumentEngineKey(),
|
|
||||||
'views' => $views,
|
|
||||||
'standaloneURI' => $engine->getRenderURI($ref),
|
|
||||||
'encode' => array(
|
|
||||||
'icon' => 'fa-font',
|
|
||||||
'name' => pht('Change Text Encoding...'),
|
|
||||||
'uri' => '/services/encoding/',
|
|
||||||
'value' => $encode_setting,
|
|
||||||
),
|
|
||||||
'highlight' => array(
|
|
||||||
'icon' => 'fa-lightbulb-o',
|
|
||||||
'name' => pht('Highlight As...'),
|
|
||||||
'uri' => '/services/highlight/',
|
|
||||||
'value' => $highlight_setting,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
$view_button = id(new PHUIButtonView())
|
|
||||||
->setTag('a')
|
|
||||||
->setText(pht('View Options'))
|
|
||||||
->setIcon('fa-file-image-o')
|
|
||||||
->setColor(PHUIButtonView::GREY)
|
|
||||||
->setID($control_id)
|
|
||||||
->setMetadata($meta)
|
|
||||||
->setDropdown(true)
|
|
||||||
->addSigil('document-engine-view-dropdown');
|
|
||||||
|
|
||||||
$header = id(new PHUIHeaderView())
|
|
||||||
->setHeaderIcon($icon)
|
|
||||||
->setHeader($ref->getName())
|
|
||||||
->addActionLink($view_button);
|
|
||||||
|
|
||||||
return id(new PHUIObjectBoxView())
|
|
||||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
|
||||||
->setHeader($header)
|
|
||||||
->appendChild($viewport);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,18 +152,6 @@ abstract class PhabricatorDocumentEngine
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRenderURI(PhabricatorDocumentRef $ref) {
|
|
||||||
$file = $ref->getFile();
|
|
||||||
if (!$file) {
|
|
||||||
throw new PhutilMethodNotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
$engine_key = $this->getDocumentEngineKey();
|
|
||||||
$file_phid = $file->getPHID();
|
|
||||||
|
|
||||||
return "/file/document/{$engine_key}/{$file_phid}/";
|
|
||||||
}
|
|
||||||
|
|
||||||
final public static function getEnginesForRef(
|
final public static function getEnginesForRef(
|
||||||
PhabricatorUser $viewer,
|
PhabricatorUser $viewer,
|
||||||
PhabricatorDocumentRef $ref) {
|
PhabricatorDocumentRef $ref) {
|
||||||
|
|
|
@ -0,0 +1,285 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class PhabricatorDocumentRenderingEngine
|
||||||
|
extends Phobject {
|
||||||
|
|
||||||
|
private $request;
|
||||||
|
private $controller;
|
||||||
|
private $activeEngine;
|
||||||
|
|
||||||
|
final public function setRequest(AphrontRequest $request) {
|
||||||
|
$this->request = $request;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function getRequest() {
|
||||||
|
if (!$this->request) {
|
||||||
|
throw new PhutilInvalidStateException('setRequest');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->request;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function setController(PhabricatorController $controller) {
|
||||||
|
$this->controller = $controller;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function getController() {
|
||||||
|
if (!$this->controller) {
|
||||||
|
throw new PhutilInvalidStateException('setController');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
final protected function getActiveEngine() {
|
||||||
|
if (!$this->activeEngine) {
|
||||||
|
throw new PhutilInvalidStateException('setActiveEngine');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->activeEngine;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function newDocumentView(PhabricatorDocumentRef $ref) {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$viewer = $request->getViewer();
|
||||||
|
|
||||||
|
$engines = PhabricatorDocumentEngine::getEnginesForRef($viewer, $ref);
|
||||||
|
|
||||||
|
$engine_key = $this->getSelectedDocumentEngineKey();
|
||||||
|
if (!isset($engines[$engine_key])) {
|
||||||
|
$engine_key = head_key($engines);
|
||||||
|
}
|
||||||
|
$engine = $engines[$engine_key];
|
||||||
|
|
||||||
|
$lines = $request->getURILineRange('lines', 1000);
|
||||||
|
if ($lines) {
|
||||||
|
$engine->setHighlightedLines(range($lines[0], $lines[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
$encode_setting = $request->getStr('encode');
|
||||||
|
if (strlen($encode_setting)) {
|
||||||
|
$engine->setEncodingConfiguration($encode_setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
$highlight_setting = $request->getStr('highlight');
|
||||||
|
if (strlen($highlight_setting)) {
|
||||||
|
$engine->setHighlightingConfiguration($highlight_setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
$views = array();
|
||||||
|
foreach ($engines as $candidate_key => $candidate_engine) {
|
||||||
|
$label = $candidate_engine->getViewAsLabel($ref);
|
||||||
|
if ($label === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$view_uri = $this->newRefViewURI($ref, $candidate_engine);
|
||||||
|
|
||||||
|
$view_icon = $candidate_engine->getViewAsIconIcon($ref);
|
||||||
|
$view_color = $candidate_engine->getViewAsIconColor($ref);
|
||||||
|
$loading = $candidate_engine->newLoadingContent($ref);
|
||||||
|
|
||||||
|
$views[] = array(
|
||||||
|
'viewKey' => $candidate_engine->getDocumentEngineKey(),
|
||||||
|
'icon' => $view_icon,
|
||||||
|
'color' => $view_color,
|
||||||
|
'name' => $label,
|
||||||
|
'engineURI' => $this->newRefRenderURI($ref, $candidate_engine),
|
||||||
|
'viewURI' => $view_uri,
|
||||||
|
'loadingMarkup' => hsprintf('%s', $loading),
|
||||||
|
'canEncode' => $candidate_engine->canConfigureEncoding($ref),
|
||||||
|
'canHighlight' => $candidate_engine->CanConfigureHighlighting($ref),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$viewport_id = celerity_generate_unique_node_id();
|
||||||
|
$control_id = celerity_generate_unique_node_id();
|
||||||
|
$icon = $engine->newDocumentIcon($ref);
|
||||||
|
|
||||||
|
if ($engine->shouldRenderAsync($ref)) {
|
||||||
|
$content = $engine->newLoadingContent($ref);
|
||||||
|
$config = array(
|
||||||
|
'renderControlID' => $control_id,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$content = $engine->newDocument($ref);
|
||||||
|
$config = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
Javelin::initBehavior('document-engine', $config);
|
||||||
|
|
||||||
|
$viewport = phutil_tag(
|
||||||
|
'div',
|
||||||
|
array(
|
||||||
|
'id' => $viewport_id,
|
||||||
|
),
|
||||||
|
$content);
|
||||||
|
|
||||||
|
$meta = array(
|
||||||
|
'viewportID' => $viewport_id,
|
||||||
|
'viewKey' => $engine->getDocumentEngineKey(),
|
||||||
|
'views' => $views,
|
||||||
|
'encode' => array(
|
||||||
|
'icon' => 'fa-font',
|
||||||
|
'name' => pht('Change Text Encoding...'),
|
||||||
|
'uri' => '/services/encoding/',
|
||||||
|
'value' => $encode_setting,
|
||||||
|
),
|
||||||
|
'highlight' => array(
|
||||||
|
'icon' => 'fa-lightbulb-o',
|
||||||
|
'name' => pht('Highlight As...'),
|
||||||
|
'uri' => '/services/highlight/',
|
||||||
|
'value' => $highlight_setting,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$view_button = id(new PHUIButtonView())
|
||||||
|
->setTag('a')
|
||||||
|
->setText(pht('View Options'))
|
||||||
|
->setIcon('fa-file-image-o')
|
||||||
|
->setColor(PHUIButtonView::GREY)
|
||||||
|
->setID($control_id)
|
||||||
|
->setMetadata($meta)
|
||||||
|
->setDropdown(true)
|
||||||
|
->addSigil('document-engine-view-dropdown');
|
||||||
|
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeaderIcon($icon)
|
||||||
|
->setHeader($ref->getName())
|
||||||
|
->addActionLink($view_button);
|
||||||
|
|
||||||
|
return id(new PHUIObjectBoxView())
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
|
->setHeader($header)
|
||||||
|
->appendChild($viewport);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract protected function newRefViewURI(
|
||||||
|
PhabricatorDocumentRef $ref,
|
||||||
|
PhabricatorDocumentEngine $engine);
|
||||||
|
|
||||||
|
abstract protected function newRefRenderURI(
|
||||||
|
PhabricatorDocumentRef $ref,
|
||||||
|
PhabricatorDocumentEngine $engine);
|
||||||
|
|
||||||
|
protected function getSelectedDocumentEngineKey() {
|
||||||
|
return $this->getRequest()->getURIData('engineKey');
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function newRenderResponse(PhabricatorDocumentRef $ref) {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$viewer = $request->getViewer();
|
||||||
|
|
||||||
|
$engines = PhabricatorDocumentEngine::getEnginesForRef($viewer, $ref);
|
||||||
|
$engine_key = $request->getURIData('engineKey');
|
||||||
|
if (!isset($engines[$engine_key])) {
|
||||||
|
return $this->newErrorResponse(
|
||||||
|
$ref,
|
||||||
|
pht(
|
||||||
|
'The engine ("%s") is unknown, or unable to render this document.',
|
||||||
|
$engine_key));
|
||||||
|
}
|
||||||
|
$engine = $engines[$engine_key];
|
||||||
|
|
||||||
|
$this->activeEngine = $engine;
|
||||||
|
|
||||||
|
$encode_setting = $request->getStr('encode');
|
||||||
|
if (strlen($encode_setting)) {
|
||||||
|
$engine->setEncodingConfiguration($encode_setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
$highlight_setting = $request->getStr('highlight');
|
||||||
|
if (strlen($highlight_setting)) {
|
||||||
|
$engine->setHighlightingConfiguration($highlight_setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$content = $engine->newDocument($ref);
|
||||||
|
} catch (Exception $ex) {
|
||||||
|
return $this->newErrorResponse($ref, $ex->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->newContentResponse($ref, $content);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function newErrorResponse(
|
||||||
|
PhabricatorDocumentRef $ref,
|
||||||
|
$message) {
|
||||||
|
|
||||||
|
$container = phutil_tag(
|
||||||
|
'div',
|
||||||
|
array(
|
||||||
|
'class' => 'document-engine-error',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
id(new PHUIIconView())
|
||||||
|
->setIcon('fa-exclamation-triangle red'),
|
||||||
|
' ',
|
||||||
|
$message,
|
||||||
|
));
|
||||||
|
|
||||||
|
return $this->newContentResponse($ref, $container);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function newContentResponse(
|
||||||
|
PhabricatorDocumentRef $ref,
|
||||||
|
$content) {
|
||||||
|
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$viewer = $request->getViewer();
|
||||||
|
$controller = $this->getController();
|
||||||
|
|
||||||
|
if ($request->isAjax()) {
|
||||||
|
return id(new AphrontAjaxResponse())
|
||||||
|
->setContent(
|
||||||
|
array(
|
||||||
|
'markup' => hsprintf('%s', $content),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$crumbs = $this->newCrumbs($ref);
|
||||||
|
if ($crumbs) {
|
||||||
|
$crumbs->setBorder(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$content_frame = id(new PHUIObjectBoxView())
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
|
->appendChild($content);
|
||||||
|
|
||||||
|
$page_frame = id(new PHUITwoColumnView())
|
||||||
|
->setFooter($content_frame);
|
||||||
|
|
||||||
|
return $controller->newPage()
|
||||||
|
->setCrumbs($crumbs)
|
||||||
|
->setTitle(
|
||||||
|
array(
|
||||||
|
$ref->getName(),
|
||||||
|
pht('Standalone'),
|
||||||
|
))
|
||||||
|
->appendChild($page_frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newCrumbs(PhabricatorDocumentRef $ref) {
|
||||||
|
$controller = $this->getController();
|
||||||
|
$crumbs = $controller->buildApplicationCrumbsForEditEngine();
|
||||||
|
|
||||||
|
$this->addApplicationCrumbs($ref, $crumbs);
|
||||||
|
|
||||||
|
$engine = $this->getActiveEngine();
|
||||||
|
$label = $engine->getViewAsLabel($ref);
|
||||||
|
if ($label) {
|
||||||
|
$crumbs->addTextCrumb($label);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $crumbs;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function addApplicationCrumbs(
|
||||||
|
PhabricatorDocumentRef $ref,
|
||||||
|
PHUICrumbsView $crumbs) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorFileDocumentRenderingEngine
|
||||||
|
extends PhabricatorDocumentRenderingEngine {
|
||||||
|
|
||||||
|
protected function newRefViewURI(
|
||||||
|
PhabricatorDocumentRef $ref,
|
||||||
|
PhabricatorDocumentEngine $engine) {
|
||||||
|
|
||||||
|
$file = $ref->getFile();
|
||||||
|
$engine_key = $engine->getDocumentEngineKey();
|
||||||
|
|
||||||
|
return urisprintf(
|
||||||
|
'/file/view/%d/%s/',
|
||||||
|
$file->getID(),
|
||||||
|
$engine_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newRefRenderURI(
|
||||||
|
PhabricatorDocumentRef $ref,
|
||||||
|
PhabricatorDocumentEngine $engine) {
|
||||||
|
$file = $ref->getFile();
|
||||||
|
if (!$file) {
|
||||||
|
throw new PhutilMethodNotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
$engine_key = $engine->getDocumentEngineKey();
|
||||||
|
$file_phid = $file->getPHID();
|
||||||
|
|
||||||
|
return urisprintf(
|
||||||
|
'/file/document/%s/%s/',
|
||||||
|
$engine_key,
|
||||||
|
$file_phid);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function addApplicationCrumbs(
|
||||||
|
PhabricatorDocumentRef $ref,
|
||||||
|
PHUICrumbsView $crumbs) {
|
||||||
|
|
||||||
|
$file = $ref->getFile();
|
||||||
|
if ($file) {
|
||||||
|
$crumbs->addTextCrumb($file->getMonogram(), $file->getInfoURI());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue