diff --git a/resources/main.js b/resources/main.js index 222757b..3c3abc5 100644 --- a/resources/main.js +++ b/resources/main.js @@ -42,29 +42,56 @@ $( function () { closeOpen(); } } ); +} ); + +mw.hook( 'wikipage.content' ).add( function ( $content ) { + // Gotta wrap them for this to work; maybe later the parser etc will do this for us?! + $content.find( 'div > table:not( table table )' ).wrap( '
' ); + $content.find( '.content-table-wrapper' ).prepend( '
' ); /** - * Experimental overflowing table scrolling + * Set up borders for experimental overflowing table scrolling + * + * I have no idea what I'm doing. + * + * @param {jQuery} $table */ + function setScrollClass( $table ) { + var $tableWrapper = $table.parent(), + $wrapper = $tableWrapper.parent(), + // wtf browser rtl implementations + scroll = Math.abs( $tableWrapper.scrollLeft() ); - // Gotta wrap them for this to work; maybe later the parser etc will do this for us?! - $( 'div > table' ).wrap( '
' ); - $( '.content-table-wrapper' ).prepend( '
' ); + // 1 instead of 0 because of weird rtl rounding errors or something (?!) + if ( scroll > 1 ) { + $wrapper.addClass( 'scroll-left' ); + } else { + $wrapper.removeClass( 'scroll-left' ); + } + if ( $table.outerWidth() - $tableWrapper.innerWidth() - scroll > 1 ) { + $wrapper.addClass( 'scroll-right' ); + } else { + $wrapper.removeClass( 'scroll-right' ); + } + } + + $content.find( '.content-table' ).on( 'scroll', function () { + setScrollClass( $( this ).children( 'table' ).first() ); + } ); + + /** + * Mark overflowed tables for scrolling + */ function unOverflowTables() { - $( 'div > table' ).each( function () { + $content.find( '.content-table > table' ).each( function () { var $table = $( this ), $wrapper = $table.parent().parent(); if ( $table.outerWidth() > $wrapper.outerWidth() ) { $wrapper.addClass( 'overflowed' ); - - // Frame styled tables... - // eslint-disable-next-line no-jquery/no-class-state - if ( $table.hasClass( 'wikitable' ) || $table.hasClass( 'mw-datatable' ) ) { - $wrapper.addClass( 'framed' ); - } + setScrollClass( $table ); } else { - $wrapper.removeClass( [ 'overflowed', 'framed' ] ); + $wrapper.removeClass( 'overflowed scroll-left scroll-right fixed-scrollbar-container' ); } } ); } diff --git a/resources/main.js.less b/resources/main.js.less index 4e497ed..27eed1f 100644 --- a/resources/main.js.less +++ b/resources/main.js.less @@ -4,40 +4,69 @@ .overflowed { margin: 1em 0; position: relative; - padding-right: 25px; + overflow: hidden; - &.framed { - border: solid 1px @base70; - - .content-table-toggle { - border-left: solid 1px @base70; - } - - .content-table { - border-right: solid 1px @base70; - margin: -1px -2px 0 0; - } + // Keep this visible if possible (T269912) + caption { + text-align: left; } - .content-table-toggle { - width: 25px; + // Shadow-border containers + .content-table-left, + .content-table-right { height: 100%; - background: @base80 url( images/arrow-ltr.svg ) no-repeat; - background-position: 100% 50%; position: absolute; top: 0; + z-index: 1; + } + + // Noflips because scrollbar direction depends on the content direction + .content-table-right { + /* @noflip */ right: 0; + + .mw-content-rtl & { + /* @noflip */ + left: 0; + /* @noflip */ + right: unset; + } + + .scroll-right& { + box-shadow: 0 0 4px 1px rgba( 0, 0, 0, 0.25 ); + border-left: solid 1px @base70; + } + } + + .content-table-left { + /* @noflip */ + left: 0; + + .mw-content-rtl & { + /* @noflip */ + right: 0; + /* @noflip */ + left: unset; + } + + .scroll-left& { + box-shadow: 0 0 4px 1px rgba( 0, 0, 0, 0.25 ); + border-left: solid 1px @base70; + } } .content-table { overflow: hidden; overflow-x: scroll; - .mw_metadata, - .mw-datatable, - .wikitable { - margin: 0 -1px; - border-bottom-width: 0; + > table { + margin: 0; + + &.mw_metadata, + &.mw-datatable, + &.wikitable { + border-bottom-width: 0; + } } } }