Use \u{00A0} instead of   or  

Directly use the UTF-8 encoding of the 'NO-BREAK SPACE' (U+00A0) instead of
the HTML/XML entities   or   or  .

With the UTF-8 character the generated HTML is shorter and better to read.

Also change the special value for the label in HTMLForm from   to
U+00A0 but also support   for backward compability.

Bug: T154300
Change-Id: I882599ac1120789bb4e524c4394870680caca4f4
This commit is contained in:
Fomafix 2016-12-27 22:14:16 +01:00 committed by Krinkle
parent 0dead475ab
commit 125cbd8c01
31 changed files with 68 additions and 62 deletions

View file

@ -581,7 +581,7 @@ class CategoryViewer extends ContextSource {
foreach ( $colContents as $char => $articles ) {
# Change space to non-breaking space to keep headers aligned
$h3char = $char === ' ' ? ' ' : htmlspecialchars( $char );
$h3char = $char === ' ' ? "\u{00A0}" : htmlspecialchars( $char );
$ret .= '<div class="mw-category-group"><h3>' . $h3char;
$ret .= "</h3>\n";

View file

@ -927,7 +927,7 @@ class Html {
'label', [
'for' => $selectAttribs['id'] ?? null,
], $params['label']
) . '&#160;';
) . "\u{00A0}";
}
// Wrap options in a <select>

View file

