1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-22 21:40:55 +01:00

Examples using JX.View

Summary: Provide a dirt-simple working example of client-side templating and
reactive programming.

Test Plan: Load the examples

Reviewers: epriestley, mroch, tomo

Reviewed By: epriestley

CC: ide, schrockn, aran, rzadorozny, epriestley

Differential Revision: 908
This commit is contained in:
adonohue 2011-09-07 14:01:13 -07:00
parent d5cb67d8c4
commit 7d2a18d883
19 changed files with 732 additions and 10 deletions

View file

@ -819,6 +819,16 @@ celerity_register_resource_map(array(
),
'disk' => '/rsrc/js/javelin/ext/reactor/core/DynVal.js',
),
0 =>
array(
'uri' => '/res/11520eb6/rsrc/js/javelin/lib/__tests__/JSON.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-json',
),
'disk' => '/rsrc/js/javelin/lib/__tests__/JSON.js',
),
'javelin-event' =>
array(
'uri' => '/res/f42fa6ea/rsrc/js/javelin/core/Event.js',
@ -1438,6 +1448,148 @@ celerity_register_resource_map(array(
),
'disk' => '/rsrc/css/application/uiexample/example.css',
),
'phabricator-uiexample-javelin-view' =>
array(
'uri' => '/res/a2ce2cfc/rsrc/js/application/uiexample/JavelinViewExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
2 => 'javelin-util',
3 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/uiexample/JavelinViewExample.js',
),
'phabricator-uiexample-reactor-button' =>
array(
'uri' => '/res/142127f6/rsrc/js/application/uiexample/ReactorButtonExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorButtonExample.js',
),
'phabricator-uiexample-reactor-checkbox' =>
array(
'uri' => '/res/c75cb9e9/rsrc/js/application/uiexample/ReactorCheckboxExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorCheckboxExample.js',
),
'phabricator-uiexample-reactor-focus' =>
array(
'uri' => '/res/3cc992eb/rsrc/js/application/uiexample/ReactorFocusExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorFocusExample.js',
),
'phabricator-uiexample-reactor-input' =>
array(
'uri' => '/res/4953da16/rsrc/js/application/uiexample/ReactorInputExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-reactor-dom',
5 => 'javelin-view-html',
6 => 'javelin-view-interpreter',
7 => 'javelin-view-renderer',
),
'disk' => '/rsrc/js/application/uiexample/ReactorInputExample.js',
),
'phabricator-uiexample-reactor-mouseover' =>
array(
'uri' => '/res/52a355b6/rsrc/js/application/uiexample/ReactorMouseoverExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorMouseoverExample.js',
),
'phabricator-uiexample-reactor-radio' =>
array(
'uri' => '/res/ae87f3af/rsrc/js/application/uiexample/ReactorRadioExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorRadioExample.js',
),
'phabricator-uiexample-reactor-select' =>
array(
'uri' => '/res/23cb448a/rsrc/js/application/uiexample/ReactorSelectExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorSelectExample.js',
),
'phabricator-uiexample-reactor-sendclass' =>
array(
'uri' => '/res/8cd34264/rsrc/js/application/uiexample/ReactorSendClassExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorSendClassExample.js',
),
'phabricator-uiexample-reactor-sendproperties' =>
array(
'uri' => '/res/18af54aa/rsrc/js/application/uiexample/ReactorSendPropertiesExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorSendPropertiesExample.js',
),
'phriction-document-css' =>
array(
'uri' => '/res/a0eb9ea1/rsrc/css/application/phriction/phriction-document-css.css',
@ -1465,16 +1617,6 @@ celerity_register_resource_map(array(
),
'disk' => '/rsrc/css/core/syntax.css',
),
0 =>
array(
'uri' => '/res/11520eb6/rsrc/js/javelin/lib/__tests__/JSON.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-json',
),
'disk' => '/rsrc/js/javelin/lib/__tests__/JSON.js',
),
), array(
'packages' =>
array(

View file

@ -49,6 +49,7 @@ phutil_register_library_map(array(
'AphrontHeadsupActionView' => 'view/layout/headsup/action',
'AphrontIsolatedDatabaseConnection' => 'storage/connection/isolated',
'AphrontIsolatedDatabaseConnectionTestCase' => 'storage/connection/isolated/__tests__',
'AphrontJavelinView' => 'view/javelin-view',
'AphrontKeyboardShortcutsAvailableView' => 'view/widget/keyboardshortcuts',
'AphrontListFilterView' => 'view/layout/listfilter',
'AphrontMySQLDatabaseConnection' => 'storage/connection/mysql',
@ -323,6 +324,9 @@ phutil_register_library_map(array(
'HeraldTranscriptListController' => 'applications/herald/controller/transcriptlist',
'HeraldValueTypeConfig' => 'applications/herald/config/valuetype',
'Javelin' => 'infrastructure/javelin/api',
'JavelinReactorExample' => 'applications/uiexample/examples/reactor',
'JavelinViewExample' => 'applications/uiexample/examples/client',
'JavelinViewExampleServerView' => 'applications/uiexample/examples/client',
'LiskDAO' => 'storage/lisk/dao',
'LiskIsolationTestCase' => 'storage/lisk/dao/__tests__',
'LiskIsolationTestDAO' => 'storage/lisk/dao/__tests__',
@ -781,6 +785,7 @@ phutil_register_library_map(array(
'AphrontHeadsupActionView' => 'AphrontView',
'AphrontIsolatedDatabaseConnection' => 'AphrontDatabaseConnection',
'AphrontIsolatedDatabaseConnectionTestCase' => 'PhabricatorTestCase',
'AphrontJavelinView' => 'AphrontView',
'AphrontKeyboardShortcutsAvailableView' => 'AphrontView',
'AphrontListFilterView' => 'AphrontView',
'AphrontMySQLDatabaseConnection' => 'AphrontDatabaseConnection',
@ -984,6 +989,9 @@ phutil_register_library_map(array(
'HeraldTranscript' => 'HeraldDAO',
'HeraldTranscriptController' => 'HeraldController',
'HeraldTranscriptListController' => 'HeraldController',
'JavelinReactorExample' => 'PhabricatorUIExample',
'JavelinViewExample' => 'PhabricatorUIExample',
'JavelinViewExampleServerView' => 'AphrontView',
'LiskIsolationTestCase' => 'PhabricatorTestCase',
'LiskIsolationTestDAO' => 'LiskDAO',
'ManiphestAuxiliaryFieldDefaultSpecification' => 'ManiphestAuxiliaryFieldSpecification',

View file

@ -0,0 +1,59 @@
<?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 JavelinViewExample extends PhabricatorUIExample {
public function getName() {
return 'Javelin Views';
}
public function getDescription() {
return 'Mix and match client and server views.';
}
public function renderExample() {
$request = $this->getRequest();
$init = $request->getStr('init');
$parent_server_template = new JavelinViewExampleServerView();
$parent_client_template = new AphrontJavelinView();
$parent_client_template
->setName('JavelinViewExample')
->setCelerityResource('phabricator-uiexample-javelin-view');
$child_server_template = new JavelinViewExampleServerView();
$child_client_template = new AphrontJavelinView();
$child_client_template
->setName('JavelinViewExample')
->setCelerityResource('phabricator-uiexample-javelin-view');
$parent_server_template->appendChild($parent_client_template);
$parent_client_template->appendChild($child_server_template);
$child_server_template->appendChild($child_client_template);
$child_client_template->appendChild('Hey, it worked.');
$panel = new AphrontPanelView();
$panel->appendChild($parent_server_template);
return $panel;
}
}

View file

@ -0,0 +1,27 @@
<?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 JavelinViewExampleServerView extends AphrontView {
public function render() {
return phutil_render_tag(
'div',
array('class' => 'server-view'),
$this->renderChildren()
);
}
}

View file

@ -0,0 +1,18 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/uiexample/examples/base');
phutil_require_module('phabricator', 'view/base');
phutil_require_module('phabricator', 'view/javelin-view');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'markup');
phutil_require_source('JavelinViewExample.php');
phutil_require_source('JavelinViewExampleServerView.php');

View file

@ -0,0 +1,105 @@
<?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 JavelinReactorExample extends PhabricatorUIExample {
public function getName() {
return 'Javelin Reactor Examples';
}
public function getDescription() {
return 'Lots of code';
}
public function renderExample() {
$rows = array();
$examples = array(
array(
'Reactive button only generates a stream of events',
'ReactorButtonExample',
'phabricator-uiexample-reactor-button',
array(),
),
array(
'Reactive checkbox generates a boolean dynamic value',
'ReactorCheckboxExample',
'phabricator-uiexample-reactor-checkbox',
array('checked' => true)
),
array(
'Reactive focus detector generates a boolean dynamic value',
'ReactorFocusExample',
'phabricator-uiexample-reactor-focus',
array(),
),
array(
'Reactive input box, with normal and calmed output',
'ReactorInputExample',
'phabricator-uiexample-reactor-input',
array('init' => 'Initial value'),
),
array(
'Reactive mouseover detector generates a boolean dynamic value',
'ReactorMouseoverExample',
'phabricator-uiexample-reactor-mouseover',
array(),
),
array(
'Reactive radio buttons generate a string dynamic value',
'ReactorRadioExample',
'phabricator-uiexample-reactor-radio',
array(),
),
array(
'Reactive select box generates a string dynamic value',
'ReactorSelectExample',
'phabricator-uiexample-reactor-select',
array(),
),
array(
'sendclass makes the class of an element a string dynamic value',
'ReactorSendClassExample',
'phabricator-uiexample-reactor-sendclass',
array()
),
array(
'sendproperties makes some properties of an object into dynamic values',
'ReactorSendPropertiesExample',
'phabricator-uiexample-reactor-sendproperties',
array(),
),
);
foreach ($examples as $example) {
list($desc, $name, $resource, $params) = $example;
$template = new AphrontJavelinView();
$template
->setName($name)
->setParameters($params)
->setCelerityResource($resource);
$rows[] = array($desc, $template->render());
}
$table = new AphrontTableView($rows);
$panel = new AphrontPanelView();
$panel->appendChild($table);
return $panel;
}
}

View file

@ -0,0 +1,15 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/uiexample/examples/base');
phutil_require_module('phabricator', 'view/control/table');
phutil_require_module('phabricator', 'view/javelin-view');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_source('JavelinReactorExample.php');

View file

@ -0,0 +1,87 @@
<?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 AphrontJavelinView extends AphrontView {
private static $renderContext = array();
private static function peekRenderContext() {
return nonempty(end(self::$renderContext), null);
}
private static function popRenderContext() {
return array_pop(self::$renderContext);
}
private static function pushRenderContext($token) {
self::$renderContext[] = $token;
}
private $name;
private $parameters;
private $celerityResource;
public function render() {
$id = celerity_generate_unique_node_id();
$placeholder = "<span id={$id} />";
require_celerity_resource($this->getCelerityResource());
$render_context = self::peekRenderContext();
self::pushRenderContext($id);
Javelin::initBehavior('view-placeholder', array(
'id' => $id,
'view' => $this->getName(),
'params' => $this->getParameters(),
'children' => $this->renderChildren(),
'trigger_id' => $render_context,
));
self::popRenderContext();
return $placeholder;
}
protected function getName() {
return $this->name;
}
final public function setName($template_name) {
$this->name = $template_name;
return $this;
}
protected function getParameters() {
return $this->parameters;
}
final public function setParameters($template_parameters) {
$this->parameters = $template_parameters;
return $this;
}
protected function getCelerityResource() {
return $this->celerityResource;
}
final public function setCelerityResource($celerity_resource) {
$this->celerityResource = $celerity_resource;
return $this;
}
}

View file

@ -0,0 +1,16 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'infrastructure/celerity/api');
phutil_require_module('phabricator', 'infrastructure/javelin/api');
phutil_require_module('phabricator', 'view/base');
phutil_require_module('phutil', 'utils');
phutil_require_source('AphrontJavelinView.php');

View file

@ -0,0 +1,20 @@
/**
* @provides phabricator-uiexample-javelin-view
* @requires javelin-install
* javelin-view
* javelin-util
* javelin-dom
*/
JX.install('JavelinViewExample', {
extend: 'View',
members: {
render: function(rendered_children) {
return JX.$N(
'div',
{ className: 'client-view' },
rendered_children
);
}
}
});

View file

@ -0,0 +1,38 @@
/**
* @provides phabricator-uiexample-reactor-button
* @requires javelin-install
* javelin-view
* javelin-util
* javelin-dom
* javelin-reactor-dom
*/
JX.install('ReactorButtonExample', {
extend: 'View',
members: {
render: function(rendered_children) {
var button = JX.$N('button', {}, "Fun");
var clicks = JX.RDOM.clickPulses(button);
var time = JX.RDOM.time();
// function snapshot(pulses, dynval) {
// return new DynVal(
// pulses.transform(JX.bind(dynval, dynval.getValueNow)),
// dynval.getValueNow()
// );
// }
//
// Below could be...
// time.snapshot(clicks)
// clicks.snapshot(time)
var snapshot_time = new JX.DynVal(
clicks.transform(JX.bind(time, time.getValueNow)),
time.getValueNow()
);
return [button, JX.RDOM.$DT(snapshot_time)];
}
}
});

View file

@ -0,0 +1,19 @@
/**
* @provides phabricator-uiexample-reactor-checkbox
* @requires javelin-install
* javelin-view
* javelin-util
* javelin-dom
* javelin-reactor-dom
*/
JX.install('ReactorCheckboxExample', {
extend: 'View',
members: {
render: function(rendered_children) {
var checkbox = JX.$N('input', {type: 'checkbox'});
return [checkbox, JX.RDOM.$DT(JX.RDOM.checkbox(checkbox))];
}
}
});

View file

@ -0,0 +1,18 @@
/**
* @provides phabricator-uiexample-reactor-focus
* @requires javelin-install
* javelin-view
* javelin-util
* javelin-dom
* javelin-reactor-dom
*/
JX.install('ReactorFocusExample', {
extend: 'View',
members: {
render: function(rendered_children) {
var input = JX.$N('input');
return [input, JX.RDOM.$DT(JX.RDOM.hasFocus(input))];
}
}
});

View file

@ -0,0 +1,35 @@
/**
* @provides phabricator-uiexample-reactor-input
* @requires javelin-install
* javelin-view
* javelin-util
* javelin-dom
* javelin-reactor-dom
* javelin-view-html
* javelin-view-interpreter
* javelin-view-renderer
*/
JX.install('ReactorInputExample', {
extend: 'View',
members: {
render: function(rendered_children) {
var html = JX.HTMLView.registerToInterpreter(new JX.ViewInterpreter());
var raw_input = JX.ViewRenderer.render(
html.input({ value: this.getAttr('init') })
);
var input = JX.RDOM.input(raw_input);
return JX.ViewRenderer.render(
html.div(
raw_input,
html.br(),
html.span(JX.RDOM.$DT(input)),
html.br(),
html.span(JX.RDOM.$DT(input.calm(500)))
)
);
}
}
});

View file

@ -0,0 +1,18 @@
/**
* @provides phabricator-uiexample-reactor-mouseover
* @requires javelin-install
* javelin-view
* javelin-util
* javelin-dom
* javelin-reactor-dom
*/
JX.install('ReactorMouseoverExample', {
extend: 'View',
members: {
render: function(rendered_children) {
var target = JX.$N("span", "mouseover me ");
return [target, JX.RDOM.$DT(JX.RDOM.isMouseOver(target))];
}
}
});

View file

@ -0,0 +1,26 @@
/**
* @provides phabricator-uiexample-reactor-radio
* @requires javelin-install
* javelin-view
* javelin-util
* javelin-dom
* javelin-reactor-dom
*/
JX.install('ReactorRadioExample', {
extend: 'View',
members: {
render: function(rendered_children) {
var radio_one = JX.$N('input', {type: 'radio', name: 'n', value: 'one'});
var radio_two = JX.$N('input', {type: 'radio', name: 'n', value: 'two'});
radio_one.checked = true;
return [
radio_one,
radio_two,
JX.RDOM.$DT(JX.RDOM.radio([radio_one, radio_two]))
];
}
}
});

View file

@ -0,0 +1,23 @@
/**
* @provides phabricator-uiexample-reactor-select
* @requires javelin-install
* javelin-view
* javelin-util
* javelin-dom
* javelin-reactor-dom
*/
JX.install('ReactorSelectExample', {
extend: 'View',
members: {
render: function(rendered_children) {
var select = JX.$N('select', {}, [
JX.$N('option', { value: 'goat' }, 'Goat'),
JX.$N('option', { value: 'bat' }, 'Bat'),
JX.$N('option', { value: 'duck' }, 'Duck'),
]);
return [select, JX.RDOM.$DT(JX.RDOM.select(select))];
}
}
});

View file

@ -0,0 +1,20 @@
/**
* @provides phabricator-uiexample-reactor-sendclass
* @requires javelin-install
* javelin-view
* javelin-util
* javelin-dom
* javelin-reactor-dom
*/
JX.install('ReactorSendClassExample', {
extend: 'View',
members: {
render: function(rendered_children) {
var input = JX.$N('input', { type: 'checkbox' });
var span = JX.$N('a', 'Hey');
JX.RDOM.sendClass(JX.RDOM.checkbox(input), span, 'disabled');
return [input, span];
}
}
});

View file

@ -0,0 +1,28 @@
/**
* @provides phabricator-uiexample-reactor-sendproperties
* @requires javelin-install
* javelin-view
* javelin-util
* javelin-dom
* javelin-reactor-dom
*/
JX.install('ReactorSendPropertiesExample', {
extend: 'View',
members: {
render: function(rendered_children) {
var color = JX.$N('input', {value: '#fff000'});
var title = JX.$N('input', {value: 'seen on hover'});
var target = JX.$N('span', 'Change my color and title');
JX.RDOM.sendProps(target, {
style: {
backgroundColor: JX.RDOM.input(color)
},
title: JX.RDOM.input(title)
});
return [color, title, target];
}
}
});