JsonContent: align object key cells at the top

The default middle vertical align can make it hard to find the object
key for long tables (where the value is itself a long object or array).
Move it to the top, and add position: sticky to make it stay on screen
as the top of the table is scrolled out of view. (position: sticky is
not supported in Internet Explorer, but in that case this should
gracefully degrade to keeping the object key at the top, which is no
worse than the previous behavior, where the object key might be out of
view in all browsers.)

The extra <span> is necessary because putting position: sticky on the
table cell itself doesn’t work.

Change-Id: Ib38710e5cc2b75971a26eabf7f144378790d3661
This commit is contained in:
Lucas Werkmeister 2020-01-10 19:44:36 +01:00
parent 215d5f2aff
commit 6e074668bc
3 changed files with 20 additions and 10 deletions

View file

@ -163,7 +163,8 @@ class JsonContent extends TextContent {
* @return string HTML.
*/
protected function objectRow( $key, $val ) {
$th = Html::element( 'th', [], $key );
$thContent = Html::element( 'span', [], $key );
$th = Html::rawElement( 'th', [], $thContent );
$td = $this->valueCell( $val );
return Html::rawElement( 'tr', [], $th . $td );
}

View file

@ -42,4 +42,10 @@
.mw-json th {
background-color: #fff;
font-weight: normal;
vertical-align: top;
}
.mw-json th span {
position: sticky;
top: 0.5em;
}

View file

@ -114,27 +114,30 @@ class JsonContentTest extends MediaWikiLangTestCase {
],
[
(object)[ 'foo' ],
'<table class="mw-json"><tbody><tr><th>0</th><td class="mw-json-value">"foo"</td></tr>' .
'</tbody></table>'
'<table class="mw-json"><tbody><tr><th><span>0</span></th>' .
'<td class="mw-json-value">"foo"</td></tr></tbody></table>'
],
[
(object)[ 'foo', 'bar' ],
'<table class="mw-json"><tbody><tr><th>0</th><td class="mw-json-value">"foo"</td></tr>' .
'<tr><th>1</th><td class="mw-json-value">"bar"</td></tr></tbody></table>'
'<table class="mw-json"><tbody><tr><th><span>0</span></th>' .
'<td class="mw-json-value">"foo"</td></tr><tr><th><span>1</span></th>' .
'<td class="mw-json-value">"bar"</td></tr></tbody></table>'
],
[
(object)[ 'baz' => 'foo', 'bar' ],
'<table class="mw-json"><tbody><tr><th>baz</th><td class="mw-json-value">"foo"</td></tr>' .
'<tr><th>0</th><td class="mw-json-value">"bar"</td></tr></tbody></table>'
'<table class="mw-json"><tbody><tr><th><span>baz</span></th>' .
'<td class="mw-json-value">"foo"</td></tr><tr><th><span>0</span></th>' .
'<td class="mw-json-value">"bar"</td></tr></tbody></table>'
],
[
(object)[ 'baz' => 1000, 'bar' ],
'<table class="mw-json"><tbody><tr><th>baz</th><td class="mw-json-value">1000</td></tr>' .
'<tr><th>0</th><td class="mw-json-value">"bar"</td></tr></tbody></table>'
'<table class="mw-json"><tbody><tr><th><span>baz</span></th>' .
'<td class="mw-json-value">1000</td></tr><tr><th><span>0</span></th>' .
'<td class="mw-json-value">"bar"</td></tr></tbody></table>'
],
[
(object)[ '<script>alert("evil!")</script>' ],
'<table class="mw-json"><tbody><tr><th>0</th><td class="mw-json-value">"' .
'<table class="mw-json"><tbody><tr><th><span>0</span></th><td class="mw-json-value">"' .
'&lt;script>alert("evil!")&lt;/script>"' .
'</td></tr></tbody></table>',
],