diff options
author | Brian Evans <grknight@gentoo.org> | 2022-11-08 14:22:52 -0500 |
---|---|---|
committer | Brian Evans <grknight@gentoo.org> | 2022-11-08 14:22:52 -0500 |
commit | 0dad0fd9a1353d251e1a7beb28d1656d6521f406 (patch) | |
tree | 9f7536819d37ccc0d9d4c564ce3eeff0c3c0fe20 /UniversalLanguageSelector/resources/js/ext.uls.interface.js | |
parent | Update MLEB to 2022.10 (diff) | |
download | extensions-0dad0fd9a1353d251e1a7beb28d1656d6521f406.tar.gz extensions-0dad0fd9a1353d251e1a7beb28d1656d6521f406.tar.bz2 extensions-0dad0fd9a1353d251e1a7beb28d1656d6521f406.zip |
Move extensions out of MLEB
Signed-off-by: Brian Evans <grknight@gentoo.org>
Diffstat (limited to 'UniversalLanguageSelector/resources/js/ext.uls.interface.js')
-rw-r--r-- | UniversalLanguageSelector/resources/js/ext.uls.interface.js | 778 |
1 files changed, 778 insertions, 0 deletions
diff --git a/UniversalLanguageSelector/resources/js/ext.uls.interface.js b/UniversalLanguageSelector/resources/js/ext.uls.interface.js new file mode 100644 index 00000000..5ae9a8b4 --- /dev/null +++ b/UniversalLanguageSelector/resources/js/ext.uls.interface.js @@ -0,0 +1,778 @@ +/*! + * ULS interface integration logic + * + * Copyright (C) 2012-2013 Alolita Sharma, Amir Aharoni, Arun Ganesh, Brandon Harris, + * Niklas Laxström, Pau Giner, Santhosh Thottingal, Siebrand Mazeland and other + * contributors. See CREDITS for a list. + * + * UniversalLanguageSelector is dual licensed GPLv2 or later and MIT. You don't + * have to do anything special to choose one license or the other and you don't + * have to notify anyone which license you are using. You are free to use + * UniversalLanguageSelector in commercial projects as long as the copyright + * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details. + * + * @file + * @ingroup Extensions + * @licence GNU General Public Licence 2.0 or later + * @licence MIT License + */ + +( function () { + 'use strict'; + var languageSettingsModules = [ 'ext.uls.displaysettings' ], + launchULS = require( './ext.uls.launch.js' ), + ActionsMenu = require( './ext.uls.actions.menu.js' ), + ActionsMenuItem = require( './ext.uls.actions.menu.item.js' ); + require( './ext.uls.actions.menu.items.registry.js' ); + + /** + * Construct the display settings link + * + * @return {jQuery} + */ + function displaySettings() { + return $( '<button>' ) + .addClass( 'display-settings-block' ) + .attr( { + title: $.i18n( 'ext-uls-display-settings-desc' ), + 'data-i18n': 'ext-uls-display-settings-title' + } ) + .i18n(); + } + + /** + * Construct the input settings link + * + * @return {jQuery} + */ + function inputSettings() { + return $( '<button>' ) + .addClass( 'input-settings-block' ) + .attr( { + title: $.i18n( 'ext-uls-input-settings-desc' ), + 'data-i18n': 'ext-uls-input-settings-title' + } ) + .i18n(); + } + + /** + * For Vector, check if the language button id exists. + * For other skins, check wgULSDisplaySettingsInInterlanguage for the current skin. + * + * @return {boolean} + */ + function isUsingStandaloneLanguageButton() { + // Checking for the ULS language button id returns true for Vector, false for other skins. + return $( '#p-lang-btn' ).length > 0 || mw.config.get( 'wgULSDisplaySettingsInInterlanguage' ); + } + + /** + * @return {jQuery} + */ + function createActionsMenuTrigger() { + var classes = [ 'mw-ui-button', 'mw-ui-quiet', 'uls-language-actions-button' ]; + return $( '<button>' ).addClass( classes ); + } + + /** + * @param {jQuery} actionsMenuTrigger + * @param {number} menuItemsCount + */ + function setActionsMenuTriggerIconClass( actionsMenuTrigger, menuItemsCount ) { + var iconClass, iconClasses = { + single: 'uls-language-actions-button--single', + multiple: 'uls-language-actions-button--multiple' + }; + if ( menuItemsCount > 1 ) { + iconClass = iconClasses.multiple; + } else { + iconClass = iconClasses.single; + } + iconClasses = Object.keys( iconClasses ).map( function ( key ) { + return iconClasses[ key ]; + } ); + // reset icon classes + // The following classes are being removed here (if present): + // * uls-language-actions-button--multiple + // * uls-language-actions-button--single + actionsMenuTrigger.removeClass( iconClasses ); + // One of the following classes are being added here: + // * uls-language-actions-button--multiple + // OR + // * uls-language-actions-button--single + actionsMenuTrigger.addClass( iconClass ); + } + + function hideLanguageSettingsFooter( uls ) { + uls.$menu.find( '#uls-settings-block' ).eq( 0 ).hide(); + } + + /** + * @param {jQuery} $element + * @param {Function} onCloseHandler + * @param {Object} uls + */ + function openLanguageSettings( $element, onCloseHandler, uls ) { + mw.loader.using( languageSettingsModules ).then( function () { + $element.languagesettings( { + defaultModule: 'display', + onClose: onCloseHandler, + onPosition: uls.position.bind( uls ), + onVisible: uls.hide.bind( uls ) + } ).trigger( 'click' ); + } ); + } + + /** + * Provide entry points to create article in other languages. T290436 + * + * @param {Object} uls The ULS object + */ + function addEmptyState( uls ) { + var $emptyStateContainer = $( '<section>' ).addClass( 'uls-empty-state' ); + + function openActionsMenuEventHandler( event ) { + event.stopPropagation(); + function onMenuClose() { + uls.show(); + } + openLanguageSettings( $( event.target ), onMenuClose, uls ); + } + + var languageSettingsMenuItem = { + name: 'languageSettings', + icon: 'settings', + text: $.i18n( 'ext-uls-actions-menu-language-settings-item-label' ), + handler: openActionsMenuEventHandler + }; + + var actionItemsRegistry = mw.uls.ActionsMenuItemsRegistry; + actionItemsRegistry.register( languageSettingsMenuItem ); + + var $actionsMenuTrigger = createActionsMenuTrigger(); + setActionsMenuTriggerIconClass( $actionsMenuTrigger, actionItemsRegistry.size() ); + var $header = $( '<h3>' ) + .addClass( 'uls-empty-state__header' ) + .text( $.i18n( 'ext-uls-empty-state-header' ) ); + var $desc = $( '<p>' ) + .addClass( 'uls-empty-state__desc' ) + .text( $.i18n( 'ext-uls-empty-state-desc' ) ); + $emptyStateContainer.append( $header, $desc ); + uls.$resultsView.append( $emptyStateContainer ); + + var actionItems = actionItemsRegistry.getItems(); + + if ( actionItems.length > 1 ) { + // languageSettingsMenuItem will be always there. + // If other actions available, change text + $header.text( $.i18n( 'ext-uls-empty-state-header-actions-available' ) ); + $desc.text( $.i18n( 'ext-uls-empty-state-desc-actions-available' ) ); + } + + // Action menu items need OOUI widgets. Load them and register trigger event handler. + mw.loader.using( [ 'oojs-ui-widgets', 'oojs-ui.styles.icons-interactions' ] ).done( function () { + var $actionsList = $( '<ul>' ).addClass( 'uls-language-action-items' ); + actionItems.forEach( function ( actionItem ) { + var actionButton = new ActionsMenuItem( + actionItem.icon, + actionItem.text, + actionItem.handler, + actionItem.href + ).render(); + $actionsList.append( $( '<li>' ).append( actionButton.$element ) ); + } ); + + $emptyStateContainer.append( $actionsList ); + } ); + + } + + /** + * Add language actions menu + * + * @param {Object} uls The ULS object + */ + function addActionsMenuTrigger( uls ) { + var actionsMenuDialog; + + function openActionsMenuEventHandler( event ) { + event.stopPropagation(); + + function onMenuClose() { + actionsMenuDialog.hide(); + uls.show(); + } + openLanguageSettings( $( event.target ), onMenuClose, uls ); + } + + var languageSettingsMenuItem = { + name: 'languageSettings', + icon: 'settings', + text: $.i18n( 'ext-uls-actions-menu-language-settings-item-label' ), + handler: openActionsMenuEventHandler + }; + + var actionItemsRegistry = mw.uls.ActionsMenuItemsRegistry; + actionItemsRegistry.register( languageSettingsMenuItem ); + + var $actionsMenuTrigger = createActionsMenuTrigger(); + setActionsMenuTriggerIconClass( $actionsMenuTrigger, actionItemsRegistry.size() ); + + function registerTriggerListener() { + $actionsMenuTrigger.off( 'click' ); + $actionsMenuTrigger.on( 'click', function () { + var menuItemsLength = actionItemsRegistry.size(); + + if ( menuItemsLength === 1 ) { + openLanguageSettings( $actionsMenuTrigger, uls.show.bind( uls ), uls ); + $actionsMenuTrigger.off( 'click' ); + } else if ( menuItemsLength > 1 ) { + actionsMenuDialog = actionsMenuDialog || new ActionsMenu( { + actions: actionItemsRegistry.getItems(), + onPosition: uls.position.bind( uls ), + onClose: uls.show.bind( uls ) + } ); + actionsMenuDialog.render(); + uls.hide(); + } + } ); + } + function onActionItemAdded( item ) { + var itemsLength = actionItemsRegistry.size(); + setActionsMenuTriggerIconClass( $actionsMenuTrigger, itemsLength ); + registerTriggerListener(); + if ( actionsMenuDialog ) { + actionsMenuDialog.renderAction( item ); + } + } + actionItemsRegistry.on( 'register', onActionItemAdded ); + uls.$menu.append( $actionsMenuTrigger ); + // Action menu items need OOUI widgets. Load them and register trigger event handler. + mw.loader.using( [ 'oojs-ui-widgets', 'oojs-ui.styles.icons-interactions' ] ).done( function () { + registerTriggerListener(); + } ); + } + + /** + * Add display settings link to the settings bar in ULS + * + * @param {Object} uls The ULS object + */ + function addDisplaySettings( uls ) { + var $displaySettings = displaySettings(); + + uls.$menu.find( '#uls-settings-block' ).append( $displaySettings ); + // Initialize the trigger + $displaySettings.one( 'click', function () { + $displaySettings.languagesettings( { + defaultModule: 'display', + onClose: uls.show.bind( uls ), + onPosition: uls.position.bind( uls ), + onVisible: uls.hide.bind( uls ) + } ).trigger( 'click' ); + } ); + } + + /** + * Add input settings link to the settings bar in ULS + * + * @param {Object} uls The ULS object + */ + function addInputSettings( uls ) { + var $inputSettings = inputSettings(); + + uls.$menu.find( '#uls-settings-block' ).append( $inputSettings ); + // Initialize the trigger + $inputSettings.one( 'click', function () { + $inputSettings.languagesettings( { + defaultModule: 'input', + onClose: uls.show.bind( uls ), + onPosition: uls.position.bind( uls ), + onVisible: uls.hide.bind( uls ) + } ).trigger( 'click' ); + } ); + } + + function userCanChangeLanguage() { + return mw.config.get( 'wgULSAnonCanChangeLanguage' ) || !mw.user.isAnon(); + } + + /** + * The tooltip to be shown when language changed using ULS. + * It also allows to undo the language selection. + * + * @param {string} previousLang + * @param {string} previousAutonym + */ + function showUndoTooltip( previousLang, previousAutonym ) { + var trigger, popup, popupPosition, + configPosition = mw.config.get( 'wgULSPosition' ), + triggerSelector = ( configPosition === 'interlanguage' ) ? + '.uls-settings-trigger, .mw-interlanguage-selector' : + '.uls-trigger'; + + // Fallback if no entry point is present + trigger = document.querySelector( triggerSelector ) || document.querySelector( '#pt-preferences' ); + + // Skip tooltip if there is no element to attach the tooltip to. + // It will cause errors otherwise. + if ( !trigger ) { + return; + } + + function hideTipsy() { + popup.toggle( false ); + } + + function showTipsy( timeout ) { + var tipsyTimer = 0; + + popup.toggle( true ); + popup.toggleClipping( false ); + + // if the mouse is over the tooltip, do not hide + $( '.uls-tipsy' ).on( 'mouseover', function () { + clearTimeout( tipsyTimer ); + } ).on( 'mouseout', function () { + tipsyTimer = setTimeout( hideTipsy, timeout ); + } ).on( 'click', hideTipsy ); + + tipsyTimer = setTimeout( hideTipsy, timeout ); + } + + if ( configPosition === 'interlanguage' ) { + popupPosition = 'after'; + } else { + popupPosition = 'below'; + } + popup = new OO.ui.PopupWidget( { + padded: true, + width: 300, + classes: [ 'uls-tipsy' ], + // Automatically positioned relative to the trigger + $floatableContainer: $( trigger ), + position: popupPosition, + $content: ( function () { + var messageKey, $link; + + $link = $( '<a>' ) + .text( previousAutonym ) + .prop( { + href: '', + class: 'uls-prevlang-link', + lang: previousLang, + // We could get dir from uls.data, + // but we are trying to avoid loading it + // and 'auto' is safe enough in this context. + // T130390: must use attr + dir: 'auto' + } ) + .on( 'click', function ( event ) { + event.preventDefault(); + + // Track if event logging is enabled + mw.hook( 'mw.uls.language.revert' ).fire(); + + mw.loader.using( [ 'ext.uls.common' ] ).then( function () { + mw.uls.changeLanguage( event.target.lang ); + } ); + } ); + + if ( mw.storage.get( 'uls-gp' ) === '1' ) { + messageKey = 'ext-uls-undo-language-tooltip-text-local'; + } else { + messageKey = 'ext-uls-undo-language-tooltip-text'; + } + + // Message keys listed above + // eslint-disable-next-line mediawiki/msg-doc + return $( '<p>' ).append( mw.message( messageKey, $link ).parseDom() ); + }() ) + } ); + + popup.$element.appendTo( document.body ); + + // The interlanguage position needs some time to settle down + setTimeout( function () { + // Show the tipsy tooltip on page load. + showTipsy( 6000 ); + }, 700 ); + + // manually show the tooltip + $( trigger ).on( 'mouseover', function () { + // show only if the ULS panel is not shown + // eslint-disable-next-line no-jquery/no-sizzle + if ( !$( '.uls-menu:visible' ).length ) { + showTipsy( 3000 ); + } + } ); + } + + /** + * Adds display and input settings to the ULS dialog after loading their code. + * + * @param {Object} uls The ULS instance + * @return {jQuery.Promise} + */ + function loadDisplayAndInputSettings( uls ) { + return mw.loader.using( languageSettingsModules ).then( function () { + addDisplaySettings( uls ); + addInputSettings( uls ); + } ); + } + + function initSecondaryEntryPoints() { + $( '.uls-settings-trigger' ).one( 'click', function ( e ) { + e.preventDefault(); + mw.loader.using( languageSettingsModules, function () { + $( e.target ).languagesettings(); + $( e.target ).trigger( 'click' ); + } ); + } ); + } + + function initInterlanguageEntryPoint() { + var $pLang = $( '#p-lang' ); + + var $trigger = $( '<button>' ) + .addClass( 'uls-settings-trigger' ) + .prop( 'title', mw.msg( 'ext-uls-select-language-settings-icon-tooltip' ) ); + + // Append ULS cog to interlanguage section header in the sidebar + $pLang.prepend( $trigger ); + + // Replace the title of the interlanguage links area from "In other languages" to + // "Languages" if there are no language links. TODO: Remove this feature? + if ( !$pLang.find( 'div ul' ).children().length && isUsingStandaloneLanguageButton ) { + $pLang.find( 'h3' ).text( mw.msg( 'uls-plang-title-languages' ) ); + } + + var clickHandler = function ( e ) { + var languagesettings = $trigger.data( 'languagesettings' ), + languageSettingsOptions; + + if ( languagesettings ) { + if ( !languagesettings.shown ) { + mw.hook( 'mw.uls.settings.open' ).fire( 'interlanguage' ); + } + + return; + } + + // Initialize the Language settings window + languageSettingsOptions = { + defaultModule: 'display', + onPosition: function () { + var caretRadius, top, left, + ulsTriggerHeight = this.$element.height(), + ulsTriggerWidth = this.$element[ 0 ].offsetWidth, + ulsTriggerOffset = this.$element.offset(); + + // Same as border width in mixins.less, or near enough + caretRadius = 12; + + if ( ulsTriggerOffset.left > $( window ).width() / 2 ) { + left = ulsTriggerOffset.left - this.$window.width() - caretRadius; + this.$window.removeClass( 'selector-left' ).addClass( 'selector-right' ); + } else { + left = ulsTriggerOffset.left + ulsTriggerWidth + caretRadius; + 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. 16 is trigger icon height in pixels + top = ulsTriggerOffset.top + + ( ulsTriggerHeight / 2 ) - + ( caretRadius + 16 ); + + return { top: top, left: left }; + }, + onVisible: function () { + this.$window.addClass( 'callout' ); + } + }; + + mw.loader.using( languageSettingsModules, function () { + $trigger.languagesettings( languageSettingsOptions ).trigger( 'click' ); + } ); + + e.stopPropagation(); + }; + + $trigger.on( 'click', clickHandler ); + } + + function initPersonalEntryPoint() { + var $trigger = $( '.uls-trigger' ); + var clickHandler; + + if ( !userCanChangeLanguage() ) { + clickHandler = function ( e ) { + var languagesettings = $trigger.data( 'languagesettings' ); + + e.preventDefault(); + + if ( languagesettings ) { + if ( !languagesettings.shown ) { + mw.hook( 'mw.uls.settings.open' ).fire( 'personal' ); + } + } else { + mw.loader.using( languageSettingsModules, function () { + $trigger.languagesettings( { autoOpen: true } ); + mw.hook( 'mw.uls.settings.open' ).fire( 'personal' ); + } ); + // Stop propagating the event to avoid closing the languagesettings dialog + // when the event propagates to the document click handler inside + // languagesettings + e.stopPropagation(); + } + }; + } else { + clickHandler = function ( e, eventParams ) { + var uls = $trigger.data( 'uls' ); + + e.preventDefault(); + + if ( uls ) { + if ( !uls.shown ) { + mw.hook( 'mw.uls.settings.open' ).fire( 'personal' ); + } + } else { + mw.loader.using( 'ext.uls.mediawiki', function () { + $trigger.uls( { + quickList: function () { + return mw.uls.getFrequentLanguageList(); + }, + onReady: function () { + loadDisplayAndInputSettings( this ); + }, + onSelect: function ( language ) { + mw.uls.changeLanguage( language ); + }, + // Not actually used on sites with the gear icon + // in the interlanguage area, because this ULS + // will be a container for other ULS panels. + // However, this is used on sites with ULS + // in the personal bar, and in that case it has the same + // purpose as the selector in Display settings, + // so it has the same identifier. + ulsPurpose: 'interface-language' + } ); + + // Allow styles to apply first and position to work by + // delaying the activation after them. + setTimeout( function () { + $trigger.trigger( 'click', eventParams ); + }, 0 ); + } ); + } + }; + } + + $trigger.on( 'click', clickHandler ); + // Optimization: Prefetch the Resource loader modules for ULS on mouseover + $trigger.one( 'mouseover', function () { + mw.loader.load( languageSettingsModules ); + } ); + } + + function initLanguageChangeUndoTooltip() { + var previousLanguage, currentLanguage, previousAutonym, currentAutonym; + + if ( !userCanChangeLanguage() ) { + return; + } + + previousLanguage = mw.storage.get( 'uls-previous-language-code' ); + currentLanguage = mw.config.get( 'wgUserLanguage' ); + previousAutonym = mw.storage.get( 'uls-previous-language-autonym' ); + currentAutonym = mw.config.get( 'wgULSCurrentAutonym' ); + + // If storage is empty, i.e. first visit, then store the current language + // immediately so that we know when it changes. + if ( !previousLanguage || !previousAutonym ) { + mw.storage.set( 'uls-previous-language-code', currentLanguage ); + mw.storage.set( 'uls-previous-language-autonym', currentAutonym ); + return; + } + + if ( previousLanguage !== currentLanguage ) { + mw.loader.using( 'oojs-ui-core' ).done( function () { + showUndoTooltip( previousLanguage, previousAutonym ); + } ); + mw.storage.set( 'uls-previous-language-code', currentLanguage ); + mw.storage.set( 'uls-previous-language-autonym', currentAutonym ); + // Store this language in a list of frequently used languages + mw.loader.using( [ 'ext.uls.common' ] ).then( function () { + mw.uls.addPreviousLanguage( currentLanguage ); + } ); + } + } + + function initIme() { + var imeSelector = mw.config.get( 'wgULSImeSelectors' ).join( ', ' ); + + $( document.body ).on( 'focus.imeinit', imeSelector, function () { + var $input = $( this ); + $( document.body ).off( '.imeinit' ); + mw.loader.using( 'ext.uls.ime', function () { + mw.ime.setup(); + mw.ime.handleFocus( $input ); + } ); + } ); + } + + /** + * Special handling for checkbox hack. + * Disable default checkbox behavior and bind click to "Enter" keyboard events + */ + function handleCheckboxSelector() { + // If the ULS button is also a checkbox, we can + // conclude that it's using the checkbox hack. + $( document ).on( 'input', 'input.mw-interlanguage-selector[type="checkbox"]', function ( ev ) { + var elem = ev.currentTarget; + elem.checked = false; + } ); + + $( document ).on( 'keydown', 'input.mw-interlanguage-selector[type="checkbox"]', function ( ev ) { + var elem = ev.currentTarget; + if ( ev.key !== 'Enter' ) { + return; + } + elem.click(); + } ); + } + + /** + * Load and open ULS for content language selection. + * + * This dialog is primarily for selecting the language of the content, but may also provide + * access to display and input settings if isUsingStandaloneLanguageButton() returns true. + * + * @param {jQuery.Event} ev + */ + function loadContentLanguageSelector( ev ) { + var $target = $( ev.currentTarget ); + + // Avoid reinitializing ULS multiple times for an element + if ( $target.attr( 'data-uls-loaded' ) ) { + return; + } + + ev.preventDefault(); + + mw.loader.using( 'ext.uls.mediawiki' ).then( function () { + var parent, languageNodes, standalone, uls; + + parent = document.querySelectorAll( '.mw-portlet-lang, #p-lang' )[ 0 ]; + languageNodes = parent ? parent.querySelectorAll( '.interlanguage-link-target' ) : []; + standalone = isUsingStandaloneLanguageButton(); + + $target.attr( 'data-uls-loaded', true ); + + // Setup click handler for ULS + launchULS( + $target, + mw.uls.getInterlanguageListFromNodes( languageNodes ), + // Using this as heuristic for now. May need to reconsider later. Enables + // behavior specific to compact language links. + !standalone + ); + + // Trigger the click handler to open ULS once ready + if ( standalone ) { + // Provide access to display and input settings if this entry point is the single + // point of access to all language settings. + uls = $target.data( 'uls' ); + // first hide #uls-settings-block div since it's unused, and it causes + // an unwanted extra border to show up at the bottom of the menu + hideLanguageSettingsFooter( uls ); + if ( languageNodes.length ) { + addActionsMenuTrigger( uls ); + } else { + // There are no languages - The article exist only the current language wiki + // Provide entry points to create article in other languages. T290436 + addEmptyState( uls ); + } + $target.trigger( 'click' ); + } else { + $target.trigger( 'click' ); + } + } ); + } + + /** Setup lazy-loading for content language selector */ + function initContentLanguageSelectorClickHandler() { + // FIXME: In Timeless ULS is embedded in a menu which stops event propagation + if ( $( '.sidebar-inner' ).length ) { + $( '.sidebar-inner #p-lang' ) + .one( 'click', '.mw-interlanguage-selector', loadContentLanguageSelector ); + } else { + // This button may be created by the new Vector skin, or ext.uls.compactlinks module + // if there are many languages. Warning: Both this module and ext.uls.compactlinks + // module may run simultaneously. Using event delegation to avoid race conditions where + // the trigger may be created after this code. + $( document ).on( 'click', '.mw-interlanguage-selector', loadContentLanguageSelector ); + // Special handling for checkbox hack. + handleCheckboxSelector(); + } + } + + function init() { + initLanguageChangeUndoTooltip(); + initIme(); + + // There are three basic components of ULS interface: + // - language selection for interface + // - language selection for content + // - settings view (access to language selection for interface, fonts, input methods) + // + // These can be combined in different ways: + // - Vector skin (recently) has an omni selector that has content language selection as + // primary action with access to the settings view. It is on top right corner (LTR) of + // the page content area. It may not be present on all pages. + // - Compact language links provides access to content language selection only and it is in + // the interlanguage section of the sidebar. This is in addition to one of the main entry + // points below. + // - Personal entry point appears at the top of the page. It provides quick access to the + // interface language selection with access to the settings view, except if user is not + // logged in and not allowed to change a language. In this case it defaults to settings + // view without language selection. + // - Interlanguage entry point (a cog) appears in the interlanguage section in the sidebar. + // It defaults to the settings view. + // + // The three main entry points (omni selector, personal, interlanguage) are mutually + // exclusive. There may be secondary entry points anywhere on the page using the + // uls-settings-trigger class. + + // First init secondary to avoid initing the interlanguage entry point multiple times + initSecondaryEntryPoints(); + var position = mw.config.get( 'wgULSPosition' ); + if ( position === 'interlanguage' ) { + initInterlanguageEntryPoint(); + } else { + initPersonalEntryPoint(); + } + + var compact = mw.config.get( 'wgULSisCompactLinksEnabled' ); + // The scope of the compact language links user preference has been expanded to also + // determine whether to show the omni box or not. Compact language links is already not + // loaded server side, so this is only relevant for the omnibox. + if ( compact ) { + // Init compact languages OR omni selector using the mw-interlanguage-selector class + initContentLanguageSelectorClickHandler(); + } else { + $( '.mw-interlanguage-selector' ).removeClass( 'mw-interlanguage-selector' ); + document.body.classList.add( 'mw-interlanguage-selector-disabled' ); + } + } + + // Early execute of init + if ( document.readyState === 'interactive' ) { + init(); + } else { + $( init ); + } + +}() ); |