1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-22 20:51:10 +01:00

Allow CelerityResourceResponse to hold resources from multiple maps

Summary:
Ref T4222. Currently, CelerityResourceResponse holds response resources in flat maps. Instead, specify which map resources appear in.

Also, provide `requireResource()` and `initBehavior()` APIs on the Controller and View base classes. These provide a cleaner abstraction over `require_celerity_resource()` and `Javelin::initBehavior()`, but are otherwise the same. Move a few callsites over.

Test Plan:
  - Reloaded pages.
  - Browsed around Differential.

Reviewers: btrahan, hach-que

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T4222

Differential Revision: https://secure.phabricator.com/D7876
This commit is contained in:
epriestley 2014-01-02 11:59:35 -08:00
parent 09341be10f
commit 31b6f69ff7
18 changed files with 146 additions and 53 deletions

View file

@ -9,7 +9,6 @@ abstract class AphrontController extends Phobject {
private $currentApplication; private $currentApplication;
private $delegatingController; private $delegatingController;
public function setDelegatingController( public function setDelegatingController(
AphrontController $delegating_controller) { AphrontController $delegating_controller) {
$this->delegatingController = $delegating_controller; $this->delegatingController = $delegating_controller;
@ -64,4 +63,24 @@ abstract class AphrontController extends Phobject {
return $this->currentApplication; return $this->currentApplication;
} }
public function getDefaultResourceSource() {
throw new Exception(
pht(
'A Controller must implement getDefaultResourceSource() before you '.
'can invoke requireResource() or initBehavior().'));
}
public function requireResource($symbol) {
$response = CelerityAPI::getStaticResourceResponse();
$response->requireResource($symbol, $this->getDefaultResourceSource());
return $this;
}
public function initBehavior($name, $config = array()) {
Javelin::initBehavior(
$name,
$config,
$this->getDefaultResourceSource());
}
} }

View file

@ -408,4 +408,9 @@ abstract class PhabricatorController extends AphrontController {
return array($can_act, $message); return array($can_act, $message);
} }
public function getDefaultResourceSource() {
return 'phabricator';
}
} }

View file

