mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 06:42:42 +01:00
Celerity, a Haste-style static resource management system.
This commit is contained in:
parent
fed4c583c5
commit
7bb0db1365
23 changed files with 531 additions and 9 deletions
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');
|
|
@ -40,8 +40,14 @@ class AphrontPageView extends AphrontView {
|
|||
protected function getTail() {
|
||||
return '';
|
||||
}
|
||||
|
||||
protected function willRenderPage() {
|
||||
return;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
|
||||
$this->willRenderPage();
|
||||
|
||||
$title = $this->getTitle();
|
||||
$head = $this->getHead();
|
||||
|
|
|
@ -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() {
|
||||
return
|
||||
'<script type="text/javascript" src="/rsrc/js/javelin/javelin.dev.js">'.
|
||||
'</script>'.
|
||||
$response = CelerityAPI::getStaticResourceResponse();
|
||||
return
|
||||
$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
Loading…
Reference in a new issue