Fix positioning of input/display settings for new language selector

Unrelated behavior change: ULS language selection dialog is hidden while
display or input settings is open.

Also simplified dead code in addDisplaySettings.

Bug: T276248
Change-Id: Ia91a2b83e7ad4072016649230e2376b0793cbbff
This commit is contained in:
Niklas Laxström
2021-03-22 10:23:51 +01:00
committed by Nikerabbit
parent ffc9c20fdb
commit 8c835588f2
4 changed files with 46 additions and 76 deletions

View File

@@ -302,8 +302,7 @@
$languages.append( $moreLanguagesButton ); $languages.append( $moreLanguagesButton );
// Show the long language list to select a language for display settings // Show the long language list to select a language for display settings
$moreLanguagesButton.uls( { $moreLanguagesButton.uls( {
left: displaySettings.$parent.left, onPosition: this.$parent.position.bind( this.$parent ),
top: displaySettings.$parent.top,
onReady: function () { onReady: function () {
var $wrap, var $wrap,
uls = this, uls = this,
@@ -328,8 +327,6 @@
uls.$menu.toggleClass( 'selector-right', displaySettings.$parent.$window.hasClass( 'selector-right' ) ); uls.$menu.toggleClass( 'selector-right', displaySettings.$parent.$window.hasClass( 'selector-right' ) );
}, },
onVisible: function () { onVisible: function () {
var $parent;
this.$menu.find( '.uls-languagefilter' ) this.$menu.find( '.uls-languagefilter' )
.prop( 'placeholder', $.i18n( 'ext-uls-display-settings-ui-language' ) ); .prop( 'placeholder', $.i18n( 'ext-uls-display-settings-ui-language' ) );
@@ -340,15 +337,6 @@
return; return;
} }
$parent = $( '#language-settings-dialog' );
// Re-position the element according to the window that called it
if ( parseInt( $parent.css( 'left' ), 10 ) ) {
this.$menu.css( 'left', $parent.css( 'left' ) );
}
if ( parseInt( $parent.css( 'top' ), 10 ) ) {
this.$menu.css( 'top', $parent.css( 'top' ) );
}
// If the ULS is shown in the sidebar, // If the ULS is shown in the sidebar,
// add a caret pointing to the icon // add a caret pointing to the icon
// eslint-disable-next-line no-jquery/no-class-state // eslint-disable-next-line no-jquery/no-class-state

View File

@@ -74,27 +74,14 @@
var $displaySettings = displaySettings(); var $displaySettings = displaySettings();
uls.$menu.find( '#uls-settings-block' ).append( $displaySettings ); uls.$menu.find( '#uls-settings-block' ).append( $displaySettings );
// Initialize the trigger // Initialize the trigger
$displaySettings.one( 'click', function () { $displaySettings.one( 'click', function () {
var displaySettingsOptions = { $displaySettings.languagesettings( {
defaultModule: 'display' defaultModule: 'display',
}, onClose: uls.show.bind( uls ),
ulsPosition = mw.config.get( 'wgULSPosition' ), onPosition: uls.position.bind( uls ),
anonMode = ( mw.user.isAnon() && onVisible: uls.hide.bind( uls )
!mw.config.get( 'wgULSAnonCanChangeLanguage' ) ); } ).trigger( 'click' );
// If the ULS trigger is shown in the top personal menu,
// closing the display settings must show the main ULS
// languages list, unless we are in anon mode and thus
// cannot show the language list
if ( ulsPosition === 'personal' && !anonMode ) {
displaySettingsOptions.onClose = function () {
uls.show();
};
}
$.extend( displaySettingsOptions, uls.position() );
$displaySettings.languagesettings( displaySettingsOptions ).trigger( 'click' );
} ); } );
} }
@@ -107,20 +94,14 @@
var $inputSettings = inputSettings(); var $inputSettings = inputSettings();
uls.$menu.find( '#uls-settings-block' ).append( $inputSettings ); uls.$menu.find( '#uls-settings-block' ).append( $inputSettings );
// Initialize the trigger // Initialize the trigger
$inputSettings.one( 'click', function () { $inputSettings.one( 'click', function () {
var position = uls.position();
$inputSettings.languagesettings( { $inputSettings.languagesettings( {
defaultModule: 'input', defaultModule: 'input',
onClose: function () { onClose: uls.show.bind( uls ),
uls.show(); onPosition: uls.position.bind( uls ),
}, onVisible: uls.hide.bind( uls )
top: position.top,
left: position.left
} ).trigger( 'click' ); } ).trigger( 'click' );
} ); } );
} }
@@ -305,33 +286,34 @@
// Initialize the Language settings window // Initialize the Language settings window
languageSettingsOptions = { languageSettingsOptions = {
defaultModule: 'display', defaultModule: 'display',
onVisible: function () { onPosition: function () {
var caretRadius, var caretRadius, top, left,
ulsTriggerHeight = this.$element.height(), ulsTriggerHeight = this.$element.height(),
ulsTriggerWidth = this.$element[ 0 ].offsetWidth, ulsTriggerWidth = this.$element[ 0 ].offsetWidth,
ulsTriggerOffset = this.$element.offset(); ulsTriggerOffset = this.$element.offset();
this.$window.addClass( 'callout' );
// Same as border width in mixins.less, or near enough // Same as border width in mixins.less, or near enough
caretRadius = 12; caretRadius = 12;
if ( ulsTriggerOffset.left > $( window ).width() / 2 ) { if ( ulsTriggerOffset.left > $( window ).width() / 2 ) {
this.left = ulsTriggerOffset.left - this.$window.width() - caretRadius; left = ulsTriggerOffset.left - this.$window.width() - caretRadius;
this.$window.removeClass( 'selector-left' ).addClass( 'selector-right' ); this.$window.removeClass( 'selector-left' ).addClass( 'selector-right' );
} else { } else {
this.left = ulsTriggerOffset.left + ulsTriggerWidth + caretRadius; left = ulsTriggerOffset.left + ulsTriggerWidth + caretRadius;
this.$window.removeClass( 'selector-right' ).addClass( 'selector-left' ); this.$window.removeClass( 'selector-right' ).addClass( 'selector-left' );
} }
// The top of the dialog is aligned in relation to // The top of the dialog is aligned in relation to
// the middle of the trigger, so that middle of the // the middle of the trigger, so that middle of the
// caret aligns with it. 16 is trigger icon height in pixels // caret aligns with it. 16 is trigger icon height in pixels
this.top = ulsTriggerOffset.top + top = ulsTriggerOffset.top +
( ulsTriggerHeight / 2 ) - ( ulsTriggerHeight / 2 ) -
( caretRadius + 16 ); ( caretRadius + 16 );
this.position(); return { top: top, left: left };
},
onVisible: function () {
this.$window.addClass( 'callout' );
} }
}; };

