Index: src/aphront/AphrontController.php =================================================================== --- src/aphront/AphrontController.php +++ src/aphront/AphrontController.php @@ -9,7 +9,6 @@ private $currentApplication; private $delegatingController; - public function setDelegatingController( AphrontController $delegating_controller) { $this->delegatingController = $delegating_controller; @@ -64,4 +63,24 @@ 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()); + } + } Index: src/applications/base/controller/PhabricatorController.php =================================================================== --- src/applications/base/controller/PhabricatorController.php +++ src/applications/base/controller/PhabricatorController.php @@ -408,4 +408,9 @@ return array($can_act, $message); } + public function getDefaultResourceSource() { + return 'phabricator'; + } + + } Index: src/applications/differential/controller/DifferentialRevisionViewController.php =================================================================== --- src/applications/differential/controller/DifferentialRevisionViewController.php +++ src/applications/differential/controller/DifferentialRevisionViewController.php @@ -497,8 +497,8 @@ ); } - require_celerity_resource('phabricator-object-selector-css'); - require_celerity_resource('javelin-behavior-phabricator-object-selector'); + $this->requireResource('phabricator-object-selector-css'); + $this->requireResource('javelin-behavior-phabricator-object-selector'); $links[] = array( 'icon' => 'link', Index: src/applications/differential/view/DifferentialAddCommentView.php =================================================================== --- src/applications/differential/view/DifferentialAddCommentView.php +++ src/applications/differential/view/DifferentialAddCommentView.php @@ -48,7 +48,7 @@ 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'); Index: src/applications/differential/view/DifferentialChangesetDetailView.php =================================================================== --- src/applications/differential/view/DifferentialChangesetDetailView.php +++ src/applications/differential/view/DifferentialChangesetDetailView.php @@ -94,8 +94,8 @@ } public function render() { - require_celerity_resource('differential-changeset-view-css'); - require_celerity_resource('syntax-highlighting-css'); + $this->requireResource('differential-changeset-view-css'); + $this->requireResource('syntax-highlighting-css'); Javelin::initBehavior('phabricator-oncopy', array()); Index: src/applications/differential/view/DifferentialChangesetListView.php =================================================================== --- src/applications/differential/view/DifferentialChangesetListView.php +++ src/applications/differential/view/DifferentialChangesetListView.php @@ -103,7 +103,7 @@ } public function render() { - require_celerity_resource('differential-changeset-view-css'); + $this->requireResource('differential-changeset-view-css'); $changesets = $this->changesets; @@ -183,20 +183,20 @@ $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, 'whitespace' => $this->whitespace, 'uri' => $this->renderURI, )); - Javelin::initBehavior('differential-show-more', array( + $this->initBehavior('differential-show-more', array( 'uri' => $this->renderURI, 'whitespace' => $this->whitespace, )); - Javelin::initBehavior('differential-comment-jump', array()); + $this->initBehavior('differential-comment-jump', array()); if ($this->inlineURI) { $undo_templates = $this->renderUndoTemplates(); Index: src/applications/differential/view/DifferentialDiffTableOfContentsView.php =================================================================== --- src/applications/differential/view/DifferentialDiffTableOfContentsView.php +++ src/applications/differential/view/DifferentialDiffTableOfContentsView.php @@ -54,8 +54,8 @@ public function render() { - require_celerity_resource('differential-core-view-css'); - require_celerity_resource('differential-table-of-contents-css'); + $this->requireResource('differential-core-view-css'); + $this->requireResource('differential-table-of-contents-css'); $rows = array(); Index: src/applications/differential/view/DifferentialLocalCommitsView.php =================================================================== --- src/applications/differential/view/DifferentialLocalCommitsView.php +++ src/applications/differential/view/DifferentialLocalCommitsView.php @@ -20,7 +20,7 @@ return null; } - require_celerity_resource('differential-local-commits-view-css'); + $this->requireResource('differential-local-commits-view-css'); $has_tree = false; $has_local = false; Index: src/applications/differential/view/DifferentialResultsTableView.php =================================================================== --- src/applications/differential/view/DifferentialResultsTableView.php +++ src/applications/differential/view/DifferentialResultsTableView.php @@ -97,10 +97,10 @@ ), 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( 'table', Index: src/applications/differential/view/DifferentialRevisionCommentListView.php =================================================================== --- src/applications/differential/view/DifferentialRevisionCommentListView.php +++ src/applications/differential/view/DifferentialRevisionCommentListView.php @@ -53,7 +53,7 @@ public function render() { - require_celerity_resource('differential-revision-comment-list-css'); + $this->requireResource('differential-revision-comment-list-css'); $engine = new PhabricatorMarkupEngine(); $engine->setViewer($this->user); @@ -154,7 +154,7 @@ $visible = array_reverse($visible); if ($hidden) { - Javelin::initBehavior( + $this->initBehavior( 'differential-show-all-comments', array( 'markup' => implode("\n", $hidden), Index: src/applications/differential/view/DifferentialRevisionCommentView.php =================================================================== --- src/applications/differential/view/DifferentialRevisionCommentView.php +++ src/applications/differential/view/DifferentialRevisionCommentView.php @@ -67,8 +67,8 @@ throw new Exception("Call setUser() before rendering!"); } - require_celerity_resource('phabricator-remarkup-css'); - require_celerity_resource('differential-revision-comment-css'); + $this->requireResource('phabricator-remarkup-css'); + $this->requireResource('differential-revision-comment-css'); $comment = $this->comment; Index: src/applications/differential/view/DifferentialRevisionDetailView.php =================================================================== --- src/applications/differential/view/DifferentialRevisionDetailView.php +++ src/applications/differential/view/DifferentialRevisionDetailView.php @@ -45,7 +45,7 @@ public function render() { - require_celerity_resource('differential-core-view-css'); + $this->requireResource('differential-core-view-css'); $revision = $this->revision; $user = $this->getUser(); Index: src/applications/differential/view/DifferentialRevisionListView.php =================================================================== --- src/applications/differential/view/DifferentialRevisionListView.php +++ src/applications/differential/view/DifferentialRevisionListView.php @@ -102,8 +102,8 @@ -$stale); } - Javelin::initBehavior('phabricator-tooltips', array()); - require_celerity_resource('aphront-tooltip-css'); + $this->initBehavior('phabricator-tooltips', array()); + $this->requireResource('aphront-tooltip-css'); $flagged = mpull($this->flags, null, 'getObjectPHID'); Index: src/applications/differential/view/DifferentialRevisionUpdateHistoryView.php =================================================================== --- src/applications/differential/view/DifferentialRevisionUpdateHistoryView.php +++ src/applications/differential/view/DifferentialRevisionUpdateHistoryView.php @@ -30,8 +30,8 @@ public function render() { - require_celerity_resource('differential-core-view-css'); - require_celerity_resource('differential-revision-history-css'); + $this->requireResource('differential-core-view-css'); + $this->requireResource('differential-revision-history-css'); $data = array( array( Index: src/infrastructure/celerity/CelerityResourceMap.php =================================================================== --- src/infrastructure/celerity/CelerityResourceMap.php +++ src/infrastructure/celerity/CelerityResourceMap.php @@ -236,4 +236,8 @@ return isset($this->packageMap[$name]); } + public function getResourceTypeForName($name) { + return $this->resources->getResourceType($name); + } + } Index: src/infrastructure/celerity/CelerityStaticResourceResponse.php =================================================================== --- src/infrastructure/celerity/CelerityStaticResourceResponse.php +++ src/infrastructure/celerity/CelerityStaticResourceResponse.php @@ -39,8 +39,12 @@ * 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. */ - public function initBehavior($behavior, array $config = array()) { - $this->requireResource('javelin-behavior-'.$behavior); + public function initBehavior( + $behavior, + array $config = array(), + $source_name = 'phabricator') { + + $this->requireResource('javelin-behavior-'.$behavior, $source_name); if (empty($this->behaviors[$behavior])) { $this->behaviors[$behavior] = array(); @@ -53,19 +57,39 @@ return $this; } - public function requireResource($symbol) { - $this->symbols[$symbol] = true; + public function requireResource($symbol, $source_name) { + 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; + return $this; } private function resolveResources() { 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); - $this->packaged = $map->getPackagedNamesForSymbols($symbols); + $map = CelerityResourceMap::getNamedInstance($source_name); + $packaged = $map->getPackagedNamesForSymbols($symbols); + $this->packaged[$source_name] = $packaged; + } $this->needsResolve = false; } return $this; @@ -74,24 +98,34 @@ public function renderSingleResource($symbol, $source_name) { $map = CelerityResourceMap::getNamedInstance($source_name); $packaged = $map->getPackagedNamesForSymbols(array($symbol)); - return $this->renderPackagedResources($packaged); + return $this->renderPackagedResources($map, $packaged); } public function renderResourcesOfType($type) { $this->resolveResources(); - $resources = array(); - foreach ($this->packaged as $name) { - $resource_type = CelerityResourceTransformer::getResourceType($name); - if ($resource_type == $type) { - $resources[] = $name; + $result = array(); + foreach ($this->packaged as $source_name => $resource_names) { + $map = CelerityResourceMap::getNamedInstance($source_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(); foreach ($resources as $name) { if (isset($this->hasRendered[$name])) { @@ -99,15 +133,19 @@ } $this->hasRendered[$name] = true; - $output[] = $this->renderResource($name); - $output[] = "\n"; + $output[] = $this->renderResource($map, $name); } - return phutil_implode_html('', $output); + + return $output; } - private function renderResource($name) { - $uri = $this->getURI($name); - $type = CelerityResourceTransformer::getResourceType($name); + private function renderResource( + CelerityResourceMap $map, + $name) { + + $uri = $this->getURI($map, $name); + $type = $map->getResourceTypeForName($name); + switch ($type) { case 'css': return phutil_tag( @@ -126,7 +164,12 @@ ), ''); } - 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() { @@ -225,8 +268,11 @@ $this->resolveResources(); $resources = array(); - foreach ($this->packaged as $resource) { - $resources[] = $this->getURI($resource); + foreach ($this->packaged as $source_name => $resource_names) { + $map = CelerityResourceMap::getNamedInstance($source_name); + foreach ($resource_names as $resource_name) { + $resources[] = $this->getURI($map, $resource_name); + } } if ($resources) { $response['javelin_resources'] = $resources; @@ -235,8 +281,10 @@ return $response; } - private function getURI($name) { - $map = CelerityResourceMap::getNamedInstance('phabricator'); + private function getURI( + CelerityResourceMap $map, + $name) { + $uri = $map->getURIForName($name); // In developer mode, we dump file modification times into the URI. When a Index: src/infrastructure/celerity/api.php =================================================================== --- src/infrastructure/celerity/api.php +++ src/infrastructure/celerity/api.php @@ -15,9 +15,9 @@ * * @group celerity */ -function require_celerity_resource($symbol) { +function require_celerity_resource($symbol, $source_name = 'phabricator') { $response = CelerityAPI::getStaticResourceResponse(); - $response->requireResource($symbol); + $response->requireResource($symbol, $source_name); } Index: src/view/AphrontView.php =================================================================== --- src/view/AphrontView.php +++ src/view/AphrontView.php @@ -128,6 +128,23 @@ 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 )---------------------------------------------------------- */