1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-29 10:12:41 +01:00

Javelin integration.

This commit is contained in:
epriestley 2011-01-25 11:57:47 -08:00
parent e284d5b5dc
commit 16ad2386d8
24 changed files with 630 additions and 122 deletions

View file

@ -9,7 +9,7 @@
celerity_register_resource_map(array( celerity_register_resource_map(array(
'aphront-dialog-view-css' => 'aphront-dialog-view-css' =>
array( array(
'path' => '/res/2ef90210/rsrc/css/aphront/dialog-view.css', 'path' => '/res/771b987d/rsrc/css/aphront/dialog-view.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -17,7 +17,7 @@ celerity_register_resource_map(array(
), ),
'aphront-form-view-css' => 'aphront-form-view-css' =>
array( array(
'path' => '/res/517031e5/rsrc/css/aphront/form-view.css', 'path' => '/res/20ebc99b/rsrc/css/aphront/form-view.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -25,7 +25,7 @@ celerity_register_resource_map(array(
), ),
'aphront-panel-view-css' => 'aphront-panel-view-css' =>
array( array(
'path' => '/res/d96d5826/rsrc/css/aphront/panel-view.css', 'path' => '/res/d1ce0c3d/rsrc/css/aphront/panel-view.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -33,7 +33,7 @@ celerity_register_resource_map(array(
), ),
'aphront-side-nav-view-css' => 'aphront-side-nav-view-css' =>
array( array(
'path' => '/res/89b99d7d/rsrc/css/aphront/side-nav-view.css', 'path' => '/res/1a16f19a/rsrc/css/aphront/side-nav-view.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -41,7 +41,7 @@ celerity_register_resource_map(array(
), ),
'aphront-table-view-css' => 'aphront-table-view-css' =>
array( array(
'path' => '/res/639b3af2/rsrc/css/aphront/table-view.css', 'path' => '/res/52b0191f/rsrc/css/aphront/table-view.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -49,7 +49,7 @@ celerity_register_resource_map(array(
), ),
'phabricator-standard-page-view' => 'phabricator-standard-page-view' =>
array( array(
'path' => '/res/f1a74aa4/rsrc/css/application/base/standard-page-view.css', 'path' => '/res/0eef6905/rsrc/css/application/base/standard-page-view.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -57,7 +57,7 @@ celerity_register_resource_map(array(
), ),
'differential-changeset-view-css' => 'differential-changeset-view-css' =>
array( array(
'path' => '/res/08a5c816/rsrc/css/application/differential/changeset-view.css', 'path' => '/res/921d3a0c/rsrc/css/application/differential/changeset-view.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -73,7 +73,7 @@ celerity_register_resource_map(array(
), ),
'differential-table-of-contents-css' => 'differential-table-of-contents-css' =>
array( array(
'path' => '/res/cd5c966d/rsrc/css/application/differential/table-of-contents.css', 'path' => '/res/ebf6641c/rsrc/css/application/differential/table-of-contents.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -81,7 +81,7 @@ celerity_register_resource_map(array(
), ),
'phabricator-directory-css' => 'phabricator-directory-css' =>
array( array(
'path' => '/res/795c7b4e/rsrc/css/application/directory/phabricator-directory.css', 'path' => '/res/6a000601/rsrc/css/application/directory/phabricator-directory.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -89,7 +89,7 @@ celerity_register_resource_map(array(
), ),
'phabricator-core-buttons-css' => 'phabricator-core-buttons-css' =>
array( array(
'path' => '/res/5f44fe89/rsrc/css/core/buttons.css', 'path' => '/res/6e348ba4/rsrc/css/core/buttons.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -103,6 +103,22 @@ celerity_register_resource_map(array(
array( array(
), ),
), ),
'syntax-highlighting-css' =>
array(
'path' => '/res/fb673ece/rsrc/css/core/syntax.css',
'type' => 'css',
'requires' =>
array(
),
),
'javelin-behavior-differential-populate' =>
array(
'path' => '/res/b419291a/rsrc/js/application/differential/behavior-populate.js',
'type' => 'js',
'requires' =>
array(
),
),
'javelin-init-dev' => 'javelin-init-dev' =>
array( array(
'path' => '/res/c57a9e89/rsrc/js/javelin/init.dev.js', 'path' => '/res/c57a9e89/rsrc/js/javelin/init.dev.js',

View file

@ -9,6 +9,7 @@ phutil_register_library_map(array(
'class' => 'class' =>
array( array(
'Aphront404Response' => 'aphront/response/404', 'Aphront404Response' => 'aphront/response/404',
'AphrontAjaxResponse' => 'aphront/response/ajax',
'AphrontApplicationConfiguration' => 'aphront/applicationconfiguration', 'AphrontApplicationConfiguration' => 'aphront/applicationconfiguration',
'AphrontController' => 'aphront/controller', 'AphrontController' => 'aphront/controller',
'AphrontDatabaseConnection' => 'storage/connection/base', 'AphrontDatabaseConnection' => 'storage/connection/base',
@ -62,6 +63,7 @@ phutil_register_library_map(array(
'DifferentialChangeType' => 'applications/differential/constants/changetype', 'DifferentialChangeType' => 'applications/differential/constants/changetype',
'DifferentialChangeset' => 'applications/differential/storage/changeset', 'DifferentialChangeset' => 'applications/differential/storage/changeset',
'DifferentialChangesetDetailView' => 'applications/differential/view/changesetdetailview', 'DifferentialChangesetDetailView' => 'applications/differential/view/changesetdetailview',
'DifferentialChangesetListView' => 'applications/differential/view/changesetlistview',
'DifferentialChangesetParser' => 'applications/differential/parser/changeset', 'DifferentialChangesetParser' => 'applications/differential/parser/changeset',
'DifferentialChangesetViewController' => 'applications/differential/controller/changesetview', 'DifferentialChangesetViewController' => 'applications/differential/controller/changesetview',
'DifferentialController' => 'applications/differential/controller/base', 'DifferentialController' => 'applications/differential/controller/base',
@ -76,6 +78,7 @@ phutil_register_library_map(array(
'DifferentialRevisionControlSystem' => 'applications/differential/constants/revisioncontrolsystem', 'DifferentialRevisionControlSystem' => 'applications/differential/constants/revisioncontrolsystem',
'DifferentialRevisionStatus' => 'applications/differential/constants/revisionstatus', 'DifferentialRevisionStatus' => 'applications/differential/constants/revisionstatus',
'DifferentialUnitStatus' => 'applications/differential/constants/unitstatus', 'DifferentialUnitStatus' => 'applications/differential/constants/unitstatus',
'Javelin' => 'infratructure/javelin/api',
'LiskDAO' => 'storage/lisk/dao', 'LiskDAO' => 'storage/lisk/dao',
'PhabricatorConduitAPIController' => 'applications/conduit/controller/api', 'PhabricatorConduitAPIController' => 'applications/conduit/controller/api',
'PhabricatorConduitConnectionLog' => 'applications/conduit/storage/connectionlog', 'PhabricatorConduitConnectionLog' => 'applications/conduit/storage/connectionlog',
@ -125,7 +128,9 @@ phutil_register_library_map(array(
array( array(
'_qsprintf_check_scalar_type' => 'storage/qsprintf', '_qsprintf_check_scalar_type' => 'storage/qsprintf',
'_qsprintf_check_type' => 'storage/qsprintf', '_qsprintf_check_type' => 'storage/qsprintf',
'celerity_gen_unique_node_id' => 'infratructure/celerity/api',
'celerity_register_resource_map' => 'infratructure/celerity/map', 'celerity_register_resource_map' => 'infratructure/celerity/map',
'javelin_render_tag' => 'infratructure/javelin/markup',
'qsprintf' => 'storage/qsprintf', 'qsprintf' => 'storage/qsprintf',
'queryfx' => 'storage/queryfx', 'queryfx' => 'storage/queryfx',
'queryfx_all' => 'storage/queryfx', 'queryfx_all' => 'storage/queryfx',
@ -138,6 +143,7 @@ phutil_register_library_map(array(
'requires_class' => 'requires_class' =>
array( array(
'Aphront404Response' => 'AphrontResponse', 'Aphront404Response' => 'AphrontResponse',
'AphrontAjaxResponse' => 'AphrontResponse',
'AphrontDefaultApplicationConfiguration' => 'AphrontApplicationConfiguration', 'AphrontDefaultApplicationConfiguration' => 'AphrontApplicationConfiguration',
'AphrontDefaultApplicationController' => 'AphrontController', 'AphrontDefaultApplicationController' => 'AphrontController',
'AphrontDialogResponse' => 'AphrontResponse', 'AphrontDialogResponse' => 'AphrontResponse',
@ -175,6 +181,7 @@ phutil_register_library_map(array(
'ConduitAPI_user_find_Method' => 'ConduitAPIMethod', 'ConduitAPI_user_find_Method' => 'ConduitAPIMethod',
'DifferentialChangeset' => 'DifferentialDAO', 'DifferentialChangeset' => 'DifferentialDAO',
'DifferentialChangesetDetailView' => 'AphrontView', 'DifferentialChangesetDetailView' => 'AphrontView',
'DifferentialChangesetListView' => 'AphrontView',
'DifferentialChangesetViewController' => 'DifferentialController', 'DifferentialChangesetViewController' => 'DifferentialController',
'DifferentialController' => 'PhabricatorController', 'DifferentialController' => 'PhabricatorController',
'DifferentialDAO' => 'PhabricatorLiskDAO', 'DifferentialDAO' => 'PhabricatorLiskDAO',

View file

@ -82,7 +82,7 @@ class AphrontDefaultApplicationConfiguration
), ),
'/res/' => array( '/res/' => array(
'(?<hash>[a-f0-9]{8})/(?<path>[^.]+\.(?:css|js))$' '(?<hash>[a-f0-9]{8})/(?<path>.+\.(?:css|js))$'
=> 'CelerityResourceController', => 'CelerityResourceController',
), ),

View file

@ -0,0 +1,45 @@
<?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.
*/
/**
* @group aphront
*/
class AphrontAjaxResponse extends AphrontResponse {
private $content;
private $error;
public function setContent($content) {
$this->content = $content;
return $this;
}
public function buildResponseString() {
$response = CelerityAPI::getStaticResourceResponse();
return $response->renderAjaxResponse(
$this->content,
$this->error);
}
public function getHeaders() {
return array(
array('Content-Type', 'text/plain; charset=UTF-8'),
);
}
}

View file

@ -0,0 +1,13 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/base');
phutil_require_module('phabricator', 'infratructure/celerity/api');
phutil_require_source('AphrontAjaxResponse.php');

View file

@ -37,14 +37,22 @@ class DifferentialChangesetViewController extends DifferentialController {
$output = $parser->render(); $output = $parser->render();
$request = $this->getRequest();
if ($request->isAjax()) {
return id(new AphrontAjaxResponse())
->setContent($output);
}
$detail = new DifferentialChangesetDetailView();
$detail->setChangeset($changeset);
$detail->appendChild($output);
// TODO: This is a bit of a hacky mess. // TODO: This is a bit of a hacky mess.
$output = $output =
'<div style="padding: 2em 1em;">'. '<div style="padding: 2em 1em;">'.
'<div class="differential-primary-pane">'. '<div class="differential-primary-pane">'.
'<div class="differential-review-stage">'. '<div class="differential-review-stage">'.
'<h1>'.phutil_escape_html($changeset->getDisplayFilename()).'</h1>'. $detail->render().
'<br />'.
$output.
'</div>'. '</div>'.
'</div>'. '</div>'.
'</div>'; '</div>';

View file

@ -7,11 +7,12 @@
phutil_require_module('phabricator', 'aphront/response/404'); phutil_require_module('phabricator', 'aphront/response/404');
phutil_require_module('phabricator', 'aphront/response/ajax');
phutil_require_module('phabricator', 'applications/differential/controller/base'); phutil_require_module('phabricator', 'applications/differential/controller/base');
phutil_require_module('phabricator', 'applications/differential/parser/changeset'); phutil_require_module('phabricator', 'applications/differential/parser/changeset');
phutil_require_module('phabricator', 'applications/differential/storage/changeset'); phutil_require_module('phabricator', 'applications/differential/storage/changeset');
phutil_require_module('phabricator', 'applications/differential/view/changesetdetailview');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils'); phutil_require_module('phutil', 'utils');

View file

@ -36,7 +36,7 @@ class DifferentialDiffViewController extends DifferentialController {
$table_of_contents = id(new DifferentialDiffTableOfContentsView()) $table_of_contents = id(new DifferentialDiffTableOfContentsView())
->setChangesets($changesets); ->setChangesets($changesets);
$details = id(new DifferentialChangesetDetailView()) $details = id(new DifferentialChangesetListView())
->setChangesets($changesets); ->setChangesets($changesets);
return $this->buildStandardPageResponse( return $this->buildStandardPageResponse(

View file

@ -9,6 +9,7 @@
phutil_require_module('phabricator', 'aphront/response/404'); phutil_require_module('phabricator', 'aphront/response/404');
phutil_require_module('phabricator', 'applications/differential/controller/base'); phutil_require_module('phabricator', 'applications/differential/controller/base');
phutil_require_module('phabricator', 'applications/differential/storage/diff'); phutil_require_module('phabricator', 'applications/differential/storage/diff');
phutil_require_module('phabricator', 'applications/differential/view/changesetlistview');
phutil_require_module('phabricator', 'applications/differential/view/difftableofcontents'); phutil_require_module('phabricator', 'applications/differential/view/difftableofcontents');
phutil_require_module('phutil', 'utils'); phutil_require_module('phutil', 'utils');

View file

@ -18,115 +18,45 @@
class DifferentialChangesetDetailView extends AphrontView { class DifferentialChangesetDetailView extends AphrontView {
private $changesets = array(); private $changeset;
private $buttons = array();
public function setChangesets($changesets) { public function setChangeset($changeset) {
$this->changesets = $changesets; $this->changeset = $changeset;
return $this;
}
public function addButton($button) {
$this->buttons[] = $button;
return $this; return $this;
} }
public function render() { public function render() {
$against = array(); // TODO require_celerity_resource('differential-changeset-view-css');
$edit = false; require_celerity_resource('syntax-highlighting-css');
$changesets = $this->changesets; $edit = false; // TODO
foreach ($changesets as $key => $changeset) {
if (empty($against[$changeset->getID()])) {
$type = $changeset->getChangeType();
if ($type == DifferentialChangeType::TYPE_MOVE_AWAY ||
$type == DifferentialChangeType::TYPE_MULTICOPY) {
unset($changesets[$key]);
}
}
}
$output = array(); $changeset = $this->changeset;
$mapping = array();
foreach ($changesets as $key => $changeset) {
$file = $changeset->getFilename();
$class = 'differential-changeset'; $class = 'differential-changeset';
if (!$edit) { if (!$edit) {
$class .= ' differential-changeset-noneditable'; $class .= ' differential-changeset-immutable';
} }
$id = $changeset->getID();
if ($id) {
$against_id = idx($against, $id);
} else {
$against_id = null;
}
/*
$detail_uri = URI($render_uri)
->addQueryData(array(
'changeset' => $id,
'against' => $against_id,
'whitespace' => $whitespace,
));
*/
$detail_uri = '/differential/changeset/'.$changeset->getID().'/';
$detail = phutil_render_tag(
'a',
array(
'style' => 'float: right',
'class' => 'button small grey',
'href' => $detail_uri,
'target' => '_blank',
),
'Standalone View');
// $div = <div class="differential-loading">Loading&hellip;</div>;
$display_filename = $changeset->getDisplayFilename(); $display_filename = $changeset->getDisplayFilename();
$output[] = $output = javelin_render_tag(
'<div>'. 'div',
'<h1>'.$detail.phutil_escape_html($display_filename).'</h1>'.
'<div>Loading...</div>'.
'</div>';
/*
<div class={$class}
sigil="differential-changeset"
meta={$changeset->getID()}>
{$detail}
<a name={alite_urlize($file)} /><h1>{$file}</h1>
{$div}
</div>;
*/
/*
$mapping[$div->requireUniqueId()] = array_filter(
array( array(
$changeset->getID(), 'sigil' => 'differential-changeset',
idx($against, $changeset->getID()), 'class' => $class,
)); ),
'<a name="#'."TODO".'"></a>'.
implode('', $this->buttons).
'<h1>'.phutil_escape_html($display_filename).'</h1>'.
'<div style="clear: both;"></div>'.
$this->renderChildren());
*/ return $output;
}
/*
require_static('differential-diff-css');
require_static('differential-syntax-css');
Javelin::initBehavior('differential-populate', array(
'registry' => $mapping,
'whitespace' => $whitespace,
'uri' => $render_uri,
));
Javelin::initBehavior('differential-context', array(
'uri' => $render_uri,
));
if ($edit) {
require_static('remarkup-css');
Javelin::initBehavior('differential-inline', array(
'uri' => '/differential/feedback/'.$revision->getID().'/',
));
}
*/
return
'<div class="differential-review-stage">'.
implode("\n", $output).
'</div>';
} }
} }

View file

@ -6,11 +6,11 @@
phutil_require_module('phabricator', 'applications/differential/constants/changetype'); phutil_require_module('phabricator', 'infratructure/celerity/api');
phutil_require_module('phabricator', 'infratructure/javelin/markup');
phutil_require_module('phabricator', 'view/base'); phutil_require_module('phabricator', 'view/base');
phutil_require_module('phutil', 'markup'); phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
phutil_require_source('DifferentialChangesetDetailView.php'); phutil_require_source('DifferentialChangesetDetailView.php');

View file

@ -0,0 +1,126 @@
<?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 DifferentialChangesetListView extends AphrontView {
private $changesets = array();
public function setChangesets($changesets) {
$this->changesets = $changesets;
return $this;
}
public function render() {
require_celerity_resource('differential-changeset-view-css');
$against = array(); // TODO
$edit = false;
$changesets = $this->changesets;
foreach ($changesets as $key => $changeset) {
if (empty($against[$changeset->getID()])) {
$type = $changeset->getChangeType();
if ($type == DifferentialChangeType::TYPE_MOVE_AWAY ||
$type == DifferentialChangeType::TYPE_MULTICOPY) {
unset($changesets[$key]);
}
}
}
$output = array();
$mapping = array();
foreach ($changesets as $key => $changeset) {
$file = $changeset->getFilename();
$class = 'differential-changeset';
if (!$edit) {
$class .= ' differential-changeset-noneditable';
}
$id = $changeset->getID();
if ($id) {
$against_id = idx($against, $id);
} else {
$against_id = null;
}
/*
TODO
$detail_uri = URI($render_uri)
->addQueryData(array(
'changeset' => $id,
'against' => $against_id,
'whitespace' => $whitespace,
));
*/
$detail_uri = '/differential/changeset/'.$changeset->getID().'/';
$detail_button = phutil_render_tag(
'a',
array(
'style' => 'float: right',
'class' => 'button small grey',
'href' => $detail_uri,
'target' => '_blank',
),
'Standalone View');
$uniq_id = celerity_generate_unique_node_id();
$detail = new DifferentialChangesetDetailView();
$detail->setChangeset($changeset);
$detail->addButton($detail_button);
$detail->appendChild(
phutil_render_tag(
'div',
array(
'id' => $uniq_id,
),
'<div class="differential-loading">Loading...</div>'));
$output[] = $detail->render();
$mapping[$uniq_id] = array($changeset->getID());
}
$whitespace = null;
Javelin::initBehavior('differential-populate', array(
'registry' => $mapping,
'whitespace' => $whitespace,
'uri' => '/differential/changeset/',//$render_uri,
));
/*
Javelin::initBehavior('differential-context', array(
'uri' => $render_uri,
));
if ($edit) {
require_static('remarkup-css');
Javelin::initBehavior('differential-inline', array(
'uri' => '/differential/feedback/'.$revision->getID().'/',
));
}
*/
return
'<div class="differential-review-stage">'.
implode("\n", $output).
'</div>';
}
}

View file

@ -0,0 +1,19 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/differential/constants/changetype');
phutil_require_module('phabricator', 'applications/differential/view/changesetdetailview');
phutil_require_module('phabricator', 'infratructure/celerity/api');
phutil_require_module('phabricator', 'infratructure/javelin/api');
phutil_require_module('phabricator', 'view/base');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
phutil_require_source('DifferentialChangesetListView.php');

View file

@ -26,6 +26,7 @@ final class DifferentialDiffTableOfContentsView extends AphrontView {
} }
public function render() { public function render() {
require_celerity_resource('differential-table-of-contents-css');
$rows = array(); $rows = array();

View file

@ -7,6 +7,7 @@
phutil_require_module('phabricator', 'applications/differential/constants/changetype'); phutil_require_module('phabricator', 'applications/differential/constants/changetype');
phutil_require_module('phabricator', 'infratructure/celerity/api');
phutil_require_module('phabricator', 'view/base'); phutil_require_module('phabricator', 'view/base');
phutil_require_module('phutil', 'markup'); phutil_require_module('phutil', 'markup');

View file

@ -33,3 +33,12 @@ function require_celerity_resource($symbol) {
$response = CelerityAPI::getStaticResourceResponse(); $response = CelerityAPI::getStaticResourceResponse();
$response->requireResource($symbol); $response->requireResource($symbol);
} }
function celerity_generate_unique_node_id() {
static $uniq = 0;
$response = CelerityAPI::getStaticResourceResponse();
$block = $response->getMetadataBlock();
return 'UQ'.$block.'_'.($uniq++);
}

View file

@ -21,6 +21,31 @@ final class CelerityStaticResourceResponse {
private $symbols = array(); private $symbols = array();
private $needsResolve = true; private $needsResolve = true;
private $resolved; private $resolved;
private $metadata = array();
private $metadataBlock = 0;
private $behaviors = array();
public function __construct() {
if (isset($_REQUEST['__metablock__'])) {
$this->metadataBlock = (int)$_REQUEST['__metablock__'];
}
}
public function addMetadata($metadata) {
$id = count($this->metadata);
$this->metadata[$id] = $metadata;
return $this->metadataBlock.'_'.$id;
}
public function getMetadataBlock() {
return $this->metadataBlock;
}
public function initBehavior($behavior, array $config = array()) {
$this->requireResource('javelin-behavior-'.$behavior);
$this->behaviors[$behavior][] = $config;
return $this;
}
public function requireResource($symbol) { public function requireResource($symbol) {
$this->symbols[$symbol] = true; $this->symbols[$symbol] = true;
@ -55,9 +80,66 @@ final class CelerityStaticResourceResponse {
return '<link rel="stylesheet" type="text/css" href="'.$path.'" />'; return '<link rel="stylesheet" type="text/css" href="'.$path.'" />';
case 'js': case 'js':
$path = phutil_escape_html($resource['path']); $path = phutil_escape_html($resource['path']);
return '<script type="text/javascript" src="'.$path.'" />'; return '<script type="text/javascript" src="'.$path.'">'.
'</script>';
} }
throw new Exception("Unable to render resource."); throw new Exception("Unable to render resource.");
} }
public function renderHTMLFooter() {
$data = array();
if ($this->metadata) {
$json_metadata = json_encode($this->metadata);
$this->metadata = array();
} else {
$json_metadata = '{}';
}
// Even if there is no metadata on the page, Javelin uses the mergeData()
// call to start dispatching the event queue.
$data[] = 'JX.Stratcom.mergeData('.$this->metadataBlock.', '.
$json_metadata.');';
$onload = array();
if ($this->behaviors) {
$behavior = json_encode($this->behaviors);
$onload[] = 'JX.initBehaviors('.$behavior.')';
$this->behaviors = array();
}
if ($onload) {
foreach ($onload as $func) {
$data[] = 'JX.onload(function(){'.$func.'});';
}
}
if ($data) {
$data = implode("\n", $data);
return '<script type="text/javascript">//<![CDATA['."\n".
$data.'//]]></script>';
} else {
return '';
}
}
public function renderAjaxResponse($payload, $error = null) {
$response = array(
'error' => $error,
'payload' => $payload,
);
if ($this->metadata) {
$response['javelin_metadata'] = $this->metadata;
$this->metadata = array();
}
if ($this->behaviors) {
$response['javelin_behaviors'] = $this->behaviors;
$this->behaviors = array();
}
$response = 'for (;;);'.json_encode($response);
return $response;
}
} }

View file

@ -0,0 +1,24 @@
<?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 Javelin {
public static function initBehavior($behavior, array $config = array()) {
$response = CelerityAPI::getStaticResourceResponse();
$response->initBehavior($behavior, $config);
}
}

View file

@ -0,0 +1,12 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'infratructure/celerity/api');
phutil_require_source('Javelin.php');

View file

@ -0,0 +1,14 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'infratructure/celerity/api');
phutil_require_module('phutil', 'markup');
phutil_require_source('markup.php');

View file

@ -0,0 +1,55 @@
<?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.
*/
function javelin_render_tag(
$tag,
array $attributes = array(),
$content = null) {
if (isset($attributes['sigil']) ||
isset($attributes['meta']) ||
isset($attributes['mustcapture'])) {
$classes = array();
foreach ($attributes as $k => $v) {
switch ($k) {
case 'sigil':
$classes[] = 'FN_'.$v;
unset($attributes[$k]);
break;
case 'meta':
$response = CelerityAPI::getStaticResourceResponse();
$id = $response->addMetadata($v);
$classes[] = 'FD_'.$id;
unset($attributes[$k]);
break;
case 'mustcapture':
$classes[] = 'FI_CAPTURE';
unset($attributes[$k]);
break;
}
}
if (isset($attributes['class'])) {
$classes[] = $attributes['class'];
}
$attributes['class'] = implode(' ', $classes);
}
return phutil_render_tag($tag, $attributes, $content);
}

View file

@ -59,6 +59,8 @@ class PhabricatorStandardPageView extends AphrontPageView {
require_celerity_resource('phabricator-core-buttons-css'); require_celerity_resource('phabricator-core-buttons-css');
require_celerity_resource('phabricator-standard-page-view'); require_celerity_resource('phabricator-standard-page-view');
require_celerity_resource('javelin-lib-dev');
$this->bodyContent = $this->renderChildren(); $this->bodyContent = $this->renderChildren();
} }
@ -122,9 +124,7 @@ class PhabricatorStandardPageView extends AphrontPageView {
$response = CelerityAPI::getStaticResourceResponse(); $response = CelerityAPI::getStaticResourceResponse();
return return
$response->renderResourcesOfType('js'). $response->renderResourcesOfType('js').
'<script type="text/javascript">'. $response->renderHTMLFooter();
'JX.Stratcom.mergeData(0, {});'.
'</script>';
} }
} }

View file

@ -0,0 +1,122 @@
/**
* @provides syntax-highlighting-css
*/
.remarkup-code .uu { /* Forbidden Unicode */
color: #aa0066;
}
.remarkup-code .over-the-line {
color: #aa0066;
margin-right: 1px;
}
.remarkup-code td span {
padding: 1px 0 3px;
}
.remarkup-code .hll {
background-color: #ffffcc;
}
.remarkup-code .c, /* Comment */
.remarkup-code .cm, /* Comment.Multiline */
.remarkup-code .c1, /* Comment.Single */
.remarkup-code .cs { /* Comment.Special */
color: #666666;
}
.remarkup-code .sd, /* Literal.String.Doc */
.remarkup-code .sh { /* Literal.String.Heredoc */
color: #000000;
}
.remarkup-code .s, /* Literal.String */
.remarkup-code .sb, /* Literal.String.Backtick */
.remarkup-code .sc, /* Literal.String.Char */
.remarkup-code .s2, /* Literal.String.Double */
.remarkup-code .s1, /* Literal.String.Single */
.remarkup-code .sx { /* Literal.String.Other */
color: #766510;
}
.remarkup-code .sr { /* Literal.String.Regex */
color: #BB6688;
}
.remarkup-code .nv, /* Name.Variable */
.remarkup-code .vi, /* Name.Variable.Instance */
.remarkup-code .vg { /* Name.Variable.Global */
color: #001294;
}
.remarkup-code .na { /* Name.Attribute */
color: #354BB3;
}
.remarkup-code .kc, /* Keyword.Constant */
.remarkup-code .no { /* Name.Constant */
color: #000A65;
}
.remarkup-code .k, /* Keyword */
.remarkup-code .kd, /* Keyword.Declaration */
.remarkup-code .kn, /* Keyword.Namespace */
.remarkup-code .kt { /* Keyword.Type */
color: #AA4000;
}
.remarkup-code .cp, /* Comment.Preproc */
.remarkup-code .kp, /* Keyword.Pseudo */
.remarkup-code .kr, /* Keyword.Reserved */
.remarkup-code .nb, /* Name.Builtin */
.remarkup-code .bp { /* Name.Builtin.Pseudo */
color: #304A96;
}
.remarkup-code .nc, /* Name.Class */
.remarkup-code .nt, /* Name.Tag */
.remarkup-code .vc { /* Name.Variable.Class */
color: #00702A;
}
.remarkup-code .nf, /* Name.Function */
.remarkup-code .nx { /* Name.Other */
color: #004012;
}
.remarkup-code .o, /* Operator */
.remarkup-code .ss { /* Literal.String.Symbol */
color: #AA2211;
}
.remarkup-code .m, /* Literal.Number */
.remarkup-code .mf, /* Literal.Number.Float */
.remarkup-code .mh, /* Literal.Number.Hex */
.remarkup-code .mi, /* Literal.Number.Integer */
.remarkup-code .mo, /* Literal.Number.Oct */
.remarkup-code .il { /* Literal.Number.Integer.Long */
color: #601200;
}
.remarkup-code .gd { color: #A00000 } /* Generic.Deleted */
.remarkup-code .ge { } /* Generic.Emph */
.remarkup-code .gr { color: #FF0000 } /* Generic.Error */
.remarkup-code .gh { color: #000080; } /* Generic.Heading */
.remarkup-code .gi { color: #00A000 } /* Generic.Inserted */
.remarkup-code .go { color: #808080 } /* Generic.Output */
.remarkup-code .gp { color: #000080 } /* Generic.Prompt */
.remarkup-code .gs { } /* Generic.Strong */
.remarkup-code .gu { color: #800080 } /* Generic.Subheading */
.remarkup-code .gt { color: #0040D0 } /* Generic.Traceback */
.remarkup-code .nd { color: #AA22FF } /* Name.Decorator */
.remarkup-code .ni { color: #999999 } /* Name.Entity */
.remarkup-code .ne { color: #D2413A } /* Name.Exception */
.remarkup-code .nl { color: #A0A000 } /* Name.Label */
.remarkup-code .nn { color: #0000FF } /* Name.Namespace */
.remarkup-code .ow { color: #AA22FF } /* Operator.Word */
.remarkup-code .w { color: #bbbbbb } /* Text.Whitespace */
.remarkup-code .se { color: #BB6622 } /* Literal.String.Escape */
.remarkup-code .si { color: #BB6688 } /* Literal.String.Interpol */

View file

@ -0,0 +1,22 @@
/**
* @provides javelin-behavior-differential-populate
*/
JX.behavior('differential-populate', function(config) {
function onresponse(target, response) {
JX.DOM.replace(JX.$(target), JX.HTML(response));
}
var uri;
for (var k in config.registry) {
uri = config.uri + config.registry[k][0] + '/';
new JX.Request(uri, JX.bind(null, onresponse, k))
.setData({
against: config.registry[k][1],
whitespace: config.whitespace
})
.send();
}
});