1
0
Fork 0
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:
epriestley 2013-01-16 10:50:41 -08:00
parent 65fbbd06c6
commit dc09d60185
4 changed files with 183 additions and 81 deletions

View file

@ -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
View 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());
}
}

View file

@ -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);
} }
} }

View file

@ -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',
);
}
} }