Fix directionality of ULS CLL and languageselect callouts

when appearing on right side of screen

Languageselect was mostly fixed in 354378, but I forgot the
settings ones, so the triangle just disappears when
switching dialogs currently. This follows up on that and
properly fixes it.

Sidebar callouts now appear toward content regardless of
where they're appearing from, or the language
directionality. Triangles are now consistently alligned to
the top of the callout (same position in languageselect and
compact language links) to avoid issues with it appearing
over a scrollbar.

Sideways callout triangles (carets) are consolidated into a
single rendering approach and mixin across compact language
links and toolbox language selector.

Bug: T161586
Change-Id: I7717e26525ac527ede486796f49083ed40ee7d4f
This commit is contained in:
Isarra
2017-05-20 16:41:33 +00:00
committed by Derk-Jan Hartman
parent fa0ad11222
commit 86c636fd0a
7 changed files with 73 additions and 120 deletions

View File

@@ -1,4 +1,5 @@
@import 'mediawiki.mixins';
@import 'ext.uls.mixins.less';
/* stylelint-disable selector-no-id */
@@ -30,34 +31,6 @@
background-color: #ccc;
}
.interlanguage-uls-menu:before {
background: none repeat scroll 0 0 #fcfcfc;
border-left: 1px solid rgba( 0, 0, 0, 0.2 );
border-top: 1px solid rgba( 0, 0, 0, 0.2 );
box-shadow: -2px -2px 2px rgba( 0, 0, 0, 0.1 );
content: '';
height: 16px;
width: 16px;
left: -9px;
position: absolute;
/* The dialog middle is positioned 250px away from the center of the trigger. Substract 8 for
* half of the box height to center middle of the box rather than the top. The remaining 2 are
* either for top-margin of the menu and border of this box, or because we use do not account
* for the margin of the trigger when we use $.fn.outerWidth without true as a parameter.
*/
top: 240px;
transform: rotate( -45deg );
-webkit-transform: rotate( -45deg );
-moz-transform: rotate( -45deg );
-o-transform: rotate( -45deg );
-ms-transform: rotate( -45deg );
background-clip: padding-box;
}
body.rtl .interlanguage-uls-menu:before {
transform: rotate( 45deg );
-webkit-transform: rotate( 45deg );
-moz-transform: rotate( 45deg );
-o-transform: rotate( 45deg );
-ms-transform: rotate( 45deg );
.interlanguage-uls-menu {
.caret();
}

View File

@@ -1,3 +1,5 @@
@import 'ext.uls.mixins.less';
/* Overrides to follow MediaWiki style */
.uls-menu {
border-radius: 4px;
@@ -16,63 +18,8 @@
border-bottom-left-radius: 4px;
}
/* Caret */
.uls-menu.callout .caret-before,
.uls-menu.callout .caret-after {
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
display: inline-block;
/* 17px aligns nicely with the size of the search row in language selection */
top: 17px;
position: absolute;
}
.uls-menu.callout .caret-after {
display: inline-block;
}
// How do you do switch for flipping in less? These are very redundant.
.uls-menu.callout .caret-right {
.caret-before,
.caret-after {
/* @noflip */
border-left: 10px solid #c9c9c9;
/* @noflip */
right: -11px;
}
.caret-after {
/* @noflip */
border-left: 10px solid #fcfcfc;
/* @noflip */
right: -10px;
}
}
.uls-menu.callout--languageselection .caret-right .caret-after {
/* @noflip */
border-left: 10px solid #fff;
}
.uls-menu.callout .caret-left {
.caret-before,
.caret-after {
/* @noflip */
border-right: 10px solid #c9c9c9;
/* @noflip */
left: -11px;
}
.caret-after {
/* @noflip */
border-right: 10px solid #fcfcfc;
/* @noflip */
left: -10px;
}
}
.uls-menu.callout--languageselection .caret-left .caret-after {
/* @noflip */
border-right: 10px solid #fff;
.uls-menu.callout {
.caret();
}
.uls-ui-languages button {

View File

@@ -0,0 +1,42 @@
// Generate a caret by embedding in the callout.
// Expects callout to have either selector-right or selecter-left class on it to determine directionality.
.caret() {
&:before,
&:after {
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
display: inline-block;
/* 17px aligns nicely with the size of the search row in language selection */
top: 17px;
position: absolute;
content: '';
}
&.selector-right {
&:before {
/* @noflip */
border-left: 10px solid #c9c9c9;
/* @noflip */
right: -11px;
}
&:after {
/* @noflip */
border-left: 10px solid #fcfcfc;
/* @noflip */
right: -10px;
}
}
&.selector-left {
&:before {
/* @noflip */
border-right: 10px solid #c9c9c9;
/* @noflip */
left: -11px;
}
&:after {
/* @noflip */
border-right: 10px solid #fcfcfc;
/* @noflip */
left: -10px;
}
}
}

View File

@@ -117,7 +117,6 @@
CompactInterlanguageList.prototype.createSelector = function ( $trigger ) {
var languages,
self = this,
dir = $( 'html' ).prop( 'dir' ),
ulsLanguageList = {};
languages = $.map( this.interlanguageList, function ( language, languageCode ) {
@@ -152,18 +151,18 @@
width = $trigger.outerWidth();
height = $trigger.outerHeight();
// Triangle width is: Math.sqrt( 2 * Math.pow( 16, 2 ) ) / 2 =~ 11.3;
// Box width = 16 + 1 for border.
// The resulting value is rounded up 14 to have a small space between.
triangleWidth = 14;
// Triangle width is: who knows now, but this still looks fine.
triangleWidth = 12;
if ( dir === 'rtl' ) {
if ( offset.left > $( window ).width() / 2 ) {
this.left = offset.left - this.$menu.outerWidth() - triangleWidth;
this.$menu.removeClass( 'selector-left' ).addClass( 'selector-right' );
} else {
this.left = offset.left + width + triangleWidth;
this.$menu.removeClass( 'selector-right' ).addClass( 'selector-left' );
}
// Offset -250px from the middle of the trigger
this.top = offset.top + ( height / 2 ) - 250;
// Offset from the middle of the trigger
this.top = offset.top + ( height / 2 ) - 27;
this.$menu.css( {
left: this.left,

View File

@@ -312,10 +312,11 @@
uls.$menu.find( '.uls-search-wrapper' ).wrap( $wrap );
uls.$menu.find( '.uls-search-wrapper-wrapper' ).prepend( $back );
uls.$menu.prepend(
$( '<span>' ).addClass( 'caret-before' ),
$( '<span>' ).addClass( 'caret-after' )
);
if ( $( '.uls-settings-trigger' ).offset().left > $( window ).width() / 2 ) {
uls.$menu.removeClass( 'selector-left' ).addClass( 'selector-right' );
} else {
uls.$menu.removeClass( 'selector-right' ).addClass( 'selector-left' );
}
},
onVisible: function () {
var $parent;

View File

@@ -350,10 +350,11 @@
uls.$menu.find( '.uls-search-wrapper' ).wrap( $wrap );
uls.$menu.find( '.uls-search-wrapper-wrapper' ).prepend( $back );
uls.$menu.prepend(
$( '<span>' ).addClass( 'caret-before' ),
$( '<span>' ).addClass( 'caret-after' )
);
if ( $( '.uls-settings-trigger' ).offset().left > $( window ).width() / 2 ) {
uls.$menu.removeClass( 'selector-left' ).addClass( 'selector-right' );
} else {
uls.$menu.removeClass( 'selector-right' ).addClass( 'selector-left' );
}
},
onVisible: function () {
var $parent;

View File

@@ -346,41 +346,31 @@
languageSettingsOptions = {
defaultModule: 'display',
onVisible: function () {
var caretRadius, caretPosition,
$caretBefore = $( '<span>' ).addClass( 'caret-before' ),
$caretAfter = $( '<span>' ).addClass( 'caret-after' ),
$caretWrapper = $( '<span>' ),
var caretRadius,
ulsTriggerHeight = this.$element.height(),
ulsTriggerWidth = this.$element.width(),
ulsTriggerOffset = this.$element.offset();
// Add the callout caret triangle
// pointing to the trigger icon
this.$window.addClass( 'callout' );
this.$window.prepend( $caretWrapper.prepend( $caretBefore, $caretAfter ) );
// Calculate the positioning of the panel
// according to the position of the trigger icon
caretRadius = parseInt( $caretBefore.css( 'border-top-width' ), 10 );
// Same as border width in mixins.less, or near enough
caretRadius = 12;
if ( ulsTriggerOffset.left > $( window ).width() / 2 ) {
this.left = ulsTriggerOffset.left - this.$window.width() - caretRadius;
$caretWrapper.addClass( 'caret-right' );
caretPosition = $caretBefore.position();
this.$window.removeClass( 'selector-left' ).addClass( 'selector-right' );
} else {
this.left = ulsTriggerOffset.left + ulsTriggerWidth + caretRadius;
$caretWrapper.addClass( 'caret-left' );
caretPosition = $caretAfter.position();
this.$window.removeClass( 'selector-right' ).addClass( 'selector-left' );
}
// The top of the dialog is aligned in relation to
// the middle of the trigger, so that middle of the
// caret aligns with it. 2 is for border and margin.
// caret aligns with it. 17 is a random number.
this.top = ulsTriggerOffset.top +
( ulsTriggerHeight / 2 ) -
( caretRadius + caretPosition.top + 2 );
( caretRadius + 17 );
this.position();
}