From 86c636fd0acb9354dbedca9c9a152014971a83f3 Mon Sep 17 00:00:00 2001 From: Isarra Date: Sat, 20 May 2017 16:41:33 +0000 Subject: [PATCH] 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 --- resources/css/ext.uls.compactlinks.less | 33 ++----------- resources/css/ext.uls.less | 61 ++----------------------- resources/css/ext.uls.mixins.less | 42 +++++++++++++++++ resources/js/ext.uls.compactlinks.js | 15 +++--- resources/js/ext.uls.displaysettings.js | 9 ++-- resources/js/ext.uls.inputsettings.js | 9 ++-- resources/js/ext.uls.interface.js | 24 +++------- 7 files changed, 73 insertions(+), 120 deletions(-) create mode 100644 resources/css/ext.uls.mixins.less diff --git a/resources/css/ext.uls.compactlinks.less b/resources/css/ext.uls.compactlinks.less index 8223c9fa..70ded668 100644 --- a/resources/css/ext.uls.compactlinks.less +++ b/resources/css/ext.uls.compactlinks.less @@ -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(); } diff --git a/resources/css/ext.uls.less b/resources/css/ext.uls.less index d09263ab..940d713f 100644 --- a/resources/css/ext.uls.less +++ b/resources/css/ext.uls.less @@ -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 { diff --git a/resources/css/ext.uls.mixins.less b/resources/css/ext.uls.mixins.less new file mode 100644 index 00000000..c08c5569 --- /dev/null +++ b/resources/css/ext.uls.mixins.less @@ -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; + } + } +} diff --git a/resources/js/ext.uls.compactlinks.js b/resources/js/ext.uls.compactlinks.js index f292194a..13ad20d5 100644 --- a/resources/js/ext.uls.compactlinks.js +++ b/resources/js/ext.uls.compactlinks.js @@ -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, diff --git a/resources/js/ext.uls.displaysettings.js b/resources/js/ext.uls.displaysettings.js index 95fc770b..69e6f852 100644 --- a/resources/js/ext.uls.displaysettings.js +++ b/resources/js/ext.uls.displaysettings.js @@ -312,10 +312,11 @@ uls.$menu.find( '.uls-search-wrapper' ).wrap( $wrap ); uls.$menu.find( '.uls-search-wrapper-wrapper' ).prepend( $back ); - uls.$menu.prepend( - $( '' ).addClass( 'caret-before' ), - $( '' ).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; diff --git a/resources/js/ext.uls.inputsettings.js b/resources/js/ext.uls.inputsettings.js index 2f920de6..bb1f6537 100644 --- a/resources/js/ext.uls.inputsettings.js +++ b/resources/js/ext.uls.inputsettings.js @@ -350,10 +350,11 @@ uls.$menu.find( '.uls-search-wrapper' ).wrap( $wrap ); uls.$menu.find( '.uls-search-wrapper-wrapper' ).prepend( $back ); - uls.$menu.prepend( - $( '' ).addClass( 'caret-before' ), - $( '' ).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; diff --git a/resources/js/ext.uls.interface.js b/resources/js/ext.uls.interface.js index 2ceba429..77f92de5 100644 --- a/resources/js/ext.uls.interface.js +++ b/resources/js/ext.uls.interface.js @@ -346,41 +346,31 @@ languageSettingsOptions = { defaultModule: 'display', onVisible: function () { - var caretRadius, caretPosition, - $caretBefore = $( '' ).addClass( 'caret-before' ), - $caretAfter = $( '' ).addClass( 'caret-after' ), - $caretWrapper = $( '' ), + 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(); }