@ -382,7 +382,7 @@ class Xml {
$value = false, $attribs = []
) {
list( $label, $input ) = self::inputLabelSep( $label, $name, $id, $size, $value, $attribs );
return $label . '&#160;' . $input;
return $label . "\u{00A0}" . $input;
}
/**
@ -420,7 +420,7 @@ class Xml {
public static function checkLabel( $label, $name, $id, $checked = false, $attribs = [] ) {
global $wgUseMediaWikiUIEverywhere;
$chkLabel = self::check( $name, $checked, [ 'id' => $id ] + $attribs ) .
'&#160;' .
"\u{00A0}" .
self::label( $label, $id, $attribs );
if ( $wgUseMediaWikiUIEverywhere ) {
@ -446,7 +446,7 @@ class Xml {
$checked = false, $attribs = []
) {
return self::radio( $name, $value, $checked, [ 'id' => $id ] + $attribs ) .
'&#160;' .
"\u{00A0}" .
self::label( $label, $id, $attribs );
}

View file

@ -197,8 +197,8 @@ class HistoryAction extends FormlessAction {
$content .= Xml::dateMenu(
( $year == null ? MWTimestamp::getLocalInstance()->format( 'Y' ) : $year ),
$month
) . '&#160;';
$content .= $tagSelector ? ( implode( '&#160;', $tagSelector ) . '&#160;' ) : '';
) . "\u{00A0}";
$content .= $tagSelector ? ( implode( "\u{00A0}", $tagSelector ) . "\u{00A0}" ) : '';
$content .= $checkDeleted . Html::submitButton(
$this->msg( 'historyaction-submit' )->text(),
[],

View file

@ -152,7 +152,7 @@ class ChangesList extends ContextSource {
* @param string $nothing To use for empty space
* @return string
*/
public function recentChangesFlags( $flags, $nothing = '&#160;' ) {
public function recentChangesFlags( $flags, $nothing = "\u{00A0}" ) {
$f = '';
foreach ( array_keys( $this->getConfig()->get( 'RecentChangesFlags' ) ) as $flag ) {
$f .= isset( $flags[$flag] ) && $flags[$flag]

View file

@ -715,10 +715,10 @@ class EnhancedChangesList extends ChangesList {
}
if ( isset( $data['timestampLink'] ) ) {
$line .= '&#160;' . $data['timestampLink'];
$line .= "\u{00A0}" . $data['timestampLink'];
unset( $data['timestampLink'] );
}
$line .= '&#160;</td>';
$line .= "\u{00A0}</td>";
$line .= Html::openElement( 'td', [
'class' => 'mw-changeslist-line-inner',
// Used for reliable determination of the affiliated page

View file

@ -312,7 +312,7 @@ class DifferenceEngine extends ContextSource {
$rollbackLink = Linker::generateRollback( $this->mNewRev, $this->getContext() );
if ( $rollbackLink ) {
$out->preventClickjacking();
$rollback = '&#160;&#160;&#160;' . $rollbackLink;
$rollback = "\u{00A0}\u{00A0}\u{00A0}" . $rollbackLink;
}
}
@ -342,7 +342,7 @@ class DifferenceEngine extends ContextSource {
[ 'diff' => 'prev', 'oldid' => $this->mOldid ] + $query
);
} else {
$prevlink = '&#160;';
$prevlink = "\u{00A0}";
}
if ( $this->mOldRev->isMinor() ) {
@ -395,7 +395,7 @@ class DifferenceEngine extends ContextSource {
[ 'diff' => 'next', 'oldid' => $this->mNewid ] + $query
);
} else {
$nextlink = '&#160;';
$nextlink = "\u{00A0}";
}
if ( $this->mNewRev->isMinor() ) {
@ -586,7 +586,7 @@ class DifferenceEngine extends ContextSource {
protected function revisionDeleteLink( $rev ) {
$link = Linker::getRevDeleteLink( $this->getUser(), $rev, $rev->getTitle() );
if ( $link !== '' ) {
$link = '&#160;&#160;&#160;' . $link . ' ';
$link = "\u{00A0}\u{00A0}\u{00A0}" . $link . ' ';
}
return $link;

View file

@ -43,9 +43,9 @@ class TableDiffFormatter extends DiffFormatter {
* @return mixed
*/
public static function escapeWhiteSpace( $msg ) {
$msg = preg_replace( '/^ /m', '&#160; ', $msg );
$msg = preg_replace( '/ $/m', ' &#160;', $msg );
$msg = preg_replace( '/ /', '&#160; ', $msg );
$msg = preg_replace( '/^ /m', "\u{00A0} ", $msg );
$msg = preg_replace( '/ $/m', " \u{00A0}", $msg );
$msg = preg_replace( '/ /', "\u{00A0} ", $msg );
return $msg;
}
@ -123,7 +123,7 @@ class TableDiffFormatter extends DiffFormatter {
* @return string
*/
protected function contextLine( $line ) {
return $this->wrapLine( '&#160;', 'diff-context', $line );
return $this->wrapLine( "\u{00A0}", 'diff-context', $line );
}
/**
@ -146,7 +146,7 @@ class TableDiffFormatter extends DiffFormatter {
* @return string
*/
protected function emptyLine() {
return '<td colspan="2">&#160;</td>';
return "<td colspan=\"2\">\u{00A0}</td>";
}
/**

View file

@ -66,7 +66,7 @@ class WordAccumulator {
array_push( $this->lines, $this->line );
} else {
# make empty lines visible by inserting an NBSP
array_push( $this->lines, '&#160;' );
array_push( $this->lines, "\u{00A0}" );
}
$this->line = '';
}

View file

@ -1662,7 +1662,7 @@ class HTMLForm extends ContextSource {
$html[] = $retval;
$labelValue = trim( $value->getLabel() );
if ( $labelValue !== '&#160;' && $labelValue !== '' ) {
if ( $labelValue !== "\u{00A0}" && $labelValue !== '' ) {
$hasLabel = true;
}

View file

@ -397,9 +397,9 @@ abstract class HTMLFormField {
if ( isset( $params['label-message'] ) ) {
$this->mLabel = $this->getMessage( $params['label-message'] )->parse();
} elseif ( isset( $params['label'] ) ) {
if ( $params['label'] === '&#160;' ) {
if ( $params['label'] === '&#160;' || $params['label'] === "\u{00A0}" ) {
// Apparently some things set &nbsp directly and in an odd format
$this->mLabel = '&#160;';
$this->mLabel = "\u{00A0}";
} else {
$this->mLabel = htmlspecialchars( $params['label'] );
}
@ -546,7 +546,7 @@ abstract class HTMLFormField {
$horizontalLabel = $this->mParams['horizontal-label'] ?? false;
if ( $horizontalLabel ) {
$field = '&#160;' . $inputHtml . "\n$errors";
$field = "\u{00A0}" . $inputHtml . "\n$errors";
} else {
$field = Html::rawElement(
'div',
@ -630,7 +630,7 @@ abstract class HTMLFormField {
// the element could specify, that the label doesn't need to be added
$label = $this->getLabel();
if ( $label && $label !== '&#160;' ) {
if ( $label && $label !== "\u{00A0}" ) {
$config['label'] = new OOUI\HtmlSnippet( $label );
}
@ -745,7 +745,7 @@ abstract class HTMLFormField {
$label = $this->getLabelHtml( $cellAttributes );
$html = "\n" . $errors .
$label . '&#160;' .
$label . "\u{00A0}" .
$inputHtml .
$helptext;
@ -926,7 +926,13 @@ abstract class HTMLFormField {
* @return string HTML
*/
public function getLabel() {
return is_null( $this->mLabel ) ? '' : $this->mLabel;
if ( is_null( $this->mLabel ) ) {
return '';
}
if ( $this->mLabel === '&#160;' ) {
return "\u{00A0}";
}
return $this->mLabel;
}
public function getLabelHtml( $cellAttributes = [] ) {
@ -940,7 +946,7 @@ abstract class HTMLFormField {
$labelValue = trim( $this->getLabel() );
$hasLabel = false;
if ( $labelValue !== '&#160;' && $labelValue !== '' ) {
if ( $labelValue !== "\u{00A0}" && $labelValue !== '' ) {
$hasLabel = true;
}

View file

@ -46,9 +46,9 @@ class HTMLButtonField extends HTMLFormField {
if ( isset( $info['buttonlabel-message'] ) ) {
$this->buttonLabel = $this->getMessage( $info['buttonlabel-message'] )->parse();
} elseif ( isset( $info['buttonlabel'] ) ) {
if ( $info['buttonlabel'] === '&#160;' ) {
if ( $info['buttonlabel'] === '&#160;' || $info['buttonlabel'] === "\u{00A0}" ) {
// Apparently some things set &nbsp directly and in an odd format
$this->buttonLabel = '&#160;';
$this->buttonLabel = "\u{00A0}";
} else {
$this->buttonLabel = htmlspecialchars( $info['buttonlabel'] );
}

View file

@ -27,7 +27,7 @@ class HTMLCheckField extends HTMLFormField {
}
$chkLabel = Xml::check( $this->mName, $value, $attr ) .
'&#160;' .
"\u{00A0}" .
Html::rawElement( 'label', $attrLabel, $this->mLabel );
if ( $wgUseMediaWikiUIEverywhere || $this->mParent instanceof VFormHTMLForm ) {
@ -88,7 +88,7 @@ class HTMLCheckField extends HTMLFormField {
) {
return '';
} else {
return '&#160;';
return "\u{00A0}";
}
}

View file

@ -88,7 +88,7 @@ class HTMLCheckMatrix extends HTMLFormField implements HTMLNestedFilterable {
$attribs = $this->getAttributes( [ 'disabled', 'tabindex' ] );
// Build the column headers
$headerContents = Html::rawElement( 'td', [], '&#160;' );
$headerContents = Html::rawElement( 'td', [], "\u{00A0}" );
foreach ( $columns as $columnLabel => $columnTag ) {
$headerContents .= Html::rawElement( 'td', [], $columnLabel );
}

View file

@ -296,7 +296,7 @@ class HTMLFormFieldCloner extends HTMLFormField {
$html .= $field->$getFieldHtmlMethod( $v );
$labelValue = trim( $field->getLabel() );
if ( $labelValue != '&#160;' && $labelValue !== '' ) {
if ( $labelValue != "\u{00A0}" && $labelValue !== '' ) {
$hasLabel = true;
}
}

View file

@ -70,6 +70,6 @@ class HTMLFormFieldWithButton extends HTMLFormField {
* @return String
*/
public function getElement( $element ) {
return $element . '&#160;' . $this->getInputHTML( '' );
return $element . "\u{00A0}" . $this->getInputHTML( '' );
}
}

View file

@ -105,7 +105,7 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
$elementFunc = [ Html::class, $this->mOptionsLabelsNotFromMessage ? 'rawElement' : 'element' ];
$checkbox =
Xml::check( "{$this->mName}[]", $checked, $attribs ) .
'&#160;' .
"\u{00A0}" .
call_user_func( $elementFunc,
'label',
[ 'for' => $attribs['id'] ],

View file

@ -92,7 +92,7 @@ class HTMLRadioField extends HTMLFormField {
$classes[] = 'mw-ui-radio';
}
$radio = Xml::radio( $this->mName, $info, $info === $value, $attribs + [ 'id' => $id ] );
$radio .= '&#160;' . call_user_func( $elementFunc, 'label', [ 'for' => $id ], $label );
$radio .= "\u{00A0}" . call_user_func( $elementFunc, 'label', [ 'for' => $id ], $label );
$html .= ' ' . Html::rawElement(
'div',

View file

@ -27,7 +27,7 @@ class HTMLSizeFilterField extends HTMLIntField {
$value >= 0,
$attribs
);
$html .= '&#160;' . Xml::radioLabel(
$html .= "\u{00A0}" . Xml::radioLabel(
$this->msg( 'maximum-size' )->text(),
$this->mName . '-mode',
'max',
@ -35,8 +35,8 @@ class HTMLSizeFilterField extends HTMLIntField {
$value < 0,
$attribs
);
$html .= '&#160;' . parent::getInputHTML( $value ? abs( $value ) : '' );
$html .= '&#160;' . $this->msg( 'pagesize' )->parse();
$html .= "\u{00A0}" . parent::getInputHTML( $value ? abs( $value ) : '' );
$html .= "\u{00A0}" . $this->msg( 'pagesize' )->parse();
return $html;
}

View file

@ -758,7 +758,7 @@ class WebInstaller extends Installer {
*/
public function label( $msg, $forId, $contents, $helpData = "" ) {
if ( strval( $msg ) == '' ) {
$labelText = '&#160;';
$labelText = '\u{00A0}';
} else {
$labelText = wfMessage( $msg )->escaped();
}
@ -1047,7 +1047,7 @@ class WebInstaller extends Installer {
$items[$value] =
Xml::radio( $params['controlName'], $value, $checked, $itemAttribs ) .
'&#160;' .
'\u{00A0}' .
Xml::tags( 'label', [ 'for' => $id ], $this->parse(
isset( $params['itemLabels'] ) ?
wfMessage( $params['itemLabels'][$value] )->plain() :

View file

@ -412,7 +412,7 @@ class WebInstallerOptions extends WebInstallerPage {
return '<p>' .
Html::element( 'img', [ 'src' => $this->getVar( 'wgRightsIcon' ) ] ) .
'&#160;&#160;' .
'\u{00A0}\u{00A0}' .
htmlspecialchars( $this->getVar( 'wgRightsText' ) ) .
"</p>\n" .
"<p style=\"text-align: center;\">" .

View file

@ -135,7 +135,7 @@ class LogEventsList extends ContextSource {
// Tag filter
if ( $tagSelector ) {
$html .= Xml::tags( 'p', null, implode( '&#160;', $tagSelector ) );
$html .= Xml::tags( 'p', null, implode( "\u{00A0}", $tagSelector ) );
}
// Filter links

View file

@ -119,7 +119,7 @@ abstract class TablePager extends IndexPager {
// Make table header
foreach ( $fields as $field => $name ) {
if ( strval( $name ) == '' ) {
$s .= Html::rawElement( 'th', [], '&#160;' ) . "\n";
$s .= Html::rawElement( 'th', [], "\u{00A0}" ) . "\n";
} elseif ( $this->isFieldSortable( $field ) ) {
$query = [ 'sort' => $field, 'limit' => $this->mLimit ];
$linkType = null;
@ -192,7 +192,7 @@ abstract class TablePager extends IndexPager {
$formatted = strval( $this->formatValue( $field, $value ) );
if ( $formatted == '' ) {
$formatted = '&#160;';
$formatted = "\u{00A0}";
}
$s .= Html::rawElement( 'td', $this->getCellAttrs( $field, $value ), $formatted ) . "\n";

View file

@ -556,7 +556,7 @@ class SpecialContributions extends IncludableSpecialPage {
$filterSelection = Html::rawElement(
'div',
[],
implode( '&#160;', $tagFilter )
implode( "\u{00A0}", $tagFilter )
);
} else {
$filterSelection = Html::rawElement( 'div', [], '' );
@ -609,7 +609,7 @@ class SpecialContributions extends IncludableSpecialPage {
$this->msg( 'namespace' )->text(),
'namespace',
''
) . '&#160;' .
) . "\u{00A0}" .
Html::namespaceSelector(
[ 'selected' => $this->opts['namespace'], 'all' => '' ],
[
@ -617,7 +617,7 @@ class SpecialContributions extends IncludableSpecialPage {
'id' => 'namespace',
'class' => 'namespaceselector',
]
) . '&#160;' .
) . "\u{00A0}" .
Html::rawElement(
'span',
[ 'class' => 'mw-input-with-label' ],
@ -630,7 +630,7 @@ class SpecialContributions extends IncludableSpecialPage {
'title' => $this->msg( 'tooltip-invert' )->text(),
'class' => 'mw-input'
]
) . '&#160;'
) . "\u{00A0}"
) .
Html::rawElement( 'span', [ 'class' => 'mw-input-with-label' ],
Xml::checkLabel(
@ -642,7 +642,7 @@ class SpecialContributions extends IncludableSpecialPage {
'title' => $this->msg( 'tooltip-namespace_association' )->text(),
'class' => 'mw-input'
]
) . '&#160;'
) . "\u{00A0}"
)
);

View file

@ -332,7 +332,7 @@ class SpecialEmailUser extends UnlistedSpecialPage {
Html::label(
$this->msg( 'emailusername' )->text(),
'emailusertarget'
) . '&#160;' .
) . "\u{00A0}" .
Html::input(
'target',
$name,

View file

@ -224,11 +224,11 @@ class SpecialMergeHistory extends SpecialPage {
'</td>
<td class="mw-input">' .
Xml::input( 'wpComment', 50, $this->mComment, [ 'id' => 'wpComment' ] ) .
'</td>
"</td>
</tr>
<tr>
<td>&#160;</td>
<td class="mw-submit">' .
<td>\u{00A0}</td>
<td class=\"mw-submit\">" .
Xml::submitButton(
$this->msg( 'mergehistory-submit' )->text(),
[ 'name' => 'merge', 'id' => 'mw-merge-submit' ]

View file

@ -526,7 +526,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
$this->msg( 'watchlist-unwatch' )->text(), [
'class' => 'mw-unwatch-link',
'title' => $this->msg( 'tooltip-ca-unwatch' )->text()
], [ 'action' => 'unwatch' ] ) . '&#160;';
], [ 'action' => 'unwatch' ] ) . "\u{00A0}";
}
} );
}

View file

@ -523,7 +523,7 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
]
);
$f .= '&#160;' .
$f .= "\u{00A0}" .
Xml::checkLabel(
$this->msg( 'invert' )->text(),
'invert',

View file

@ -357,7 +357,7 @@ class AllMessagesTablePager extends TablePager {
$formatted = strval( $this->formatValue( 'am_actual', $row->am_actual ) );
if ( $formatted === '' ) {
$formatted = '&#160;';
$formatted = "\u{00A0}";
}
$s .= Xml::tags( 'td', $this->getCellAttrs( 'am_actual', $row->am_actual ), $formatted )

View file

@ -331,7 +331,7 @@ class HtmlTest extends MediaWikiTestCase {
);
$this->assertEquals(
'<label for="mw-test-namespace">Select a namespace:</label>&#160;' .
'<label for="mw-test-namespace">Select a namespace:</label>' . "\u{00A0}" .
'<select id="mw-test-namespace" name="wpNamespace">' . "\n" .
'<option value="all">all</option>' . "\n" .
'<option value="0">(Main)</option>' . "\n" .
@ -359,7 +359,7 @@ class HtmlTest extends MediaWikiTestCase {
);
$this->assertEquals(
'<label for="namespace">Select a namespace:</label>&#160;' .
'<label for="namespace">Select a namespace:</label>' . "\u{00A0}" .
'<select id="namespace" name="namespace">' . "\n" .
'<option value="0">(Main)</option>' . "\n" .
'<option value="1">Talk</option>' . "\n" .

View file

@ -66,7 +66,7 @@ class ApiOptionsTest extends MediaWikiLangTestCase {
$preferences[$k] = [
'type' => 'text',
'section' => 'test',
'label' => '&#160;',
'label' => "\u{00A0}",
];
}
@ -81,7 +81,7 @@ class ApiOptionsTest extends MediaWikiLangTestCase {
],
],
'section' => 'test',
'label' => '&#160;',
'label' => "\u{00A0}",
'prefix' => 'testmultiselect-',
'default' => [],
];