@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class PHUIButtonView extends AphrontTagView {
4
5 const GREEN = 'green';
6 const GREY = 'grey';
7 const BLUE = 'blue';
8 const RED = 'red';
9 const DISABLED = 'disabled';
10
11 const SMALL = 'small';
12 const BIG = 'big';
13
14 const BUTTONTYPE_DEFAULT = 'buttontype.default';
15 const BUTTONTYPE_SIMPLE = 'buttontype.simple';
16
17 private $size;
18 private $text;
19 private $subtext;
20 private $color;
21 private $tag = 'button';
22 private $dropdown;
23 private $icon;
24 private $iconFirst;
25 private $href = null;
26 private $title = null;
27 private $disabled;
28 private $selected;
29 private $name;
30 private $tooltip;
31 private $noCSS;
32 private $hasCaret;
33 private $buttonType = self::BUTTONTYPE_DEFAULT;
34 private $auralLabel;
35
36 public function setName($name) {
37 $this->name = $name;
38 return $this;
39 }
40
41 public function getName() {
42 return $this->name;
43 }
44
45 public function setText($text) {
46 $this->text = $text;
47 return $this;
48 }
49
50 public function setHref($href) {
51 $this->href = $href;
52 return $this;
53 }
54
55 public function setTitle($title) {
56 $this->title = $title;
57 return $this;
58 }
59
60 public function setSubtext($subtext) {
61 $this->subtext = $subtext;
62 return $this;
63 }
64
65 public function setColor($color) {
66 $this->color = $color;
67 return $this;
68 }
69
70 public function getColor() {
71 return $this->color;
72 }
73
74 public function setDisabled($disabled) {
75 $this->disabled = $disabled;
76 return $this;
77 }
78
79 public function setSelected($selected) {
80 $this->selected = $selected;
81 return $this;
82 }
83
84 /**
85 * Set the HTML tag for the button, e.g. 'button', 'input', 'a'.
86 * @param string $tag
87 */
88 public function setTag($tag) {
89 $this->tag = $tag;
90 return $this;
91 }
92
93 public function setSize($size) {
94 $this->size = $size;
95 return $this;
96 }
97
98 public function setDropdown($dd) {
99 $this->dropdown = $dd;
100 return $this;
101 }
102
103 public function setTooltip($text) {
104 $this->tooltip = $text;
105 return $this;
106 }
107
108 public function setNoCSS($no_css) {
109 $this->noCSS = $no_css;
110 return $this;
111 }
112
113 public function setHasCaret($has_caret) {
114 $this->hasCaret = $has_caret;
115 return $this;
116 }
117
118 public function getHasCaret() {
119 return $this->hasCaret;
120 }
121
122 public function setButtonType($button_type) {
123 $this->buttonType = $button_type;
124 return $this;
125 }
126
127 public function getButtonType() {
128 return $this->buttonType;
129 }
130
131 public function setAuralLabel($aural_label) {
132 $this->auralLabel = $aural_label;
133 return $this;
134 }
135
136 public function getAuralLabel() {
137 return $this->auralLabel;
138 }
139
140 /**
141 * @param PHUIIconView|string $icon
142 * @param ?bool $first
143 */
144 public function setIcon($icon, $first = true) {
145 if (!($icon instanceof PHUIIconView)) {
146 $icon = id(new PHUIIconView())
147 ->setIcon($icon);
148 }
149 $this->icon = $icon;
150 $this->iconFirst = $first;
151 return $this;
152 }
153
154 /**
155 * Get the HTML tag set for the button, e.g. 'button', 'input', 'a'.
156 * @return string
157 */
158 protected function getTagName() {
159 return $this->tag;
160 }
161
162 public function setDropdownMenu(PhabricatorActionListView $actions) {
163 Javelin::initBehavior('phui-dropdown-menu');
164
165 $this->addSigil('phui-dropdown-menu');
166 $this->setDropdown(true);
167 $this->setMetadata($actions->getDropdownMenuMetadata());
168
169 return $this;
170 }
171
172 public function setDropdownMenuID($id) {
173 Javelin::initBehavior('phui-dropdown-menu');
174
175 $this->addSigil('phui-dropdown-menu');
176 $this->setMetadata(
177 array(
178 'menuID' => $id,
179 ));
180
181 return $this;
182 }
183
184 protected function getTagAttributes() {
185
186 require_celerity_resource('phui-button-css');
187 require_celerity_resource('phui-button-simple-css');
188
189 $classes = array();
190 $classes[] = 'button';
191
192 if ($this->color) {
193 $classes[] = 'button-'.$this->color;
194 }
195
196 if ($this->size) {
197 $classes[] = $this->size;
198 }
199
200 if ($this->dropdown) {
201 $classes[] = 'dropdown';
202 }
203
204 if ($this->icon) {
205 $classes[] = 'has-icon';
206 }
207
208 if ($this->text !== null) {
209 $classes[] = 'has-text';
210 }
211
212 if ($this->iconFirst == false) {
213 $classes[] = 'icon-last';
214 }
215
216 if ($this->disabled) {
217 $classes[] = 'disabled';
218 }
219
220 if ($this->selected) {
221 $classes[] = 'selected';
222 }
223
224 switch ($this->getButtonType()) {
225 case self::BUTTONTYPE_DEFAULT:
226 $classes[] = 'phui-button-default';
227 break;
228 case self::BUTTONTYPE_SIMPLE:
229 $classes[] = 'phui-button-simple';
230 break;
231 }
232
233 $sigil = null;
234 $meta = null;
235 if ($this->tooltip) {
236 Javelin::initBehavior('phabricator-tooltips');
237 require_celerity_resource('aphront-tooltip-css');
238 $sigil = 'has-tooltip';
239 $meta = array(
240 'tip' => $this->tooltip,
241 );
242 }
243
244 if ($this->noCSS) {
245 $classes = array();
246 }
247
248 // See PHI823. If we aren't rendering a "<button>" or "<input>" tag,
249 // give the tag we are rendering a "button" role as a hint to screen
250 // readers.
251 $role = null;
252 if ($this->tag !== 'button' && $this->tag !== 'input') {
253 $role = 'button';
254 }
255
256 $attrs = array(
257 'class' => $classes,
258 'href' => $this->href,
259 'name' => $this->name,
260 'title' => $this->title,
261 'sigil' => $sigil,
262 'meta' => $meta,
263 'role' => $role,
264 );
265
266 if ($this->tag == 'input') {
267 $attrs['type'] = 'submit';
268 $attrs['value'] = $this->text;
269 }
270
271 return $attrs;
272 }
273
274 protected function getTagContent() {
275 if ($this->tag === 'input') {
276 return null;
277 }
278
279 $icon = $this->icon;
280 $text = null;
281 $subtext = null;
282
283 if ($this->subtext) {
284 $subtext = phutil_tag(
285 'div',
286 array(
287 'class' => 'phui-button-subtext',
288 ),
289 $this->subtext);
290 }
291
292 if ($this->text !== null) {
293 $text = phutil_tag(
294 'div',
295 array(
296 'class' => 'phui-button-text',
297 ),
298 array(
299 $this->text,
300 $subtext,
301 ));
302 }
303
304 $caret = null;
305 if ($this->dropdown || $this->getHasCaret()) {
306 $caret = phutil_tag('span', array('class' => 'caret'), '');
307 }
308
309 $aural = null;
310 if ($this->auralLabel !== null) {
311 $aural = phutil_tag(
312 'span',
313 array(
314 'class' => 'aural-only',
315 ),
316 $this->auralLabel);
317 }
318
319
320 if ($this->iconFirst == true) {
321 return array($aural, $icon, $text, $caret);
322 } else {
323 return array($aural, $text, $icon, $caret);
324 }
325 }
326}