View File

@@ -174,12 +174,16 @@
}, },
position: function () { position: function () {
if ( this.options.onPosition ) {
return this.options.onPosition.call( this );
}
this.top = this.top || this.$element.offset().top + this.$element.outerHeight(); this.top = this.top || this.$element.offset().top + this.$element.outerHeight();
this.left = this.left || '25%'; this.left = this.left || '25%';
this.$window.css( { return {
top: this.top, top: this.top,
left: this.left left: this.left
} ); };
}, },
i18n: function () { i18n: function () {
@@ -187,7 +191,7 @@
}, },
show: function () { show: function () {
this.position(); this.$window.css( this.position() );
if ( !this.initialized ) { if ( !this.initialized ) {
this.render(); this.render();
@@ -311,9 +315,10 @@
template: windowTemplate, template: windowTemplate,
defaultModule: false, // Name of the default module defaultModule: false, // Name of the default module
onClose: null, // An onClose event handler. onClose: null, // An onClose event handler.
top: null, // Top position of this window top: null, // DEPRECATED: Top position of this window
left: null, // Left position of this window left: null, // DEPRECATED: Left position of this window
onVisible: null // A callback that runs after the ULS panel becomes visible onVisible: null, // A callback that runs after the ULS panel becomes visible
onPosition: null // A callback that allows positioning the dialog
}; };
$.fn.languagesettings.Constructor = LanguageSettings; $.fn.languagesettings.Constructor = LanguageSettings;

View File

@@ -62,14 +62,11 @@ function launchULS( $trigger, languagesObject, forCLS ) {
} }
location.href = languagesObject[ language ].href; location.href = languagesObject[ language ].href;
}, },
onVisible: function () { onPosition: function () {
// Override the default positioning. See https://phabricator.wikimedia.org/T276248 // Override the default positioning. See https://phabricator.wikimedia.org/T276248
// Default positioning of jquery.uls is middle of the screen under the trigger. // Default positioning of jquery.uls is middle of the screen under the trigger.
// This code aligns it under the trigger and to the trigger edge depending on which // This code aligns it under the trigger and to the trigger edge depending on which
// side of the page the trigger is - should work automatically for both LTR and RTL. // side of the page the trigger is - should work automatically for both LTR and RTL.
//
// FIXME: make position() overrideable in ULS to avoid doing this after the dialog
// has been made visible
var offset, height, width; var offset, height, width;
// These are for the trigger. // These are for the trigger.
offset = $trigger.offset(); offset = $trigger.offset();
@@ -78,22 +75,21 @@ function launchULS( $trigger, languagesObject, forCLS ) {
if ( offset.left + ( width / 2 ) > $( window ).width() / 2 ) { if ( offset.left + ( width / 2 ) > $( window ).width() / 2 ) {
// Midpoint of the trigger is on the right side of the viewport. // Midpoint of the trigger is on the right side of the viewport.
this.$menu.css( { return {
left: 'auto',
// Right edge of the dialog aligns with the right edge of the trigger. // Right edge of the dialog aligns with the right edge of the trigger.
right: $( window ).width() - ( offset.left + width ), right: $( window ).width() - ( offset.left + width ),
top: offset.top + height top: offset.top + height
} ); };
} else { } else {
// Midpoint of the trigger is on the left side of the viewport. // Midpoint of the trigger is on the left side of the viewport.
this.$menu.css( { return {
// Left edge of the dialog aligns with the left edge of the trigger. // Left edge of the dialog aligns with the left edge of the trigger.
left: offset.left, left: offset.left,
right: 'auto',
top: offset.top + height top: offset.top + height
} ); };
} }
},
onVisible: function () {
$trigger.addClass( 'selector-open' ); $trigger.addClass( 'selector-open' );
}, },
languageDecorator: function ( $languageLink, language ) { languageDecorator: function ( $languageLink, language ) {
@@ -138,9 +134,9 @@ function launchULS( $trigger, languagesObject, forCLS ) {
// This class enables the caret // This class enables the caret
this.$menu.addClass( 'interlanguage-uls-menu' ); this.$menu.addClass( 'interlanguage-uls-menu' );
}; };
ulsConfig.onVisible = function () { ulsConfig.onPosition = function () {
// Compact language links specific positioning with a caret // Compact language links specific positioning with a caret
var offset, height, width, triangleWidth; var top, left, offset, height, width, triangleWidth;
// The panel is positioned carefully so that our pointy triangle, // The panel is positioned carefully so that our pointy triangle,
// which is implemented as a square box rotated 45 degrees with // which is implemented as a square box rotated 45 degrees with
// rotation origin in the middle. See the corresponding style file. // rotation origin in the middle. See the corresponding style file.
@@ -156,20 +152,19 @@ function launchULS( $trigger, languagesObject, forCLS ) {
// selector-{left,right} control which side the caret appears. // selector-{left,right} control which side the caret appears.
// It needs to match the positioning of the dialog. // It needs to match the positioning of the dialog.
if ( offset.left > $( window ).width() / 2 ) { if ( offset.left > $( window ).width() / 2 ) {
this.left = offset.left - this.$menu.outerWidth() - triangleWidth; left = offset.left - this.$menu.outerWidth() - triangleWidth;
this.$menu.removeClass( 'selector-left' ).addClass( 'selector-right' ); this.$menu.removeClass( 'selector-left' ).addClass( 'selector-right' );
} else { } else {
this.left = offset.left + width + triangleWidth; left = offset.left + width + triangleWidth;
this.$menu.removeClass( 'selector-right' ).addClass( 'selector-left' ); this.$menu.removeClass( 'selector-right' ).addClass( 'selector-left' );
} }
// Offset from the middle of the trigger // Offset from the middle of the trigger
this.top = offset.top + ( height / 2 ) - 27; top = offset.top + ( height / 2 ) - 27;
this.$menu.css( { return {
left: this.left, left: left,
top: this.top top: top
} ); };
$trigger.addClass( 'selector-open' );
}; };
} }