Correct Aphlict websocket URI construction after PHP8 compatibility changes
[phabricator.git] / src / view / phui / PHUIPropertyListView.php
blob62fa30bba846fc1946e0ea2787b1386728896f76
1 <?php
3 final class PHUIPropertyListView extends AphrontView {
5 private $parts = array();
6 private $hasKeyboardShortcuts;
7 private $object;
8 private $invokedWillRenderEvent;
9 private $actionList = null;
10 private $classes = array();
11 private $stacked;
13 const ICON_SUMMARY = 'fa-align-left';
14 const ICON_TESTPLAN = 'fa-file-text-o';
16 protected function canAppendChild() {
17 return false;
20 public function setObject($object) {
21 $this->object = $object;
22 return $this;
25 public function setActionList(PhabricatorActionListView $list) {
26 $this->actionList = $list;
27 return $this;
30 public function getActionList() {
31 return $this->actionList;
34 public function setStacked($stacked) {
35 $this->stacked = $stacked;
36 return $this;
39 public function addClass($class) {
40 $this->classes[] = $class;
41 return $this;
44 public function setHasKeyboardShortcuts($has_keyboard_shortcuts) {
45 $this->hasKeyboardShortcuts = $has_keyboard_shortcuts;
46 return $this;
49 public function addProperty($key, $value) {
50 $current = array_pop($this->parts);
52 if (!$current || $current['type'] != 'property') {
53 if ($current) {
54 $this->parts[] = $current;
56 $current = array(
57 'type' => 'property',
58 'list' => array(),
62 $current['list'][] = array(
63 'key' => $key,
64 'value' => $value,
67 $this->parts[] = $current;
68 return $this;
71 public function addSectionHeader($name, $icon = null) {
72 $this->parts[] = array(
73 'type' => 'section',
74 'name' => $name,
75 'icon' => $icon,
77 return $this;
80 public function addTextContent($content) {
81 $this->parts[] = array(
82 'type' => 'text',
83 'content' => $content,
85 return $this;
88 public function addRawContent($content) {
89 $this->parts[] = array(
90 'type' => 'raw',
91 'content' => $content,
93 return $this;
96 public function addImageContent($content) {
97 $this->parts[] = array(
98 'type' => 'image',
99 'content' => $content,
101 return $this;
104 public function invokeWillRenderEvent() {
105 if ($this->object && $this->getUser() && !$this->invokedWillRenderEvent) {
106 $event = new PhabricatorEvent(
107 PhabricatorEventType::TYPE_UI_WILLRENDERPROPERTIES,
108 array(
109 'object' => $this->object,
110 'view' => $this,
112 $event->setUser($this->getUser());
113 PhutilEventEngine::dispatchEvent($event);
115 $this->invokedWillRenderEvent = true;
118 public function hasAnyProperties() {
119 $this->invokeWillRenderEvent();
121 if ($this->parts) {
122 return true;
125 return false;
128 public function render() {
129 $this->invokeWillRenderEvent();
131 require_celerity_resource('phui-property-list-view-css');
133 $items = array();
135 $parts = $this->parts;
137 // If we have an action list, make sure we render a property part, even
138 // if there are no properties. Otherwise, the action list won't render.
139 if ($this->actionList) {
140 $this->classes[] = 'phui-property-list-has-actions';
141 $have_property_part = false;
142 foreach ($this->parts as $part) {
143 if ($part['type'] == 'property') {
144 $have_property_part = true;
145 break;
148 if (!$have_property_part) {
149 $parts[] = array(
150 'type' => 'property',
151 'list' => array(),
156 foreach ($parts as $part) {
157 $type = $part['type'];
158 switch ($type) {
159 case 'property':
160 $items[] = $this->renderPropertyPart($part);
161 break;
162 case 'section':
163 $items[] = $this->renderSectionPart($part);
164 break;
165 case 'text':
166 case 'image':
167 $items[] = $this->renderTextPart($part);
168 break;
169 case 'raw':
170 $items[] = $this->renderRawPart($part);
171 break;
172 default:
173 throw new Exception(pht("Unknown part type '%s'!", $type));
176 $this->classes[] = 'phui-property-list-section';
177 $classes = implode(' ', $this->classes);
179 return phutil_tag(
180 'div',
181 array(
182 'class' => $classes,
184 array(
185 $items,
189 private function renderPropertyPart(array $part) {
190 $items = array();
191 foreach ($part['list'] as $spec) {
192 $key = $spec['key'];
193 $value = $spec['value'];
195 // NOTE: We append a space to each value to improve the behavior when the
196 // user double-clicks a property value (like a URI) to select it. Without
197 // the space, the label is also selected.
199 $items[] = phutil_tag(
200 'dt',
201 array(
202 'class' => 'phui-property-list-key',
204 array($key, ' '));
206 $items[] = phutil_tag(
207 'dd',
208 array(
209 'class' => 'phui-property-list-value',
211 array($value, ' '));
214 $stacked = '';
215 if ($this->stacked) {
216 $stacked = 'phui-property-list-stacked';
219 $list = phutil_tag(
220 'dl',
221 array(
222 'class' => 'phui-property-list-properties',
224 $items);
226 $shortcuts = null;
227 if ($this->hasKeyboardShortcuts) {
228 $shortcuts = new AphrontKeyboardShortcutsAvailableView();
231 $list = phutil_tag(
232 'div',
233 array(
234 'class' => 'phui-property-list-properties-wrap '.$stacked,
236 array($shortcuts, $list));
238 $action_list = null;
239 if ($this->actionList) {
240 $action_list = phutil_tag(
241 'div',
242 array(
243 'class' => 'phui-property-list-actions',
245 $this->actionList);
246 $this->actionList = null;
249 return phutil_tag(
250 'div',
251 array(
252 'class' => 'phui-property-list-container grouped',
254 array($action_list, $list));
257 private function renderSectionPart(array $part) {
258 $name = $part['name'];
259 if ($part['icon']) {
260 $icon = id(new PHUIIconView())
261 ->setIcon($part['icon'].' bluegrey');
262 $name = phutil_tag(
263 'span',
264 array(
265 'class' => 'phui-property-list-section-header-icon',
267 array($icon, $name));
270 return phutil_tag(
271 'div',
272 array(
273 'class' => 'phui-property-list-section-header',
275 $name);
278 private function renderTextPart(array $part) {
279 $classes = array();
280 $classes[] = 'phui-property-list-text-content';
281 if ($part['type'] == 'image') {
282 $classes[] = 'phui-property-list-image-content';
284 return phutil_tag(
285 'div',
286 array(
287 'class' => implode(' ', $classes),
289 $part['content']);
292 private function renderRawPart(array $part) {
293 $classes = array();
294 $classes[] = 'phui-property-list-raw-content';
295 return phutil_tag(
296 'div',
297 array(
298 'class' => implode(' ', $classes),
300 $part['content']);