@ -497,8 +497,8 @@ final class DifferentialRevisionViewController extends DifferentialController {
); );
} }
require_celerity_resource('phabricator-object-selector-css'); $this->requireResource('phabricator-object-selector-css');
require_celerity_resource('javelin-behavior-phabricator-object-selector'); $this->requireResource('javelin-behavior-phabricator-object-selector');
$links[] = array( $links[] = array(
'icon' => 'link', 'icon' => 'link',

View file

@ -48,7 +48,7 @@ final class DifferentialAddCommentView extends AphrontView {
public function render() { public function render() {
require_celerity_resource('differential-revision-add-comment-css'); $this->requireResource('differential-revision-add-comment-css');
$is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business'); $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');

View file

@ -94,8 +94,8 @@ final class DifferentialChangesetDetailView extends AphrontView {
} }
public function render() { public function render() {
require_celerity_resource('differential-changeset-view-css'); $this->requireResource('differential-changeset-view-css');
require_celerity_resource('syntax-highlighting-css'); $this->requireResource('syntax-highlighting-css');
Javelin::initBehavior('phabricator-oncopy', array()); Javelin::initBehavior('phabricator-oncopy', array());

View file

@ -103,7 +103,7 @@ final class DifferentialChangesetListView extends AphrontView {
} }
public function render() { public function render() {
require_celerity_resource('differential-changeset-view-css'); $this->requireResource('differential-changeset-view-css');
$changesets = $this->changesets; $changesets = $this->changesets;
@ -183,20 +183,20 @@ final class DifferentialChangesetListView extends AphrontView {
$output[] = $detail->render(); $output[] = $detail->render();
} }
require_celerity_resource('aphront-tooltip-css'); $this->requireResource('aphront-tooltip-css');
Javelin::initBehavior('differential-populate', array( $this->initBehavior('differential-populate', array(
'registry' => $mapping, 'registry' => $mapping,
'whitespace' => $this->whitespace, 'whitespace' => $this->whitespace,
'uri' => $this->renderURI, 'uri' => $this->renderURI,
)); ));
Javelin::initBehavior('differential-show-more', array( $this->initBehavior('differential-show-more', array(
'uri' => $this->renderURI, 'uri' => $this->renderURI,
'whitespace' => $this->whitespace, 'whitespace' => $this->whitespace,
)); ));
Javelin::initBehavior('differential-comment-jump', array()); $this->initBehavior('differential-comment-jump', array());
if ($this->inlineURI) { if ($this->inlineURI) {
$undo_templates = $this->renderUndoTemplates(); $undo_templates = $this->renderUndoTemplates();

View file

@ -54,8 +54,8 @@ final class DifferentialDiffTableOfContentsView extends AphrontView {
public function render() { public function render() {
require_celerity_resource('differential-core-view-css'); $this->requireResource('differential-core-view-css');
require_celerity_resource('differential-table-of-contents-css'); $this->requireResource('differential-table-of-contents-css');
$rows = array(); $rows = array();

View file

@ -20,7 +20,7 @@ final class DifferentialLocalCommitsView extends AphrontView {
return null; return null;
} }
require_celerity_resource('differential-local-commits-view-css'); $this->requireResource('differential-local-commits-view-css');
$has_tree = false; $has_tree = false;
$has_local = false; $has_local = false;

View file

@ -97,10 +97,10 @@ final class DifferentialResultsTableView extends AphrontView {
), ),
phutil_tag('th', array('colspan' => 2), $hide_more)); phutil_tag('th', array('colspan' => 2), $hide_more));
Javelin::initBehavior('differential-show-field-details'); $this->initBehavior('differential-show-field-details');
} }
require_celerity_resource('differential-results-table-css'); $this->requireResource('differential-results-table-css');
return javelin_tag( return javelin_tag(
'table', 'table',

View file

@ -53,7 +53,7 @@ final class DifferentialRevisionCommentListView extends AphrontView {
public function render() { public function render() {
require_celerity_resource('differential-revision-comment-list-css'); $this->requireResource('differential-revision-comment-list-css');
$engine = new PhabricatorMarkupEngine(); $engine = new PhabricatorMarkupEngine();
$engine->setViewer($this->user); $engine->setViewer($this->user);
@ -154,7 +154,7 @@ final class DifferentialRevisionCommentListView extends AphrontView {
$visible = array_reverse($visible); $visible = array_reverse($visible);
if ($hidden) { if ($hidden) {
Javelin::initBehavior( $this->initBehavior(
'differential-show-all-comments', 'differential-show-all-comments',
array( array(
'markup' => implode("\n", $hidden), 'markup' => implode("\n", $hidden),

View file

@ -67,8 +67,8 @@ final class DifferentialRevisionCommentView extends AphrontView {
throw new Exception("Call setUser() before rendering!"); throw new Exception("Call setUser() before rendering!");
} }
require_celerity_resource('phabricator-remarkup-css'); $this->requireResource('phabricator-remarkup-css');
require_celerity_resource('differential-revision-comment-css'); $this->requireResource('differential-revision-comment-css');
$comment = $this->comment; $comment = $this->comment;

View file

@ -45,7 +45,7 @@ final class DifferentialRevisionDetailView extends AphrontView {
public function render() { public function render() {
require_celerity_resource('differential-core-view-css'); $this->requireResource('differential-core-view-css');
$revision = $this->revision; $revision = $this->revision;
$user = $this->getUser(); $user = $this->getUser();

View file

@ -102,8 +102,8 @@ final class DifferentialRevisionListView extends AphrontView {
-$stale); -$stale);
} }
Javelin::initBehavior('phabricator-tooltips', array()); $this->initBehavior('phabricator-tooltips', array());
require_celerity_resource('aphront-tooltip-css'); $this->requireResource('aphront-tooltip-css');
$flagged = mpull($this->flags, null, 'getObjectPHID'); $flagged = mpull($this->flags, null, 'getObjectPHID');

View file

@ -30,8 +30,8 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
public function render() { public function render() {
require_celerity_resource('differential-core-view-css'); $this->requireResource('differential-core-view-css');
require_celerity_resource('differential-revision-history-css'); $this->requireResource('differential-revision-history-css');
$data = array( $data = array(
array( array(

View file

@ -236,4 +236,8 @@ final class CelerityResourceMap {
return isset($this->packageMap[$name]); return isset($this->packageMap[$name]);
} }
public function getResourceTypeForName($name) {
return $this->resources->getResourceType($name);
}
} }

View file

@ -39,8 +39,12 @@ final class CelerityStaticResourceResponse {
* a behavior will execute only once even if it is initialized multiple times. * a behavior will execute only once even if it is initialized multiple times.
* If $config is nonempty, the behavior will be invoked once for each config. * If $config is nonempty, the behavior will be invoked once for each config.
*/ */
public function initBehavior($behavior, array $config = array()) { public function initBehavior(
$this->requireResource('javelin-behavior-'.$behavior); $behavior,
array $config = array(),
$source_name = 'phabricator') {
$this->requireResource('javelin-behavior-'.$behavior, $source_name);
if (empty($this->behaviors[$behavior])) { if (empty($this->behaviors[$behavior])) {
$this->behaviors[$behavior] = array(); $this->behaviors[$behavior] = array();
@ -53,19 +57,39 @@ final class CelerityStaticResourceResponse {
return $this; return $this;
} }
public function requireResource($symbol) { public function requireResource($symbol, $source_name) {
$this->symbols[$symbol] = true; if (isset($this->symbols[$source_name][$symbol])) {
return $this;
}
// Verify that the resource exists.
$map = CelerityResourceMap::getNamedInstance($source_name);
$name = $map->getResourceNameForSymbol($symbol);
if ($name === null) {
throw new Exception(
pht(
'No resource with symbol "%s" exists in source "%s"!',
$symbol,
$source_name));
}
$this->symbols[$source_name][$symbol] = true;
$this->needsResolve = true; $this->needsResolve = true;
return $this; return $this;
} }
private function resolveResources() { private function resolveResources() {
if ($this->needsResolve) { if ($this->needsResolve) {
$map = CelerityResourceMap::getNamedInstance('phabricator'); $this->packaged = array();
foreach ($this->symbols as $source_name => $symbols_map) {
$symbols = array_keys($symbols_map);
$symbols = array_keys($this->symbols); $map = CelerityResourceMap::getNamedInstance($source_name);
$this->packaged = $map->getPackagedNamesForSymbols($symbols); $packaged = $map->getPackagedNamesForSymbols($symbols);
$this->packaged[$source_name] = $packaged;
}
$this->needsResolve = false; $this->needsResolve = false;
} }
return $this; return $this;
@ -74,24 +98,34 @@ final class CelerityStaticResourceResponse {
public function renderSingleResource($symbol, $source_name) { public function renderSingleResource($symbol, $source_name) {
$map = CelerityResourceMap::getNamedInstance($source_name); $map = CelerityResourceMap::getNamedInstance($source_name);
$packaged = $map->getPackagedNamesForSymbols(array($symbol)); $packaged = $map->getPackagedNamesForSymbols(array($symbol));
return $this->renderPackagedResources($packaged); return $this->renderPackagedResources($map, $packaged);
} }
public function renderResourcesOfType($type) { public function renderResourcesOfType($type) {
$this->resolveResources(); $this->resolveResources();
$resources = array(); $result = array();
foreach ($this->packaged as $name) { foreach ($this->packaged as $source_name => $resource_names) {
$resource_type = CelerityResourceTransformer::getResourceType($name); $map = CelerityResourceMap::getNamedInstance($source_name);
if ($resource_type == $type) {
$resources[] = $name; $resources_of_type = array();
foreach ($resource_names as $resource_name) {
$resource_type = $map->getResourceTypeForName($resource_name);
if ($resource_type == $type) {
$resources_of_type[] = $resource_name;
}
} }
$result[] = $this->renderPackagedResources($map, $resources_of_type);
} }
return $this->renderPackagedResources($resources); return phutil_implode_html('', $result);
} }
private function renderPackagedResources(array $resources) { private function renderPackagedResources(
CelerityResourceMap $map,
array $resources) {
$output = array(); $output = array();
foreach ($resources as $name) { foreach ($resources as $name) {
if (isset($this->hasRendered[$name])) { if (isset($this->hasRendered[$name])) {
@ -99,15 +133,19 @@ final class CelerityStaticResourceResponse {
} }
$this->hasRendered[$name] = true; $this->hasRendered[$name] = true;
$output[] = $this->renderResource($name); $output[] = $this->renderResource($map, $name);
$output[] = "\n";
} }
return phutil_implode_html('', $output);
return $output;
} }
private function renderResource($name) { private function renderResource(
$uri = $this->getURI($name); CelerityResourceMap $map,
$type = CelerityResourceTransformer::getResourceType($name); $name) {
$uri = $this->getURI($map, $name);
$type = $map->getResourceTypeForName($name);
switch ($type) { switch ($type) {
case 'css': case 'css':
return phutil_tag( return phutil_tag(
@ -126,7 +164,12 @@ final class CelerityStaticResourceResponse {
), ),
''); '');
} }
throw new Exception("Unable to render resource.");
throw new Exception(
pht(
'Unable to render resource "%s", which has unknown type "%s".',
$name,
$type));
} }
public function renderHTMLFooter() { public function renderHTMLFooter() {
@ -225,8 +268,11 @@ final class CelerityStaticResourceResponse {
$this->resolveResources(); $this->resolveResources();
$resources = array(); $resources = array();
foreach ($this->packaged as $resource) { foreach ($this->packaged as $source_name => $resource_names) {
$resources[] = $this->getURI($resource); $map = CelerityResourceMap::getNamedInstance($source_name);
foreach ($resource_names as $resource_name) {
$resources[] = $this->getURI($map, $resource_name);
}
} }
if ($resources) { if ($resources) {
$response['javelin_resources'] = $resources; $response['javelin_resources'] = $resources;
@ -235,8 +281,10 @@ final class CelerityStaticResourceResponse {
return $response; return $response;
} }
private function getURI($name) { private function getURI(
$map = CelerityResourceMap::getNamedInstance('phabricator'); CelerityResourceMap $map,
$name) {
$uri = $map->getURIForName($name); $uri = $map->getURIForName($name);
// In developer mode, we dump file modification times into the URI. When a // In developer mode, we dump file modification times into the URI. When a

View file

@ -15,9 +15,9 @@
* *
* @group celerity * @group celerity
*/ */
function require_celerity_resource($symbol) { function require_celerity_resource($symbol, $source_name = 'phabricator') {
$response = CelerityAPI::getStaticResourceResponse(); $response = CelerityAPI::getStaticResourceResponse();
$response->requireResource($symbol); $response->requireResource($symbol, $source_name);
} }

View file

@ -128,6 +128,23 @@ abstract class AphrontView extends Phobject
return $children; return $children;
} }
public function getDefaultResourceSource() {
return 'phabricator';
}
public function requireResource($symbol) {
$response = CelerityAPI::getStaticResourceResponse();
$response->requireResource($symbol, $this->getDefaultResourceSource());
return $this;
}
public function initBehavior($name, $config = array()) {
Javelin::initBehavior(
$name,
$config,
$this->getDefaultResourceSource());
}
/* -( Rendering )---------------------------------------------------------- */ /* -( Rendering )---------------------------------------------------------- */