'search',
);
+ if( $wgHtml5 ) {
+ $validTypes = array_merge( $validTypes, array(
+ 'datetime',
+ 'datetime-local',
+ 'date',
+ 'month',
+ 'time',
+ 'week',
+ 'number',
+ 'range',
+ 'email',
+ 'url',
+ 'search',
+ 'tel',
+ 'color',
+ ) );
+ }
if ( isset( $attribs['type'] )
&& !in_array( $attribs['type'], $validTypes ) ) {
unset( $attribs['type'] );
return $attribs;
}
+ # Whenever altering this array, please provide a covering test case
+ # in HtmlTest::provideElementsWithAttributesHavingDefaultValues
static $attribDefaults = array(
'area' => array( 'shape' => 'rect' ),
'button' => array(
'input' => array(
'formaction' => 'GET',
'type' => 'text',
- 'value' => '',
),
'keygen' => array( 'keytype' => 'rsa' ),
'link' => array( 'media' => 'all' ),
&& strval( $attribs['type'] ) == 'text/css' ) {
unset( $attribs['type'] );
}
+ if ( $element === 'input' ) {
+ $type = isset( $attribs['type'] ) ? $attribs['type'] : null;
+ $value = isset( $attribs['value'] ) ? $attribs['value'] : null;
+ if ( $type === 'checkbox' || $type === 'radio' ) {
+ // The default value for checkboxes and radio buttons is 'on'
+ // not ''. By stripping value="" we break radio boxes that
+ // actually wants empty values.
+ if ( $value === 'on' ) {
+ unset( $attribs['value'] );
+ }
+ } elseif ( $type === 'submit' ) {
+ // The default value for submit appears to be "Submit" but
+ // let's not bother stripping out localized text that matches
+ // that.
+ } else {
+ // The default value for nearly every other field type is ''
+ // The 'range' and 'color' types use different defaults but
+ // stripping a value="" does not hurt them.
+ if ( $value === '' ) {
+ unset( $attribs['value'] );
+ }
+ }
+ }
if ( $element === 'select' && isset( $attribs['size'] ) ) {
if ( in_array( 'multiple', $attribs )
|| ( isset( $attribs['multiple'] ) && $attribs['multiple'] !== false )
);
}
+ /**
+ * @dataProvider providesHtml5InputTypes
+ */
+ function testHtmlElementAcceptsNewHtml5TypesInHtml5Mode( $HTML5InputType ) {
+ $this->enableHTML5();
+ $this->assertEquals(
+ '<input type="' . $HTML5InputType . '" />',
+ HTML::element( 'input', array( 'type' => $HTML5InputType ) ),
+ 'In HTML5, HTML::element() should accept type="' . $HTML5InputType . '"'
+ );
+ }
+
+ /**
+ * List of input element types values introduced by HTML5
+ * Full list at http://www.w3.org/TR/html-markup/input.html
+ */
+ function providesHtml5InputTypes() {
+ $types = array(
+ 'datetime',
+ 'datetime-local',
+ 'date',
+ 'month',
+ 'time',
+ 'week',
+ 'number',
+ 'range',
+ 'email',
+ 'url',
+ 'search',
+ 'tel',
+ 'color',
+ );
+ $cases = array();
+ foreach( $types as $type ) {
+ $cases[] = array( $type );
+ }
+ return $cases;
+ }
+
+ /**
+ * Test out Html::element drops default value
+ * @cover Html::dropDefaults
+ * @dataProvider provideElementsWithAttributesHavingDefaultValues
+ */
+ function testDropDefaults( $expected, $element, $message = '' ) {
+ $this->enableHTML5();
+ $this->assertEquals( $expected, $element, $message );
+ }
+
+ function provideElementsWithAttributesHavingDefaultValues() {
+ # Use cases in a concise format:
+ # <expected>, <element name>, <array of attributes> [, <message>]
+ # Will be mapped to Html::element()
+ $cases = array();
+
+ ### Generic cases, match $attribDefault static array
+ $cases[] = array( '<area />',
+ 'area', array( 'shape' => 'rect' )
+ );
+
+ $cases[] = array( '<button></button>',
+ 'button', array( 'formaction' => 'GET' )
+ );
+ $cases[] = array( '<button></button>',
+ 'button', array( 'formenctype' => 'application/x-www-form-urlencoded' )
+ );
+ $cases[] = array( '<button></button>',
+ 'button', array( 'type' => 'submit' )
+ );
+
+ $cases[] = array( '<canvas></canvas>',
+ 'canvas', array( 'height' => '150' )
+ );
+ $cases[] = array( '<canvas></canvas>',
+ 'canvas', array( 'width' => '300' )
+ );
+ # Also check with numeric values
+ $cases[] = array( '<canvas></canvas>',
+ 'canvas', array( 'height' => 150 )
+ );
+ $cases[] = array( '<canvas></canvas>',
+ 'canvas', array( 'width' => 300 )
+ );
+
+ $cases[] = array( '<command />',
+ 'command', array( 'type' => 'command' )
+ );
+
+ $cases[] = array( '<form></form>',
+ 'form', array( 'action' => 'GET' )
+ );
+ $cases[] = array( '<form></form>',
+ 'form', array( 'autocomplete' => 'on' )
+ );
+ $cases[] = array( '<form></form>',
+ 'form', array( 'enctype' => 'application/x-www-form-urlencoded' )
+ );
+
+ $cases[] = array( '<input />',
+ 'input', array( 'formaction' => 'GET' )
+ );
+ $cases[] = array( '<input />',
+ 'input', array( 'type' => 'text' )
+ );
+
+ $cases[] = array( '<keygen />',
+ 'keygen', array( 'keytype' => 'rsa' )
+ );
+
+ $cases[] = array( '<link />',
+ 'link', array( 'media' => 'all' )
+ );
+
+ $cases[] = array( '<menu></menu>',
+ 'menu', array( 'type' => 'list' )
+ );
+
+ $cases[] = array( '<script></script>',
+ 'script', array( 'type' => 'text/javascript' )
+ );
+
+ $cases[] = array( '<style></style>',
+ 'style', array( 'media' => 'all' )
+ );
+ $cases[] = array( '<style></style>',
+ 'style', array( 'type' => 'text/css' )
+ );
+
+ $cases[] = array( '<textarea></textarea>',
+ 'textarea', array( 'wrap' => 'soft' )
+ );
+
+ ### SPECIFIC CASES
+
+ # <link type="text/css" />
+ $cases[] = array( '<link />',
+ 'link', array( 'type' => 'text/css' )
+ );
+
+ # <input /> specific handling
+ $cases[] = array( '<input type="checkbox" />',
+ 'input', array( 'type' => 'checkbox', 'value' => 'on' ),
+ 'Default value "on" is stripped of checkboxes',
+ );
+ $cases[] = array( '<input type="radio" />',
+ 'input', array( 'type' => 'radio', 'value' => 'on' ),
+ 'Default value "on" is stripped of radio buttons',
+ );
+ $cases[] = array( '<input type="submit" value="Submit" />',
+ 'input', array( 'type' => 'submit', 'value' => 'Submit' ),
+ 'Default value "Submit" is kept on submit buttons (for possible l10n issues)',
+ );
+ $cases[] = array( '<input type="color" />',
+ 'input', array( 'type' => 'color', 'value' => '' ),
+ );
+ $cases[] = array( '<input type="range" />',
+ 'input', array( 'type' => 'range', 'value' => '' ),
+ );
+
+ # <select /> specifc handling
+ $cases[] = array( '<select multiple=""></select>',
+ 'select', array( 'size' => '4', 'multiple' => true ),
+ );
+ # .. with numeric value
+ $cases[] = array( '<select multiple=""></select>',
+ 'select', array( 'size' => 4, 'multiple' => true ),
+ );
+ $cases[] = array( '<select></select>',
+ 'select', array( 'size' => '1', 'multiple' => false ),
+ );
+ # .. with numeric value
+ $cases[] = array( '<select></select>',
+ 'select', array( 'size' => 1, 'multiple' => false ),
+ );
+
+ # Passing an array as value
+ $cases[] = array( '<a class="css-class-one css-class-two"></a>',
+ 'a', array( 'class' => array( 'css-class-one', 'css-class-two' ) ),
+ "dropDefaults accepts values given as an array"
+ );
+
+ # FIXME: doDropDefault should remove defaults given in an array
+ # Expected should be '<a></a>'
+ $cases[] = array( '<a class=""></a>',
+ 'a', array( 'class' => array( '', '' ) ),
+ "dropDefaults accepts values given as an array"
+ );
+
+
+ # Craft the Html elements
+ $ret = array();
+ foreach( $cases as $case ) {
+ $ret[] = array(
+ $case[0],
+ Html::element( $case[1], $case[2] )
+ );
+ }
+ return $ret;
+ }
+
}