PageRenderTime 51ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/src/view/phui/PHUIListView.php

http://github.com/facebook/phabricator
PHP | 207 lines | 164 code | 40 blank | 3 comment | 24 complexity | b3db810b10eabc6e52a6a9f7167180f3 MD5 | raw file
Possible License(s): JSON, MPL-2.0-no-copyleft-exception, Apache-2.0, BSD-3-Clause, LGPL-2.0, MIT, LGPL-2.1, LGPL-3.0
  1. <?php
  2. final class PHUIListView extends AphrontTagView {
  3. const NAVBAR_LIST = 'phui-list-navbar';
  4. const NAVBAR_VERTICAL = 'phui-list-navbar-vertical';
  5. const SIDENAV_LIST = 'phui-list-sidenav';
  6. const TABBAR_LIST = 'phui-list-tabbar';
  7. private $items = array();
  8. private $type;
  9. protected function canAppendChild() {
  10. return false;
  11. }
  12. public function newLabel($name, $key = null) {
  13. $item = id(new PHUIListItemView())
  14. ->setType(PHUIListItemView::TYPE_LABEL)
  15. ->setName($name);
  16. if ($key !== null) {
  17. $item->setKey($key);
  18. }
  19. $this->addMenuItem($item);
  20. return $item;
  21. }
  22. public function newLink($name, $href, $key = null) {
  23. $item = id(new PHUIListItemView())
  24. ->setType(PHUIListItemView::TYPE_LINK)
  25. ->setName($name)
  26. ->setHref($href);
  27. if ($key !== null) {
  28. $item->setKey($key);
  29. }
  30. $this->addMenuItem($item);
  31. return $item;
  32. }
  33. public function newButton($name, $href) {
  34. $item = id(new PHUIListItemView())
  35. ->setType(PHUIListItemView::TYPE_BUTTON)
  36. ->setName($name)
  37. ->setHref($href);
  38. $this->addMenuItem($item);
  39. return $item;
  40. }
  41. public function addMenuItem(PHUIListItemView $item) {
  42. return $this->addMenuItemAfter(null, $item);
  43. }
  44. public function addMenuItemAfter($key, PHUIListItemView $item) {
  45. if ($key === null) {
  46. $this->items[] = $item;
  47. return $this;
  48. }
  49. if (!$this->getItem($key)) {
  50. throw new Exception(pht("No such key '%s' to add menu item after!",
  51. $key));
  52. }
  53. $result = array();
  54. foreach ($this->items as $other) {
  55. $result[] = $other;
  56. if ($other->getKey() == $key) {
  57. $result[] = $item;
  58. }
  59. }
  60. $this->items = $result;
  61. return $this;
  62. }
  63. public function addMenuItemBefore($key, PHUIListItemView $item) {
  64. if ($key === null) {
  65. array_unshift($this->items, $item);
  66. return $this;
  67. }
  68. $this->requireKey($key);
  69. $result = array();
  70. foreach ($this->items as $other) {
  71. if ($other->getKey() == $key) {
  72. $result[] = $item;
  73. }
  74. $result[] = $other;
  75. }
  76. $this->items = $result;
  77. return $this;
  78. }
  79. public function addMenuItemToLabel($key, PHUIListItemView $item) {
  80. $this->requireKey($key);
  81. $other = $this->getItem($key);
  82. if ($other->getType() != PHUIListItemView::TYPE_LABEL) {
  83. throw new Exception(pht("Menu item '%s' is not a label!", $key));
  84. }
  85. $seen = false;
  86. $after = null;
  87. foreach ($this->items as $other) {
  88. if (!$seen) {
  89. if ($other->getKey() == $key) {
  90. $seen = true;
  91. }
  92. } else {
  93. if ($other->getType() == PHUIListItemView::TYPE_LABEL) {
  94. break;
  95. }
  96. }
  97. $after = $other->getKey();
  98. }
  99. return $this->addMenuItemAfter($after, $item);
  100. }
  101. private function requireKey($key) {
  102. if (!$this->getItem($key)) {
  103. throw new Exception(pht("No menu item with key '%s' exists!", $key));
  104. }
  105. }
  106. public function getItem($key) {
  107. $key = (string)$key;
  108. // NOTE: We could optimize this, but need to update any map when items have
  109. // their keys change. Since that's moderately complex, wait for a profile
  110. // or use case.
  111. foreach ($this->items as $item) {
  112. if ($item->getKey() == $key) {
  113. return $item;
  114. }
  115. }
  116. return null;
  117. }
  118. public function getItems() {
  119. return $this->items;
  120. }
  121. public function willRender() {
  122. $key_map = array();
  123. foreach ($this->items as $item) {
  124. $key = $item->getKey();
  125. if ($key !== null) {
  126. if (isset($key_map[$key])) {
  127. throw new Exception(
  128. pht("Menu contains duplicate items with key '%s'!", $key));
  129. }
  130. $key_map[$key] = $item;
  131. }
  132. }
  133. }
  134. protected function getTagName() {
  135. return 'ul';
  136. }
  137. public function setType($type) {
  138. $this->type = $type;
  139. return $this;
  140. }
  141. protected function getTagAttributes() {
  142. require_celerity_resource('phui-list-view-css');
  143. $classes = array();
  144. $classes[] = 'phui-list-view';
  145. if ($this->type) {
  146. switch ($this->type) {
  147. case self::NAVBAR_LIST:
  148. $classes[] = 'phui-list-navbar';
  149. $classes[] = 'phui-list-navbar-horizontal';
  150. break;
  151. case self::NAVBAR_VERTICAL:
  152. $classes[] = 'phui-list-navbar';
  153. $classes[] = 'phui-list-navbar-vertical';
  154. break;
  155. default:
  156. $classes[] = $this->type;
  157. break;
  158. }
  159. }
  160. return array(
  161. 'class' => implode(' ', $classes),
  162. );
  163. }
  164. protected function getTagContent() {
  165. return $this->items;
  166. }
  167. }