Index: trunk/phase3/includes/HTMLForm.php |
— | — | @@ -16,32 +16,32 @@ |
17 | 17 | * The constructor input is an associative array of $fieldname => $info, |
18 | 18 | * where $info is an Associative Array with any of the following: |
19 | 19 | * |
20 | | - * 'class' -- the subclass of HTMLFormField that will be used |
21 | | - * to create the object. *NOT* the CSS class! |
22 | | - * 'type' -- roughly translates into the <select> type attribute. |
23 | | - * if 'class' is not specified, this is used as a map |
24 | | - * through HTMLForm::$typeMappings to get the class name. |
25 | | - * 'default' -- default value when the form is displayed |
26 | | - * 'id' -- HTML id attribute |
27 | | - * 'cssclass' -- CSS class |
28 | | - * 'options' -- varies according to the specific object. |
29 | | - * 'label-message' -- message key for a message to use as the label. |
30 | | - * can be an array of msg key and then parameters to |
31 | | - * the message. |
32 | | - * 'label' -- alternatively, a raw text message. Overridden by |
33 | | - * label-message |
34 | | - * 'help-message' -- message key for a message to use as a help text. |
35 | | - * can be an array of msg key and then parameters to |
36 | | - * the message. |
37 | | - * 'required' -- passed through to the object, indicating that it |
38 | | - * is a required field. |
39 | | - * 'size' -- the length of text fields |
40 | | - * 'filter-callback -- a function name to give you the chance to |
41 | | - * massage the inputted value before it's processed. |
42 | | - * @see HTMLForm::filter() |
43 | | - * 'validation-callback' -- a function name to give you the chance |
44 | | - * to impose extra validation on the field input. |
45 | | - * @see HTMLForm::validate() |
| 20 | + * 'class' -- the subclass of HTMLFormField that will be used |
| 21 | + * to create the object. *NOT* the CSS class! |
| 22 | + * 'type' -- roughly translates into the <select> type attribute. |
| 23 | + * if 'class' is not specified, this is used as a map |
| 24 | + * through HTMLForm::$typeMappings to get the class name. |
| 25 | + * 'default' -- default value when the form is displayed |
| 26 | + * 'id' -- HTML id attribute |
| 27 | + * 'cssclass' -- CSS class |
| 28 | + * 'options' -- varies according to the specific object. |
| 29 | + * 'label-message' -- message key for a message to use as the label. |
| 30 | + * can be an array of msg key and then parameters to |
| 31 | + * the message. |
| 32 | + * 'label' -- alternatively, a raw text message. Overridden by |
| 33 | + * label-message |
| 34 | + * 'help-message' -- message key for a message to use as a help text. |
| 35 | + * can be an array of msg key and then parameters to |
| 36 | + * the message. |
| 37 | + * 'required' -- passed through to the object, indicating that it |
| 38 | + * is a required field. |
| 39 | + * 'size' -- the length of text fields |
| 40 | + * 'filter-callback -- a function name to give you the chance to |
| 41 | + * massage the inputted value before it's processed. |
| 42 | + * @see HTMLForm::filter() |
| 43 | + * 'validation-callback' -- a function name to give you the chance |
| 44 | + * to impose extra validation on the field input. |
| 45 | + * @see HTMLForm::validate() |
46 | 46 | * |
47 | 47 | * TODO: Document 'section' / 'subsection' stuff |
48 | 48 | */ |
— | — | @@ -187,10 +187,10 @@ |
188 | 188 | * The here's-one-I-made-earlier option: do the submission if |
189 | 189 | * posted, or display the form with or without funky valiation |
190 | 190 | * errors |
191 | | - * @return Bool whether submission was successful. |
| 191 | + * @return Bool or Status whether submission was successful. |
192 | 192 | */ |
193 | 193 | function show() { |
194 | | - // Check if we have the info we need |
| 194 | + # Check if we have the info we need |
195 | 195 | if ( ! $this->mTitle ) { |
196 | 196 | throw new MWException( "You must call setTitle() on an HTMLForm" ); |
197 | 197 | } |
— | — | @@ -209,9 +209,7 @@ |
210 | 210 | $result = $this->trySubmit(); |
211 | 211 | } |
212 | 212 | |
213 | | - if ( $result === true || |
214 | | - ( $result instanceof Status && $result->isGood() ) ) |
215 | | - { |
| 213 | + if ( $result === true || ( $result instanceof Status && $result->isGood() ) ){ |
216 | 214 | return $result; |
217 | 215 | } |
218 | 216 | |
— | — | @@ -708,6 +706,10 @@ |
709 | 707 | return call_user_func( $this->mValidationCallback, $value, $alldata ); |
710 | 708 | } |
711 | 709 | |
| 710 | + if ( isset( $this->mParams['required'] ) && $value === '' ) { |
| 711 | + return wfMsgExt( 'htmlform-required', 'parseinline' ); |
| 712 | + } |
| 713 | + |
712 | 714 | return true; |
713 | 715 | } |
714 | 716 | |
— | — | @@ -1001,20 +1003,6 @@ |
1002 | 1004 | |
1003 | 1005 | return Html::element( 'input', $attribs ); |
1004 | 1006 | } |
1005 | | - |
1006 | | - public function validate( $value, $alldata ) { |
1007 | | - $p = parent::validate( $value, $alldata ); |
1008 | | - |
1009 | | - if ( $p !== true ) { |
1010 | | - return $p; |
1011 | | - } |
1012 | | - |
1013 | | - if ( isset( $this->mParams['required'] ) && $value === '' ) { |
1014 | | - return wfMsgExt( 'htmlform-required', 'parseinline' ); |
1015 | | - } |
1016 | | - |
1017 | | - return true; |
1018 | | - } |
1019 | 1007 | } |
1020 | 1008 | class HTMLTextAreaField extends HTMLFormField { |
1021 | 1009 | function getCols() { |
— | — | @@ -1054,20 +1042,6 @@ |
1055 | 1043 | |
1056 | 1044 | return Html::element( 'textarea', $attribs, $value ); |
1057 | 1045 | } |
1058 | | - |
1059 | | - public function validate( $value, $alldata ) { |
1060 | | - $p = parent::validate( $value, $alldata ); |
1061 | | - |
1062 | | - if ( $p !== true ) { |
1063 | | - return $p; |
1064 | | - } |
1065 | | - |
1066 | | - if ( isset( $this->mParams['required'] ) && $value === '' ) { |
1067 | | - return wfMsgExt( 'htmlform-required', 'parseinline' ); |
1068 | | - } |
1069 | | - |
1070 | | - return true; |
1071 | | - } |
1072 | 1046 | } |
1073 | 1047 | |
1074 | 1048 | /** |
— | — | @@ -1086,8 +1060,12 @@ |
1087 | 1061 | if ( $p !== true ) { |
1088 | 1062 | return $p; |
1089 | 1063 | } |
| 1064 | + |
| 1065 | + $value = trim( $value ); |
1090 | 1066 | |
1091 | | - if ( floatval( $value ) != $value ) { |
| 1067 | + # http://dev.w3.org/html5/spec/common-microsyntaxes.html#real-numbers |
| 1068 | + # with the addition that a leading '+' sign is ok. |
| 1069 | + if ( !preg_match( '/^(\+|\-)?\d+(\.\d+)?(E(\+|\-)?\d+)?$/i', $value ) ) { |
1092 | 1070 | return wfMsgExt( 'htmlform-float-invalid', 'parse' ); |
1093 | 1071 | } |
1094 | 1072 | |
— | — | @@ -1124,8 +1102,13 @@ |
1125 | 1103 | return $p; |
1126 | 1104 | } |
1127 | 1105 | |
1128 | | - if ( $value !== '' |
1129 | | - && ( !is_numeric( $value ) || round( $value ) != $value ) |
| 1106 | + # http://dev.w3.org/html5/spec/common-microsyntaxes.html#signed-integers |
| 1107 | + # with the addition that a leading '+' sign is ok. Note that leading zeros |
| 1108 | + # are fine, and will be left in the input, which is useful for things like |
| 1109 | + # phone numbers when you know that they are integers (the HTML5 type=tel |
| 1110 | + # input does not require its value to be numeric). If you want a tidier |
| 1111 | + # value to, eg, save in the DB, clean it up with intval(). |
| 1112 | + if ( !preg_match( '/^(\+|\-)?\d*$/', trim( $value ) ) |
1130 | 1113 | ) { |
1131 | 1114 | return wfMsgExt( 'htmlform-int-invalid', 'parse' ); |
1132 | 1115 | } |
— | — | @@ -1346,11 +1329,13 @@ |
1347 | 1330 | $html .= Html::rawElement( 'h1', array(), $label ) . "\n"; |
1348 | 1331 | $html .= $this->formatOptions( $info, $value ); |
1349 | 1332 | } else { |
1350 | | - $thisAttribs = array( 'id' => $this->mID . "-$info", 'value' => $info ); |
| 1333 | + $thisAttribs = array( 'id' => "{$this->mID}-$info", 'value' => $info ); |
1351 | 1334 | |
1352 | | - $checkbox = Xml::check( $this->mName . '[]', in_array( $info, $value, true ), |
1353 | | - $attribs + $thisAttribs ); |
1354 | | - $checkbox .= ' ' . Html::rawElement( 'label', array( 'for' => $this->mID . "-$info" ), $label ); |
| 1335 | + $checkbox = Xml::check( |
| 1336 | + $this->mName . '[]', |
| 1337 | + in_array( $info, $value, true ), |
| 1338 | + $attribs + $thisAttribs ); |
| 1339 | + $checkbox .= ' ' . Html::rawElement( 'label', array( 'for' => "{$this->mID}-$info" ), $label ); |
1355 | 1340 | |
1356 | 1341 | $html .= $checkbox . '<br />'; |
1357 | 1342 | } |
— | — | @@ -1490,6 +1475,10 @@ |
1491 | 1476 | # forcing the 'wp' prefix on hidden field names |
1492 | 1477 | # is undesirable |
1493 | 1478 | $this->mName = substr( $this->mName, 2 ); |
| 1479 | + |
| 1480 | + # Per HTML5 spec, hidden fields cannot be 'required' |
| 1481 | + # http://dev.w3.org/html5/spec/states-of-the-type-attribute.html#hidden-state |
| 1482 | + unset( $this->mParams['required'] ); |
1494 | 1483 | } |
1495 | 1484 | |
1496 | 1485 | public function getTableRow( $value ) { |
— | — | @@ -1535,6 +1524,13 @@ |
1536 | 1525 | protected function needsLabel() { |
1537 | 1526 | return false; |
1538 | 1527 | } |
| 1528 | + |
| 1529 | + /** |
| 1530 | + * Button cannot be invalid |
| 1531 | + */ |
| 1532 | + public function validate( $value, $alldata ){ |
| 1533 | + return true; |
| 1534 | + } |
1539 | 1535 | } |
1540 | 1536 | |
1541 | 1537 | class HTMLEditTools extends HTMLFormField { |