mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
Genericize implementing views which expose common attributes
Summary: Some views expose some/most/all of the basics (id, class, sigil, metadata, etc); let them extend a dedicated view to get it for free. Test Plan: Viewed home page, paste, mobile dropdown, etc. Reviewers: btrahan, chad Reviewed By: btrahan CC: aran Differential Revision: https://secure.phabricator.com/D4440
This commit is contained in:
parent
65fbbd06c6
commit
dc09d60185
4 changed files with 183 additions and 81 deletions
|
@ -83,6 +83,7 @@ phutil_register_library_map(array(
|
||||||
'AphrontResponse' => 'aphront/response/AphrontResponse.php',
|
'AphrontResponse' => 'aphront/response/AphrontResponse.php',
|
||||||
'AphrontSideNavFilterView' => 'view/layout/AphrontSideNavFilterView.php',
|
'AphrontSideNavFilterView' => 'view/layout/AphrontSideNavFilterView.php',
|
||||||
'AphrontTableView' => 'view/control/AphrontTableView.php',
|
'AphrontTableView' => 'view/control/AphrontTableView.php',
|
||||||
|
'AphrontTagView' => 'view/AphrontTagView.php',
|
||||||
'AphrontTokenizerTemplateView' => 'view/control/AphrontTokenizerTemplateView.php',
|
'AphrontTokenizerTemplateView' => 'view/control/AphrontTokenizerTemplateView.php',
|
||||||
'AphrontTypeaheadTemplateView' => 'view/control/AphrontTypeaheadTemplateView.php',
|
'AphrontTypeaheadTemplateView' => 'view/control/AphrontTypeaheadTemplateView.php',
|
||||||
'AphrontURIMapper' => 'aphront/AphrontURIMapper.php',
|
'AphrontURIMapper' => 'aphront/AphrontURIMapper.php',
|
||||||
|
@ -1515,6 +1516,7 @@ phutil_register_library_map(array(
|
||||||
'AphrontRequestTestCase' => 'PhabricatorTestCase',
|
'AphrontRequestTestCase' => 'PhabricatorTestCase',
|
||||||
'AphrontSideNavFilterView' => 'AphrontView',
|
'AphrontSideNavFilterView' => 'AphrontView',
|
||||||
'AphrontTableView' => 'AphrontView',
|
'AphrontTableView' => 'AphrontView',
|
||||||
|
'AphrontTagView' => 'AphrontView',
|
||||||
'AphrontTokenizerTemplateView' => 'AphrontView',
|
'AphrontTokenizerTemplateView' => 'AphrontView',
|
||||||
'AphrontTypeaheadTemplateView' => 'AphrontView',
|
'AphrontTypeaheadTemplateView' => 'AphrontView',
|
||||||
'AphrontUsageException' => 'AphrontException',
|
'AphrontUsageException' => 'AphrontException',
|
||||||
|
@ -2305,7 +2307,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorManiphestConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
'PhabricatorManiphestConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
'PhabricatorMarkupCache' => 'PhabricatorCacheDAO',
|
'PhabricatorMarkupCache' => 'PhabricatorCacheDAO',
|
||||||
'PhabricatorMenuItemView' => 'AphrontView',
|
'PhabricatorMenuItemView' => 'AphrontView',
|
||||||
'PhabricatorMenuView' => 'AphrontView',
|
'PhabricatorMenuView' => 'AphrontTagView',
|
||||||
'PhabricatorMetaMTAController' => 'PhabricatorController',
|
'PhabricatorMetaMTAController' => 'PhabricatorController',
|
||||||
'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO',
|
'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO',
|
||||||
'PhabricatorMetaMTAEmailBodyParserTestCase' => 'PhabricatorTestCase',
|
'PhabricatorMetaMTAEmailBodyParserTestCase' => 'PhabricatorTestCase',
|
||||||
|
|
158
src/view/AphrontTagView.php
Normal file
158
src/view/AphrontTagView.php
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View which renders down to a single tag, and provides common access for tag
|
||||||
|
* attributes (setting classes, sigils, IDs, etc).
|
||||||
|
*/
|
||||||
|
abstract class AphrontTagView extends AphrontView {
|
||||||
|
|
||||||
|
private $id;
|
||||||
|
private $classes = array();
|
||||||
|
private $sigils = array();
|
||||||
|
private $style;
|
||||||
|
private $metadata;
|
||||||
|
private $mustCapture;
|
||||||
|
private $workflow;
|
||||||
|
|
||||||
|
|
||||||
|
public function setWorkflow($workflow) {
|
||||||
|
$this->workflow = $workflow;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getWorkflow() {
|
||||||
|
return $this->workflow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setMustCapture($must_capture) {
|
||||||
|
$this->mustCapture = $must_capture;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMustCapture() {
|
||||||
|
return $this->mustCapture;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function setMetadata(array $metadata) {
|
||||||
|
$this->metadata = $metadata;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function getMetadata() {
|
||||||
|
return $this->metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function setStyle($style) {
|
||||||
|
$this->style = $style;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function getStyle() {
|
||||||
|
return $this->style;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function addSigil($sigil) {
|
||||||
|
$this->sigils[] = $sigil;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function getSigil() {
|
||||||
|
return $this->sigil;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addClass($class) {
|
||||||
|
$this->classes[] = $class;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getClass() {
|
||||||
|
return $this->class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setID($id) {
|
||||||
|
$this->id = $id;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getID() {
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getTagName() {
|
||||||
|
return 'div';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getTagAttributes() {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getTagContent() {
|
||||||
|
return $this->renderChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function willRender() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function render() {
|
||||||
|
$this->willRender();
|
||||||
|
|
||||||
|
$attributes = $this->getTagAttributes();
|
||||||
|
|
||||||
|
$implode = array('class', 'sigil');
|
||||||
|
foreach ($implode as $attr) {
|
||||||
|
if (isset($attributes[$attr])) {
|
||||||
|
if (is_array($attributes[$attr])) {
|
||||||
|
$attributes[$attr] = implode(' ', $attributes[$attr]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($attributes)) {
|
||||||
|
$class = get_class($this);
|
||||||
|
throw new Exception(
|
||||||
|
"View '{$class}' did not return an array from getTagAttributes()!");
|
||||||
|
}
|
||||||
|
|
||||||
|
$sigils = $this->sigils;
|
||||||
|
if ($this->workflow) {
|
||||||
|
$sigils[] = 'workflow';
|
||||||
|
}
|
||||||
|
|
||||||
|
$tag_view_attributes = array(
|
||||||
|
'id' => $this->id,
|
||||||
|
|
||||||
|
'class' => $this->classes ? implode(' ', $this->classes) : null,
|
||||||
|
'style' => $this->style,
|
||||||
|
|
||||||
|
'meta' => $this->metadata,
|
||||||
|
'sigil' => $sigils ? implode(' ', $sigils) : null,
|
||||||
|
'mustcapture' => $this->mustCapture,
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($tag_view_attributes as $key => $value) {
|
||||||
|
if ($value === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!isset($attributes[$key])) {
|
||||||
|
$attributes[$key] = $value;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch ($key) {
|
||||||
|
case 'class':
|
||||||
|
case 'sigil':
|
||||||
|
$attributes[$key] = $attributes[$key].' '.$value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Use the explicitly set value rather than the tag default value.
|
||||||
|
$attributes[$key] = $value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return javelin_render_tag(
|
||||||
|
$this->getTagName(),
|
||||||
|
$attributes,
|
||||||
|
$this->getTagContent());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
final class PhabricatorMenuItemView extends AphrontView {
|
final class PhabricatorMenuItemView extends AphrontTagView {
|
||||||
|
|
||||||
const TYPE_LINK = 'type-link';
|
const TYPE_LINK = 'type-link';
|
||||||
const TYPE_SPACER = 'type-spacer';
|
const TYPE_SPACER = 'type-spacer';
|
||||||
|
@ -11,19 +11,9 @@ final class PhabricatorMenuItemView extends AphrontView {
|
||||||
private $type = self::TYPE_LINK;
|
private $type = self::TYPE_LINK;
|
||||||
private $isExternal;
|
private $isExternal;
|
||||||
private $key;
|
private $key;
|
||||||
private $classes = array();
|
|
||||||
private $workflow;
|
|
||||||
private $sortOrder = 1.0;
|
private $sortOrder = 1.0;
|
||||||
private $icon;
|
private $icon;
|
||||||
private $selected;
|
private $selected;
|
||||||
private $sigils = array();
|
|
||||||
private $metadata;
|
|
||||||
private $id;
|
|
||||||
|
|
||||||
public function setID($id) {
|
|
||||||
$this->id = $id;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setProperty($property) {
|
public function setProperty($property) {
|
||||||
$this->property = $property;
|
$this->property = $property;
|
||||||
|
@ -34,16 +24,6 @@ final class PhabricatorMenuItemView extends AphrontView {
|
||||||
return $this->property;
|
return $this->property;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setMetadata($metadata) {
|
|
||||||
$this->metadata = $metadata;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addSigil($sigil) {
|
|
||||||
$this->sigils[] = $sigil;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setSelected($selected) {
|
public function setSelected($selected) {
|
||||||
$this->selected = $selected;
|
$this->selected = $selected;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -107,20 +87,6 @@ final class PhabricatorMenuItemView extends AphrontView {
|
||||||
return $this->isExternal;
|
return $this->isExternal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addClass($class) {
|
|
||||||
$this->classes[] = $class;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setWorkflow($workflow) {
|
|
||||||
$this->workflow = $workflow;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getWorkflow() {
|
|
||||||
return $this->workflow;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setSortOrder($order) {
|
public function setSortOrder($order) {
|
||||||
$this->sortOrder = $order;
|
$this->sortOrder = $order;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -130,14 +96,21 @@ final class PhabricatorMenuItemView extends AphrontView {
|
||||||
return $this->sortOrder;
|
return $this->sortOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render() {
|
protected function getTagName() {
|
||||||
$classes = array(
|
return $this->href ? 'a' : 'div';
|
||||||
'phabricator-menu-item-view',
|
}
|
||||||
'phabricator-menu-item-'.$this->type,
|
|
||||||
|
protected function getTagAttributes() {
|
||||||
|
return array(
|
||||||
|
'class' => array(
|
||||||
|
'phabricator-menu-item-view',
|
||||||
|
'phabricator-menu-item-'.$this->type,
|
||||||
|
),
|
||||||
|
'href' => $this->href,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
$classes = array_merge($classes, $this->classes);
|
protected function getTagContent() {
|
||||||
|
|
||||||
$name = null;
|
$name = null;
|
||||||
if ($this->name) {
|
if ($this->name) {
|
||||||
$external = null;
|
$external = null;
|
||||||
|
@ -152,27 +125,7 @@ final class PhabricatorMenuItemView extends AphrontView {
|
||||||
phutil_escape_html($this->name.$external));
|
phutil_escape_html($this->name.$external));
|
||||||
}
|
}
|
||||||
|
|
||||||
$sigils = $this->sigils;
|
return $this->renderChildren().$name;
|
||||||
if ($this->workflow) {
|
|
||||||
$sigils[] = 'workflow';
|
|
||||||
}
|
|
||||||
if ($sigils) {
|
|
||||||
$sigils = implode(' ', $sigils);
|
|
||||||
} else {
|
|
||||||
$sigils = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return javelin_render_tag(
|
|
||||||
$this->href ? 'a' : 'div',
|
|
||||||
array(
|
|
||||||
'class' => implode(' ', $classes),
|
|
||||||
'href' => $this->href,
|
|
||||||
'sigil' => $sigils,
|
|
||||||
'meta' => $this->metadata,
|
|
||||||
'id' => $this->id,
|
|
||||||
),
|
|
||||||
$this->renderChildren().
|
|
||||||
$name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
final class PhabricatorMenuView extends AphrontView {
|
final class PhabricatorMenuView extends AphrontTagView {
|
||||||
|
|
||||||
private $items = array();
|
private $items = array();
|
||||||
private $classes = array();
|
|
||||||
|
|
||||||
public function addClass($class) {
|
|
||||||
$this->classes[] = $class;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function newLabel($name) {
|
public function newLabel($name) {
|
||||||
$item = id(new PhabricatorMenuItemView())
|
$item = id(new PhabricatorMenuItemView())
|
||||||
|
@ -59,7 +53,7 @@ final class PhabricatorMenuView extends AphrontView {
|
||||||
return $this->items;
|
return $this->items;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render() {
|
protected function willRender() {
|
||||||
$key_map = array();
|
$key_map = array();
|
||||||
foreach ($this->items as $item) {
|
foreach ($this->items as $item) {
|
||||||
$key = $item->getKey();
|
$key = $item->getKey();
|
||||||
|
@ -71,16 +65,11 @@ final class PhabricatorMenuView extends AphrontView {
|
||||||
$key_map[$key] = $item;
|
$key_map[$key] = $item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$classes = $this->classes;
|
|
||||||
$classes[] = 'phabricator-menu-view';
|
|
||||||
|
|
||||||
return phutil_render_tag(
|
|
||||||
'div',
|
|
||||||
array(
|
|
||||||
'class' => implode(' ', $classes),
|
|
||||||
),
|
|
||||||
$this->renderChildren());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getTagAttributes() {
|
||||||
|
return array(
|
||||||
|
'class' => 'phabricator-menu-view',
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue