Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/view/phui/PHUIListView.php
12249 views
1
<?php
2
3
final class PHUIListView extends AphrontTagView {
4
5
const NAVBAR_LIST = 'phui-list-navbar';
6
const NAVBAR_VERTICAL = 'phui-list-navbar-vertical';
7
const SIDENAV_LIST = 'phui-list-sidenav';
8
const TABBAR_LIST = 'phui-list-tabbar';
9
10
private $items = array();
11
private $type;
12
13
protected function canAppendChild() {
14
return false;
15
}
16
17
public function newLabel($name, $key = null) {
18
$item = id(new PHUIListItemView())
19
->setType(PHUIListItemView::TYPE_LABEL)
20
->setName($name);
21
22
if ($key !== null) {
23
$item->setKey($key);
24
}
25
26
$this->addMenuItem($item);
27
28
return $item;
29
}
30
31
public function newLink($name, $href, $key = null) {
32
$item = id(new PHUIListItemView())
33
->setType(PHUIListItemView::TYPE_LINK)
34
->setName($name)
35
->setHref($href);
36
37
if ($key !== null) {
38
$item->setKey($key);
39
}
40
41
$this->addMenuItem($item);
42
43
return $item;
44
}
45
46
public function newButton($name, $href) {
47
$item = id(new PHUIListItemView())
48
->setType(PHUIListItemView::TYPE_BUTTON)
49
->setName($name)
50
->setHref($href);
51
52
$this->addMenuItem($item);
53
54
return $item;
55
}
56
57
public function addMenuItem(PHUIListItemView $item) {
58
return $this->addMenuItemAfter(null, $item);
59
}
60
61
public function addMenuItemAfter($key, PHUIListItemView $item) {
62
if ($key === null) {
63
$this->items[] = $item;
64
return $this;
65
}
66
67
if (!$this->getItem($key)) {
68
throw new Exception(pht("No such key '%s' to add menu item after!",
69
$key));
70
}
71
72
$result = array();
73
foreach ($this->items as $other) {
74
$result[] = $other;
75
if ($other->getKey() == $key) {
76
$result[] = $item;
77
}
78
}
79
80
$this->items = $result;
81
return $this;
82
}
83
84
public function addMenuItemBefore($key, PHUIListItemView $item) {
85
if ($key === null) {
86
array_unshift($this->items, $item);
87
return $this;
88
}
89
90
$this->requireKey($key);
91
92
$result = array();
93
foreach ($this->items as $other) {
94
if ($other->getKey() == $key) {
95
$result[] = $item;
96
}
97
$result[] = $other;
98
}
99
100
$this->items = $result;
101
return $this;
102
}
103
104
public function addMenuItemToLabel($key, PHUIListItemView $item) {
105
$this->requireKey($key);
106
107
$other = $this->getItem($key);
108
if ($other->getType() != PHUIListItemView::TYPE_LABEL) {
109
throw new Exception(pht("Menu item '%s' is not a label!", $key));
110
}
111
112
$seen = false;
113
$after = null;
114
foreach ($this->items as $other) {
115
if (!$seen) {
116
if ($other->getKey() == $key) {
117
$seen = true;
118
}
119
} else {
120
if ($other->getType() == PHUIListItemView::TYPE_LABEL) {
121
break;
122
}
123
}
124
$after = $other->getKey();
125
}
126
127
return $this->addMenuItemAfter($after, $item);
128
}
129
130
private function requireKey($key) {
131
if (!$this->getItem($key)) {
132
throw new Exception(pht("No menu item with key '%s' exists!", $key));
133
}
134
}
135
136
public function getItem($key) {
137
$key = (string)$key;
138
139
// NOTE: We could optimize this, but need to update any map when items have
140
// their keys change. Since that's moderately complex, wait for a profile
141
// or use case.
142
143
foreach ($this->items as $item) {
144
if ($item->getKey() == $key) {
145
return $item;
146
}
147
}
148
149
return null;
150
}
151
152
public function getItems() {
153
return $this->items;
154
}
155
156
public function willRender() {
157
$key_map = array();
158
foreach ($this->items as $item) {
159
$key = $item->getKey();
160
if ($key !== null) {
161
if (isset($key_map[$key])) {
162
throw new Exception(
163
pht("Menu contains duplicate items with key '%s'!", $key));
164
}
165
$key_map[$key] = $item;
166
}
167
}
168
}
169
170
protected function getTagName() {
171
return 'ul';
172
}
173
174
public function setType($type) {
175
$this->type = $type;
176
return $this;
177
}
178
179
protected function getTagAttributes() {
180
require_celerity_resource('phui-list-view-css');
181
$classes = array();
182
$classes[] = 'phui-list-view';
183
if ($this->type) {
184
switch ($this->type) {
185
case self::NAVBAR_LIST:
186
$classes[] = 'phui-list-navbar';
187
$classes[] = 'phui-list-navbar-horizontal';
188
break;
189
case self::NAVBAR_VERTICAL:
190
$classes[] = 'phui-list-navbar';
191
$classes[] = 'phui-list-navbar-vertical';
192
break;
193
default:
194
$classes[] = $this->type;
195
break;
196
}
197
}
198
199
return array(
200
'class' => implode(' ', $classes),
201
);
202
}
203
204
protected function getTagContent() {
205
return $this->items;
206
}
207
}
208
209