Celerity, a Haste-style static resource management system.
This commit is contained in:
		
							
								
								
									
										32
									
								
								scripts/__init_script__.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								scripts/__init_script__.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2011 Facebook, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *   http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
$include_path = ini_get('include_path');
 | 
			
		||||
ini_set('include_path', $include_path.':'.dirname(__FILE__).'/../../');
 | 
			
		||||
@require_once 'libphutil/src/__phutil_library_init__.php';
 | 
			
		||||
if (!@constant('__LIBPHUTIL__')) {
 | 
			
		||||
  echo "ERROR: Unable to load libphutil. Update your PHP 'include_path' to ".
 | 
			
		||||
       "include the parent directory of libphutil/.\n";
 | 
			
		||||
  exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (!ini_get('date.timezone')) {
 | 
			
		||||
  date_default_timezone_set('America/Los_Angeles');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
phutil_load_library(dirname(__FILE__).'/../src/');
 | 
			
		||||
							
								
								
									
										102
									
								
								scripts/celerity_mapper.php
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										102
									
								
								scripts/celerity_mapper.php
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,102 @@
 | 
			
		||||
#!/usr/bin/env php
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
require_once dirname(__FILE__).'/__init_script__.php';
 | 
			
		||||
 | 
			
		||||
if ($argc != 2) {
 | 
			
		||||
  $self = basename($argv[0]);
 | 
			
		||||
  echo "usage: {$self} <webroot>\n";
 | 
			
		||||
  exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
phutil_require_module('phutil', 'filesystem');
 | 
			
		||||
phutil_require_module('phutil', 'filesystem/filefinder');
 | 
			
		||||
phutil_require_module('phutil', 'future/exec');
 | 
			
		||||
phutil_require_module('phutil', 'parser/docblock');
 | 
			
		||||
 | 
			
		||||
$root = Filesystem::resolvePath($argv[1]);
 | 
			
		||||
 | 
			
		||||
echo "Finding static resources...\n";
 | 
			
		||||
$files = id(new FileFinder($root))
 | 
			
		||||
  ->withType('f')
 | 
			
		||||
  ->withSuffix('js')
 | 
			
		||||
  ->withSuffix('css')
 | 
			
		||||
  ->setGenerateChecksums(true)
 | 
			
		||||
  ->find();
 | 
			
		||||
 | 
			
		||||
echo "Processing ".count($files)." files";
 | 
			
		||||
 | 
			
		||||
$file_map = array();
 | 
			
		||||
foreach ($files as $path => $hash) {
 | 
			
		||||
  echo ".";
 | 
			
		||||
  $name = '/'.Filesystem::readablePath($path, $root);
 | 
			
		||||
  $file_map[$name] = array(
 | 
			
		||||
    'hash' => $hash,
 | 
			
		||||
    'disk' => $path,
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
echo "\n";
 | 
			
		||||
 | 
			
		||||
$runtime_map = array();
 | 
			
		||||
 | 
			
		||||
$parser = new PhutilDocblockParser();
 | 
			
		||||
foreach ($file_map as $path => $info) {
 | 
			
		||||
  $data = Filesystem::readFile($info['disk']);
 | 
			
		||||
  $matches = array();
 | 
			
		||||
  $ok = preg_match('@/[*][*].*?[*]/@s', $data, $matches);
 | 
			
		||||
  if (!$ok) {
 | 
			
		||||
    throw new Exception(
 | 
			
		||||
      "File {$path} does not have a header doc comment. Encode dependency ".
 | 
			
		||||
      "data in a header docblock.");
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  list($description, $metadata) = $parser->parse($matches[0]);
 | 
			
		||||
  
 | 
			
		||||
  $provides = preg_split('/\s+/', trim(idx($metadata, 'provides')));
 | 
			
		||||
  $requires = preg_split('/\s+/', trim(idx($metadata, 'requires')));
 | 
			
		||||
  $provides = array_filter($provides);
 | 
			
		||||
  $requires = array_filter($requires);
 | 
			
		||||
  
 | 
			
		||||
  if (count($provides) !== 1) {
 | 
			
		||||
    throw new Exception(
 | 
			
		||||
      "File {$path} must @provide exactly one Celerity target.");
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  $provides = reset($provides);
 | 
			
		||||
 | 
			
		||||
  $type = 'js';
 | 
			
		||||
  if (preg_match('/\.css$/', $path)) {
 | 
			
		||||
    $type = 'css';
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  $path = '/res/'.substr($info['hash'], 0, 8).$path;
 | 
			
		||||
  
 | 
			
		||||
  $runtime_map[$provides] = array(
 | 
			
		||||
    'path'      => $path,
 | 
			
		||||
    'type'      => $type,
 | 
			
		||||
    'requires'  => $requires,
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
$runtime_map = var_export($runtime_map, true);
 | 
			
		||||
$runtime_map = preg_replace('/\s+$/m', '', $runtime_map);
 | 
			
		||||
$runtime_map = preg_replace('/array \(/', 'array(', $runtime_map);
 | 
			
		||||
 | 
			
		||||
$resource_map = <<<EOFILE
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This file is automatically generated. Use 'celerity_mapper.php' to rebuild
 | 
			
		||||
 * it.
 | 
			
		||||
 * @generated
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
celerity_register_resource_map({$runtime_map});
 | 
			
		||||
 | 
			
		||||
EOFILE;
 | 
			
		||||
 | 
			
		||||
echo "Writing map...\n";
 | 
			
		||||
Filesystem::writeFile(
 | 
			
		||||
  $root.'/../src/__celerity_resource_map__.php',
 | 
			
		||||
  $resource_map);
 | 
			
		||||
echo "Done.\n";  
 | 
			
		||||
							
								
								
									
										58
									
								
								src/__celerity_resource_map__.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/__celerity_resource_map__.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This file is automatically generated. Use 'celerity_mapper.php' to rebuild
 | 
			
		||||
 * it.
 | 
			
		||||
 * @generated
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
celerity_register_resource_map(array(
 | 
			
		||||
  'phabricator-core-css' =>
 | 
			
		||||
  array(
 | 
			
		||||
    'path' => '/res/ffa0140c/rsrc/css/base.css',
 | 
			
		||||
    'type' => 'css',
 | 
			
		||||
    'requires' =>
 | 
			
		||||
    array(
 | 
			
		||||
    ),
 | 
			
		||||
  ),
 | 
			
		||||
  'phabricator-syntax-css' =>
 | 
			
		||||
  array(
 | 
			
		||||
    'path' => '/res/bf911307/rsrc/css/syntax.css',
 | 
			
		||||
    'type' => 'css',
 | 
			
		||||
    'requires' =>
 | 
			
		||||
    array(
 | 
			
		||||
    ),
 | 
			
		||||
  ),
 | 
			
		||||
  'javelin-init-dev' =>
 | 
			
		||||
  array(
 | 
			
		||||
    'path' => '/res/c57a9e89/rsrc/js/javelin/init.dev.js',
 | 
			
		||||
    'type' => 'js',
 | 
			
		||||
    'requires' =>
 | 
			
		||||
    array(
 | 
			
		||||
    ),
 | 
			
		||||
  ),
 | 
			
		||||
  'javelin-init-prod' =>
 | 
			
		||||
  array(
 | 
			
		||||
    'path' => '/res/f0172c54/rsrc/js/javelin/init.min.js',
 | 
			
		||||
    'type' => 'js',
 | 
			
		||||
    'requires' =>
 | 
			
		||||
    array(
 | 
			
		||||
    ),
 | 
			
		||||
  ),
 | 
			
		||||
  'javelin-lib-dev' =>
 | 
			
		||||
  array(
 | 
			
		||||
    'path' => '/res/3e747182/rsrc/js/javelin/javelin.dev.js',
 | 
			
		||||
    'type' => 'js',
 | 
			
		||||
    'requires' =>
 | 
			
		||||
    array(
 | 
			
		||||
    ),
 | 
			
		||||
  ),
 | 
			
		||||
  'javelin-lib-prod' =>
 | 
			
		||||
  array(
 | 
			
		||||
    'path' => '/res/9438670e/rsrc/js/javelin/javelin.min.js',
 | 
			
		||||
    'type' => 'js',
 | 
			
		||||
    'requires' =>
 | 
			
		||||
    array(
 | 
			
		||||
    ),
 | 
			
		||||
  ),
 | 
			
		||||
));
 | 
			
		||||
@@ -46,6 +46,10 @@ phutil_register_library_map(array(
 | 
			
		||||
    'AphrontURIMapper' => 'aphront/mapper',
 | 
			
		||||
    'AphrontView' => 'view/base',
 | 
			
		||||
    'AphrontWebpageResponse' => 'aphront/response/webpage',
 | 
			
		||||
    'CelerityAPI' => 'infratructure/celerity/api',
 | 
			
		||||
    'CelerityResourceController' => 'infratructure/celerity/controller',
 | 
			
		||||
    'CelerityResourceMap' => 'infratructure/celerity/map',
 | 
			
		||||
    'CelerityStaticResourceResponse' => 'infratructure/celerity/response',
 | 
			
		||||
    'ConduitAPIMethod' => 'applications/conduit/method/base',
 | 
			
		||||
    'ConduitAPIRequest' => 'applications/conduit/protocol/request',
 | 
			
		||||
    'ConduitAPI_conduit_connect_Method' => 'applications/conduit/method/conduit/connect',
 | 
			
		||||
@@ -121,10 +125,12 @@ phutil_register_library_map(array(
 | 
			
		||||
  array(
 | 
			
		||||
    '_qsprintf_check_scalar_type' => 'storage/qsprintf',
 | 
			
		||||
    '_qsprintf_check_type' => 'storage/qsprintf',
 | 
			
		||||
    'celerity_register_resource_map' => 'infratructure/celerity/map',
 | 
			
		||||
    'qsprintf' => 'storage/qsprintf',
 | 
			
		||||
    'queryfx' => 'storage/queryfx',
 | 
			
		||||
    'queryfx_all' => 'storage/queryfx',
 | 
			
		||||
    'queryfx_one' => 'storage/queryfx',
 | 
			
		||||
    'require_celerity_resource' => 'infratructure/celerity/api',
 | 
			
		||||
    'vqsprintf' => 'storage/qsprintf',
 | 
			
		||||
    'vqueryfx' => 'storage/queryfx',
 | 
			
		||||
    'xsprintf_query' => 'storage/qsprintf',
 | 
			
		||||
@@ -161,6 +167,7 @@ phutil_register_library_map(array(
 | 
			
		||||
    'AphrontSideNavView' => 'AphrontView',
 | 
			
		||||
    'AphrontTableView' => 'AphrontView',
 | 
			
		||||
    'AphrontWebpageResponse' => 'AphrontResponse',
 | 
			
		||||
    'CelerityResourceController' => 'AphrontController',
 | 
			
		||||
    'ConduitAPI_conduit_connect_Method' => 'ConduitAPIMethod',
 | 
			
		||||
    'ConduitAPI_differential_creatediff_Method' => 'ConduitAPIMethod',
 | 
			
		||||
    'ConduitAPI_differential_setdiffproperty_Method' => 'ConduitAPIMethod',
 | 
			
		||||
 
 | 
			
		||||
@@ -81,6 +81,11 @@ class AphrontDefaultApplicationConfiguration
 | 
			
		||||
        'changeset/(?<id>\d+)/$'  => 'DifferentialChangesetViewController',
 | 
			
		||||
      ),
 | 
			
		||||
 | 
			
		||||
      '/res/' => array(
 | 
			
		||||
        '(?<hash>[a-f0-9]{8})/(?<path>[^.]+\.(?:css|js))$'
 | 
			
		||||
          => 'CelerityResourceController',
 | 
			
		||||
      ),
 | 
			
		||||
 | 
			
		||||
      '.*' => 'AphrontDefaultApplicationController',
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -96,7 +96,7 @@ final class DifferentialDiffTableOfContentsView extends AphrontView {
 | 
			
		||||
 | 
			
		||||
      $rows[] =
 | 
			
		||||
        '<tr>'.
 | 
			
		||||
          '<td class="differential-toc-char" title={$chartitle}>'.$char.'</td>'.
 | 
			
		||||
          '<td class="differential-toc-char" title='.$chartitle.'>'.$char.'</td>'.
 | 
			
		||||
          '<td class="differential-toc-prop">'.$pchar.'</td>'.
 | 
			
		||||
          '<td class="differential-toc-ftype">'.$desc.'</td>'.
 | 
			
		||||
          '<td class="differential-toc-file">'.$link.$lines.'</td>'.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										35
									
								
								src/infratructure/celerity/api/CelerityAPI.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/infratructure/celerity/api/CelerityAPI.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2011 Facebook, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *   http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
final class CelerityAPI {
 | 
			
		||||
 | 
			
		||||
  private static $response;
 | 
			
		||||
 | 
			
		||||
  public static function getStaticResourceResponse() {
 | 
			
		||||
    if (empty(self::$response)) {
 | 
			
		||||
      self::$response = new CelerityStaticResourceResponse();
 | 
			
		||||
    }
 | 
			
		||||
    return self::$response;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function require_celerity_resource($symbol) {
 | 
			
		||||
  $response = CelerityAPI::getStaticResourceResponse();
 | 
			
		||||
  $response->requireResource($symbol);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								src/infratructure/celerity/api/__init__.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/infratructure/celerity/api/__init__.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * This file is automatically generated. Lint this module to rebuild it.
 | 
			
		||||
 * @generated
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
phutil_require_module('phabricator', 'infratructure/celerity/response');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
phutil_require_source('CelerityAPI.php');
 | 
			
		||||
@@ -0,0 +1,64 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2011 Facebook, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *   http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
class CelerityResourceController extends AphrontController {
 | 
			
		||||
  
 | 
			
		||||
  private $path;
 | 
			
		||||
  private $hash;
 | 
			
		||||
  
 | 
			
		||||
  public function willProcessRequest(array $data) {
 | 
			
		||||
    $this->path = $data['path'];
 | 
			
		||||
    $this->hash = $data['hash'];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function processRequest() {
 | 
			
		||||
    $path = $this->path;
 | 
			
		||||
 | 
			
		||||
    // Sanity checking to keep this from exposing anything sensitive.
 | 
			
		||||
    $path = preg_replace('@(//|\\.\\.)@', '', $path);
 | 
			
		||||
    $matches = null;
 | 
			
		||||
    if (!preg_match('/\.(css|js)$/', $path, $matches)) {
 | 
			
		||||
      throw new Exception("Only CSS and JS resources may be served.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $type = $matches[1];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    $root = dirname(phutil_get_library_root('phabricator'));
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      $data = Filesystem::readFile($root.'/webroot/'.$path);
 | 
			
		||||
    } catch (Exception $ex) {
 | 
			
		||||
      return new Aphront404Response();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $response = new AphrontFileResponse();
 | 
			
		||||
    $response->setContent($data);
 | 
			
		||||
    switch ($type) {
 | 
			
		||||
      case 'css':
 | 
			
		||||
        $response->setMimeType("text/css; charset=utf-8");
 | 
			
		||||
        break;
 | 
			
		||||
      case 'js':
 | 
			
		||||
        $response->setMimeType("text/javascript; charset=utf-8");
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return $response;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								src/infratructure/celerity/controller/__init__.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/infratructure/celerity/controller/__init__.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * This file is automatically generated. Lint this module to rebuild it.
 | 
			
		||||
 * @generated
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
phutil_require_module('phabricator', 'aphront/controller');
 | 
			
		||||
phutil_require_module('phabricator', 'aphront/response/file');
 | 
			
		||||
 | 
			
		||||
phutil_require_module('phutil', 'filesystem');
 | 
			
		||||
phutil_require_module('phutil', 'moduleutils');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
phutil_require_source('CelerityResourceController.php');
 | 
			
		||||
							
								
								
									
										75
									
								
								src/infratructure/celerity/map/CelerityResourceMap.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/infratructure/celerity/map/CelerityResourceMap.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2011 Facebook, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *   http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
final class CelerityResourceMap {
 | 
			
		||||
 | 
			
		||||
  private static $instance;
 | 
			
		||||
  private $resourceMap;
 | 
			
		||||
 | 
			
		||||
  public static function getInstance() {
 | 
			
		||||
    if (empty(self::$instance)) {
 | 
			
		||||
      self::$instance = new CelerityResourceMap();
 | 
			
		||||
      $root = phutil_get_library_root('phabricator');
 | 
			
		||||
      $ok = @include_once $root.'/__celerity_resource_map__.php';
 | 
			
		||||
      if (!$ok) {
 | 
			
		||||
        throw new Exception("Failed to load Celerity resource map!");
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return self::$instance;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function setResourceMap($resource_map) {
 | 
			
		||||
    $this->resourceMap = $resource_map;
 | 
			
		||||
    return $this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function resolveResources(array $symbols) {
 | 
			
		||||
    $map = array();
 | 
			
		||||
    foreach ($symbols as $symbol) {
 | 
			
		||||
      if (!empty($map[$symbol])) {
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
      $this->resolveResource($map, $symbol);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return $map;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private function resolveResource(array &$map, $symbol) {
 | 
			
		||||
    if (empty($this->resourceMap[$symbol])) {
 | 
			
		||||
      throw new Exception(
 | 
			
		||||
        "Attempting to resolve unknown resource, '{$symbol}'.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $info = $this->resourceMap[$symbol];
 | 
			
		||||
    foreach ($info['requires'] as $requires) {
 | 
			
		||||
      if (!empty($map[$requires])) {
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
      $this->resolveResource($map, $requires);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $map[$symbol] = $info;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function celerity_register_resource_map(array $map) {
 | 
			
		||||
  $instance = CelerityResourceMap::getInstance();
 | 
			
		||||
  $instance->setResourceMap($map);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								src/infratructure/celerity/map/__init__.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/infratructure/celerity/map/__init__.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * This file is automatically generated. Lint this module to rebuild it.
 | 
			
		||||
 * @generated
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
phutil_require_module('phutil', 'moduleutils');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
phutil_require_source('CelerityResourceMap.php');
 | 
			
		||||
@@ -0,0 +1,63 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2011 Facebook, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *   http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
final class CelerityStaticResourceResponse {
 | 
			
		||||
 | 
			
		||||
  private $symbols = array();
 | 
			
		||||
  private $needsResolve = true;
 | 
			
		||||
  private $resolved;
 | 
			
		||||
 | 
			
		||||
  public function requireResource($symbol) {
 | 
			
		||||
    $this->symbols[$symbol] = true;
 | 
			
		||||
    $this->needsResolve = true;
 | 
			
		||||
    return $this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private function resolveResources() {
 | 
			
		||||
    if ($this->needsResolve) {
 | 
			
		||||
      $map = CelerityResourceMap::getInstance();
 | 
			
		||||
      $this->resolved = $map->resolveResources(array_keys($this->symbols));
 | 
			
		||||
      $this->needsResolve = false;
 | 
			
		||||
    }
 | 
			
		||||
    return $this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function renderResourcesOfType($type) {
 | 
			
		||||
    $this->resolveResources();
 | 
			
		||||
    $output = array();
 | 
			
		||||
    foreach ($this->resolved as $resource) {
 | 
			
		||||
      if ($resource['type'] == $type) {
 | 
			
		||||
        $output[] = $this->renderResource($resource);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return implode("\n", $output);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private function renderResource(array $resource) {
 | 
			
		||||
    switch ($resource['type']) {
 | 
			
		||||
      case 'css':
 | 
			
		||||
        $path = phutil_escape_html($resource['path']);
 | 
			
		||||
        return '<link rel="stylesheet" type="text/css" href="'.$path.'" />';
 | 
			
		||||
      case 'js':
 | 
			
		||||
        $path = phutil_escape_html($resource['path']);
 | 
			
		||||
        return '<script type="text/javascript" src="'.$path.'" />';
 | 
			
		||||
    }
 | 
			
		||||
    throw new Exception("Unable to render resource.");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								src/infratructure/celerity/response/__init__.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/infratructure/celerity/response/__init__.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * This file is automatically generated. Lint this module to rebuild it.
 | 
			
		||||
 * @generated
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
phutil_require_module('phabricator', 'infratructure/celerity/map');
 | 
			
		||||
 | 
			
		||||
phutil_require_module('phutil', 'markup');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
phutil_require_source('CelerityStaticResourceResponse.php');
 | 
			
		||||
@@ -41,8 +41,14 @@ class AphrontPageView extends AphrontView {
 | 
			
		||||
    return '';
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  protected function willRenderPage() {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function render() {
 | 
			
		||||
    
 | 
			
		||||
    $this->willRenderPage();
 | 
			
		||||
 | 
			
		||||
    $title = $this->getTitle();
 | 
			
		||||
    $head  = $this->getHead();
 | 
			
		||||
    $body  = $this->getBody();
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,7 @@ class PhabricatorStandardPageView extends AphrontPageView {
 | 
			
		||||
  private $tabs = array();
 | 
			
		||||
  private $selectedTab;
 | 
			
		||||
  private $glyph;
 | 
			
		||||
  private $bodyContent;
 | 
			
		||||
 | 
			
		||||
  public function setApplicationName($application_name) {
 | 
			
		||||
    $this->applicationName = $application_name;
 | 
			
		||||
@@ -52,10 +53,18 @@ class PhabricatorStandardPageView extends AphrontPageView {
 | 
			
		||||
    return $this->getGlyph().' '.parent::getTitle();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  protected function willRenderPage() {
 | 
			
		||||
    require_celerity_resource('phabricator-core-css');
 | 
			
		||||
    
 | 
			
		||||
    $this->bodyContent = $this->renderChildren();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  protected function getHead() {
 | 
			
		||||
    $response = CelerityAPI::getStaticResourceResponse();
 | 
			
		||||
    return
 | 
			
		||||
      '<link rel="stylesheet" type="text/css" href="/rsrc/css/base.css" />'.
 | 
			
		||||
      '<link rel="stylesheet" type="text/css" href="/rsrc/css/syntax.css" />'.
 | 
			
		||||
      $response->renderResourcesOfType('css').
 | 
			
		||||
      '<script type="text/javascript">window.__DEV__=1;</script>'.
 | 
			
		||||
      '<script type="text/javascript" src="/rsrc/js/javelin/init.dev.js">'.
 | 
			
		||||
      '</script>';
 | 
			
		||||
@@ -102,20 +111,18 @@ class PhabricatorStandardPageView extends AphrontPageView {
 | 
			
		||||
            phutil_escape_html($this->getApplicationName())).
 | 
			
		||||
          $tabs.
 | 
			
		||||
        '</div>'.
 | 
			
		||||
        $this->renderChildren().
 | 
			
		||||
        $this->bodyContent.
 | 
			
		||||
        '<div style="clear: both;"></div>'.
 | 
			
		||||
      '</div>';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function getTail() {
 | 
			
		||||
    $response = CelerityAPI::getStaticResourceResponse();
 | 
			
		||||
    return
 | 
			
		||||
      '<script type="text/javascript" src="/rsrc/js/javelin/javelin.dev.js">'.
 | 
			
		||||
      '</script>'.
 | 
			
		||||
      $response->renderResourcesOfType('js').
 | 
			
		||||
      '<script type="text/javascript">'.
 | 
			
		||||
        'JX.Stratcom.mergeData(0, {});'.
 | 
			
		||||
      '</script>';
 | 
			
		||||
    
 | 
			
		||||
    ;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
phutil_require_module('phabricator', 'infratructure/celerity/api');
 | 
			
		||||
phutil_require_module('phabricator', 'view/page/base');
 | 
			
		||||
 | 
			
		||||
phutil_require_module('phutil', 'markup');
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,7 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @provides phabricator-core-css
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
html {
 | 
			
		||||
  overflow-y: scroll;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,7 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @provides phabricator-syntax-css
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
.remarkup-code .uu { /* Forbidden Unicode */
 | 
			
		||||
  color: #aa0066;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
/** @provides javelin-init-dev */
 | 
			
		||||
/**
 | 
			
		||||
 * Javelin core; installs Javelin and Stratcom event delegation.
 | 
			
		||||
 *
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								webroot/rsrc/js/javelin/init.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								webroot/rsrc/js/javelin/init.min.js
									
									
									
									
										vendored
									
									
								
							@@ -1 +1,2 @@
 | 
			
		||||
/** @provides javelin-init-prod */
 | 
			
		||||
(function(){if(window.JX)return;window.JX={};window.__DEV__=window.__DEV__||0;var d=false;var f=[];var e=[];var h=document.documentElement;var b=!!h.addEventListener;JX.__rawEventQueue=function(o){e.push(o);var j=JX.Stratcom;if(j&&j.ready){var m=e;e=[];for(var l=0;l<m.length;++l){var k=m[l];try{var test=k.type;}catch(p){continue;}if(!d&&k.type=='domready'){document.body&&(document.body.id=null);d=true;for(var l=0;l<f.length;l++)f[l]();}j.dispatch(k);}}else{var n=o.srcElement||o.target;if(n&&(o.type in {click:1,submit:1})&&(/ FI_CAPTURE /).test(' '+n.className+' ')){o.returnValue=false;o.preventDefault&&o.preventDefault();document.body.id='event_capture';if(!add_event_listener&&document.createEventObject){e.pop();e.push(document.createEventObject(o));}return false;}}};JX.enableDispatch=function(j,k){if(j.addEventListener){j.addEventListener(k,JX.__rawEventQueue,true);}else if(j.attachEvent)j.attachEvent('on'+k,JX.__rawEventQueue);};var a=['click','change','keypress','mousedown','mouseover','mouseout','mouseup','keydown','drop','dragenter','dragleave','dragover'];if(!b)a.push('focusin','focusout');if(window.opera){a.push('focus','blur');}else a.push('submit');for(var c=0;c<a.length;++c)JX.enableDispatch(h,a[c]);var i=[('onpagehide' in window)?'pagehide':'unload','resize','focus','blur'];for(var c=0;c<i.length;++c)JX.enableDispatch(window,i[c]);JX.__simulate=function(k,event){if(!b){var j={target:k,type:event};JX.__rawEventQueue(j);if(j.returnValue===false)return false;}};if(b){document.addEventListener('DOMContentLoaded',function(){JX.__rawEventQueue({type:'domready'});},true);}else{var g="if (this.readyState == 'complete') {"+"JX.__rawEventQueue({type: 'domready'});"+"}";document.write('<script'+' defer="defer"'+' src="javascript:void(0)"'+' onreadystatechange="'+g+'"'+'><\/sc'+'ript\>');}JX.onload=function(j){if(d){j();}else f.push(j);};})();
 | 
			
		||||
@@ -1,3 +1,5 @@
 | 
			
		||||
/** @provides javelin-lib-dev */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Javelin utility functions.
 | 
			
		||||
 *
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								webroot/rsrc/js/javelin/javelin.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								webroot/rsrc/js/javelin/javelin.min.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Reference in New Issue
	
	Block a user