MediaWiki master
HTMLTextField.php
Go to the documentation of this file.
1<?php
2
4
7use OOUI\Widget;
8
25 protected $mPlaceholder = '';
26
38 public function __construct( $params ) {
39 if ( isset( $params['autocomplete'] ) && is_bool( $params['autocomplete'] ) ) {
40 $params['autocomplete'] = $params['autocomplete'] ? 'on' : 'off';
41 }
42
43 parent::__construct( $params );
44
45 if ( isset( $params['placeholder-message'] ) ) {
46 $this->mPlaceholder = $this->getMessage( $params['placeholder-message'] )->text();
47 } elseif ( isset( $params['placeholder'] ) ) {
48 $this->mPlaceholder = $params['placeholder'];
49 }
50 }
51
56 public function getSize() {
57 return $this->mParams['size'] ?? 45;
58 }
59
63 public function getSpellCheck() {
64 $val = $this->mParams['spellcheck'] ?? null;
65 if ( is_bool( $val ) ) {
66 // "spellcheck" attribute literally requires "true" or "false" to work.
67 return $val ? 'true' : 'false';
68 }
69 return null;
70 }
71
75 public function isPersistent() {
76 if ( isset( $this->mParams['persistent'] ) ) {
77 return $this->mParams['persistent'];
78 }
79 // don't put passwords into the HTML body, they could get cached or otherwise leaked
80 return !( isset( $this->mParams['type'] ) && $this->mParams['type'] === 'password' );
81 }
82
87 public function getInputHTML( $value ) {
88 if ( !$this->isPersistent() ) {
89 $value = '';
90 }
91
92 $attribs = [
93 'id' => $this->mID,
94 'name' => $this->mName,
95 'size' => $this->getSize(),
96 'value' => $value,
97 'dir' => $this->mDir,
98 'spellcheck' => $this->getSpellCheck(),
99 ] + $this->getTooltipAndAccessKey() + $this->getDataAttribs();
100
101 if ( $this->mClass !== '' ) {
102 $attribs['class'] = $this->mClass;
103 }
104 if ( $this->mPlaceholder !== '' ) {
105 $attribs['placeholder'] = $this->mPlaceholder;
106 }
107
108 # @todo Enforce pattern, step, required, readonly on the server side as
109 # well
110 $allowedParams = [
111 'type',
112 'min',
113 'max',
114 'step',
115 'title',
116 'maxlength',
117 'minlength',
118 'tabindex',
119 'disabled',
120 'required',
121 'autofocus',
122 'readonly',
123 'autocomplete',
124 'inputmode',
125 // Only used in HTML mode:
126 'pattern',
127 'list',
128 ];
129
130 $attribs += $this->getAttributes( $allowedParams );
131
132 # Extract 'type'
133 $type = $this->getType( $attribs );
134
135 $inputHtml = Html::input( $this->mName, $value, $type, $attribs );
136 return $inputHtml;
137 }
138
143 protected function getType( &$attribs ) {
144 $type = $attribs['type'] ?? 'text';
145 unset( $attribs['type'] );
146
147 # Implement tiny differences between some field variants
148 # here, rather than creating a new class for each one which
149 # is essentially just a clone of this one.
150 if ( isset( $this->mParams['type'] ) ) {
151 switch ( $this->mParams['type'] ) {
152 case 'int':
153 $type = 'number';
154 $attribs['step'] = 1;
155 break;
156 case 'float':
157 $type = 'number';
158 $attribs['step'] = 'any';
159 break;
160 # Pass through
161 case 'email':
162 case 'password':
163 case 'url':
164 $type = $this->mParams['type'];
165 break;
166 case 'textwithbutton':
167 $type = $this->mParams['inputtype'] ?? 'text';
168 break;
169 }
170 }
171
172 return $type;
173 }
174
179 public function getInputOOUI( $value ) {
180 if ( !$this->isPersistent() ) {
181 $value = '';
182 }
183
184 $attribs = $this->getTooltipAndAccessKeyOOUI();
185
186 if ( $this->mClass !== '' ) {
187 $attribs['classes'] = [ $this->mClass ];
188 }
189 if ( $this->mPlaceholder !== '' ) {
190 $attribs['placeholder'] = $this->mPlaceholder;
191 }
192
193 # @todo Enforce pattern, step, required, readonly on the server side as
194 # well
195 $allowedParams = [
196 'type',
197 'min',
198 'max',
199 'step',
200 'title',
201 'maxlength',
202 'minlength',
203 'tabindex',
204 'disabled',
205 'required',
206 'autofocus',
207 'readonly',
208 'autocomplete',
209 'inputmode',
210 // Only used in OOUI mode:
211 'autosize',
212 'flags',
213 'indicator',
214 ];
215
216 $attribs += \OOUI\Element::configFromHtmlAttributes(
217 $this->getAttributes( $allowedParams )
218 );
219
220 $type = $this->getType( $attribs );
221 if ( isset( $attribs['step'] ) && $attribs['step'] === 'any' ) {
222 $attribs['step'] = null;
223 }
224
225 return $this->getInputWidget( [
226 'id' => $this->mID,
227 'name' => $this->mName,
228 'value' => $value,
229 'type' => $type,
230 'dir' => $this->mDir,
231 ] + $attribs );
232 }
233
235 public function getInputCodex( $value, $hasErrors ) {
236 if ( !$this->isPersistent() ) {
237 $value = '';
238 }
239
240 $attribs = [
241 'id' => $this->mID,
242 'name' => $this->mName,
243 'size' => $this->getSize(),
244 'value' => $value,
245 'dir' => $this->mDir,
246 'spellcheck' => $this->getSpellCheck(),
247 ] + $this->getTooltipAndAccessKey() + $this->getDataAttribs();
248
249 if ( $this->mPlaceholder !== '' ) {
250 $attribs['placeholder'] = $this->mPlaceholder;
251 }
252 $attribs['class'] = $this->mClass ? [ $this->mClass ] : [];
253
254 $allowedParams = [
255 'type',
256 'min',
257 'max',
258 'step',
259 'title',
260 'maxlength',
261 'minlength',
262 'tabindex',
263 'disabled',
264 'required',
265 'autofocus',
266 'readonly',
267 'autocomplete',
268 'inputmode',
269 'pattern',
270 'list',
271 ];
272
273 $attribs += $this->getAttributes( $allowedParams );
274
275 $extraParams = $this->getAttributes( [ 'start-icon-class', 'end-icon-class' ] );
276
277 // Extract 'type'.
278 $type = $this->getType( $attribs );
279
280 return static::buildCodexComponent( $value, $hasErrors, $type, $this->mName, $attribs, $extraParams );
281 }
282
294 public static function buildCodexComponent( $value, $hasErrors, $type, $name, $inputAttribs, $extraParams = [] ) {
295 // Set up classes for the outer <div>.
296 $wrapperClass = [ 'cdx-text-input' ];
297 if ( $hasErrors ) {
298 $wrapperClass[] = 'cdx-text-input--status-error';
299 }
300
301 $inputAttribs['class'][] = 'cdx-text-input__input';
302 $inputHtml = Html::input( $name, $value, $type, $inputAttribs );
303
304 $startIconHtml = '';
305 $endIconHtml = '';
306 if ( isset( $extraParams['start-icon-class'] ) ) {
307 $startIconHtml = Html::element( 'span', [ 'class' => [
308 'cdx-text-input__icon',
309 'cdx-text-input__start-icon',
310 $extraParams['start-icon-class'],
311 ] ] );
312 $wrapperClass[] = 'cdx-text-input--has-start-icon';
313 }
314 if ( isset( $extraParams['end-icon-class'] ) ) {
315 $endIconHtml = Html::element( 'span', [ 'class' => [
316 'cdx-text-input__icon',
317 'cdx-text-input__end-icon',
318 $extraParams['end-icon-class'],
319 ] ] );
320 $wrapperClass[] = 'cdx-text-input--has-end-icon';
321 }
322
323 return Html::rawElement(
324 'div',
325 [ 'class' => $wrapperClass ],
326 $inputHtml . $startIconHtml . $endIconHtml
327 );
328 }
329
337 protected function getInputWidget( $params ) {
338 return new \OOUI\TextInputWidget( $params );
339 }
340
347 protected function getDataAttribs() {
348 return [];
349 }
350}
351
353class_alias( HTMLTextField::class, 'HTMLTextField' );
getInputHTML( $value)
This function must be implemented to return the HTML to generate the input object itself....
static buildCodexComponent( $value, $hasErrors, $type, $name, $inputAttribs, $extraParams=[])
Build the markup of the Codex component.
getInputCodex( $value, $hasErrors)
Same as getInputHTML, but for Codex.This is called by CodexHTMLForm.If not overridden,...
getDataAttribs()
Returns an array of data-* attributes to add to the field.
getInputOOUI( $value)
Same as getInputHTML, but returns an OOUI object.Defaults to false, which getOOUI will interpret as "...
The parent class to generate form fields.
getTooltipAndAccessKey()
Returns the attributes required for the tooltip and accesskey, for Html::element() etc.
getMessage( $value)
Turns a *-message parameter (which could be a MessageSpecifier, or a message name,...
getTooltipAndAccessKeyOOUI()
Returns the attributes required for the tooltip and accesskey, for OOUI widgets' config.
getAttributes(array $list)
Returns the given attributes from the parameters.
This class is a collection of static functions that serve two purposes:
Definition Html.php:44
element(SerializerNode $parent, SerializerNode $node, $contents)