diff options
Diffstat (limited to 'MLEB/UniversalLanguageSelector/resources/js/ext.uls.compactlinks.js')
-rw-r--r-- | MLEB/UniversalLanguageSelector/resources/js/ext.uls.compactlinks.js | 211 |
1 files changed, 24 insertions, 187 deletions
diff --git a/MLEB/UniversalLanguageSelector/resources/js/ext.uls.compactlinks.js b/MLEB/UniversalLanguageSelector/resources/js/ext.uls.compactlinks.js index 61d763ff..72038c78 100644 --- a/MLEB/UniversalLanguageSelector/resources/js/ext.uls.compactlinks.js +++ b/MLEB/UniversalLanguageSelector/resources/js/ext.uls.compactlinks.js @@ -45,20 +45,6 @@ } /** - * Normalize a language code for ULS usage. - * - * MediaWiki language codes (especially on WMF sites) are inconsistent - * with ULS codes. We need to use ULS codes to access the proper data. - * - * @param {string} code - * @return {string} Normalized language code - */ - function convertMediaWikiLanguageCodeToULS( code ) { - code = code.toLowerCase(); - return $.uls.data.isRedirect( code ) || code; - } - - /** * Get user-defined assistant languages on wikis with Translate extension. * * Where available, they're languages deemed useful by the user. @@ -96,7 +82,7 @@ } /** - * Get site-specific highlighted languags. Mostly used on Wikimedia sites. + * Get site-specific highlighted languages. Mostly used on Wikimedia sites. * * @return {string[]|undefined} Language codes */ @@ -144,7 +130,9 @@ * @class * @constructor * @param {HTMLElement} listElement Interlanguage list element - * @param {Object} options + * @param {Object} [options] + * @param {number} [options.max] maximum number of languages to show + * in the compacted list. This defaults to DEFAULT_LIST_SIZE. */ function CompactInterlanguageList( listElement, options ) { this.listElement = listElement; @@ -154,7 +142,9 @@ * @private * @property {Object} interlanguageList */ - this.interlanguageList = null; + this.interlanguageList = mw.uls.getInterlanguageListFromNodes( + listElement.querySelectorAll( '.interlanguage-link-target' ) + ); /** * @private @@ -174,7 +164,6 @@ CompactInterlanguageList.prototype.init = function () { var max = this.options.max || DEFAULT_LIST_SIZE; - this.interlanguageList = this.getInterlanguageList(); this.listSize = Object.keys( this.interlanguageList ).length; if ( this.listSize <= max ) { @@ -189,7 +178,6 @@ this.compactList = this.getCompactList(); this.hideOriginal(); this.render(); - this.listen(); }; /** @@ -208,122 +196,6 @@ }; /** - * Attaches the actual selector to the trigger. - * - * @param {jQuery} $trigger Element to use as trigger. - */ - CompactInterlanguageList.prototype.createSelector = function ( $trigger ) { - var languageCode, - languages = Object.keys( this.interlanguageList ), - self = this, - ulsLanguageList = {}; - - for ( languageCode in this.interlanguageList ) { - ulsLanguageList[ languageCode ] = this.interlanguageList[ languageCode ].textContent; - } - - // Attach ULS to the trigger - $trigger.uls( { - onReady: function () { - this.$menu.addClass( 'interlanguage-uls-menu' ); - }, - /** - * Language selection handler - * - * @param {string} language language code - * @param {Object} event jQuery event object - */ - onSelect: function ( language, event ) { - self.$trigger.removeClass( 'selector-open' ); - mw.uls.addPreviousLanguage( language ); - - // Switch the current tab to the new language, - // unless it was Ctrl-click or Command-click - if ( !event.metaKey && !event.shiftKey ) { - location.href = self.interlanguageList[ language ].href; - } - }, - onVisible: function () { - var offset, height, width, triangleWidth; - // The panel is positioned carefully so that our pointy triangle, - // which is implemented as a square box rotated 45 degrees with - // rotation origin in the middle. See the corresponding style file. - - // These are for the trigger - offset = $trigger.offset(); - width = $trigger.outerWidth(); - height = $trigger.outerHeight(); - - // Triangle width is: who knows now, but this still looks fine. - triangleWidth = 12; - - 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 from the middle of the trigger - this.top = offset.top + ( height / 2 ) - 27; - - this.$menu.css( { - left: this.left, - top: this.top - } ); - $trigger.addClass( 'selector-open' ); - }, - languageDecorator: function ( $languageLink, language ) { - var element = self.interlanguageList[ language ]; - // Set href, text, and tooltip exactly same as what was in - // interlanguage link. The ULS autonym might be different in some - // cases like sr. In ULS it is "српски", while in interlanguage links - // it is "српски / srpski" - $languageLink - .prop( { - href: element.href, - title: element.title - } ) - .text( element.textContent ); - - // This code is to support badges used in Wikimedia - // eslint-disable-next-line mediawiki/class-doc - $languageLink.parent().addClass( element.parentNode.className ); - }, - onCancel: function () { - $trigger.removeClass( 'selector-open' ); - }, - languages: ulsLanguageList, - ulsPurpose: 'compact-language-links', - // Show common languages - quickList: self.getCommonLanguages( languages ), - noResultsTemplate: function () { - var $defaultTemplate = $.fn.lcd.defaults.noResultsTemplate.call( this ); - // Customize the message - $defaultTemplate - .find( '.uls-no-results-found-title' ) - .data( 'i18n', 'ext-uls-compact-no-results' ); - return $defaultTemplate; - } - } ); - }; - - /** - * Bind to event handlers and listen for events - */ - CompactInterlanguageList.prototype.listen = function () { - var self = this; - - this.$trigger.one( 'click', function () { - // Load the ULS now. - mw.loader.using( 'ext.uls.mediawiki' ).then( function () { - self.createSelector( self.$trigger ); - self.$trigger.trigger( 'click' ); - } ); - } ); - }; - - /** * Get the compacted interlanguage list as associative array * * @return {Object} @@ -364,8 +236,8 @@ getBabelLanguages, getSitePicks, getCommonLanguages, - this.getLangsInText, - this.getLangsWithBadges, + this.getLangsInText.bind( this ), + this.getLangsWithBadges.bind( this ), getExtraCommonLanguages, getFinalFallback ]; @@ -411,7 +283,7 @@ CompactInterlanguageList.prototype.getLangsInText = function () { var languagesInText = []; Array.prototype.forEach.call( document.querySelectorAll( '#mw-content-text [lang]' ), function ( el ) { - var lang = convertMediaWikiLanguageCodeToULS( el.lang ); + var lang = mw.uls.convertMediaWikiLanguageCodeToULS( el.lang ); if ( languagesInText.indexOf( lang ) === -1 ) { languagesInText.push( lang ); } @@ -428,49 +300,14 @@ */ CompactInterlanguageList.prototype.getLangsWithBadges = function () { return Array.prototype.map.call( - document.querySelectorAll( '#p-lang [class*="badge"]' ), + this.listElement.querySelectorAll( '[class*="badge"] a.interlanguage-link-target' ), function ( el ) { - return convertMediaWikiLanguageCodeToULS( - el.querySelector( '.interlanguage-link-target' ).lang - ); + return mw.uls.convertMediaWikiLanguageCodeToULS( el.lang ); } ); }; /** - * Get the list of languages links. - * - * @return {Object} Map of language codes to elements. - */ - CompactInterlanguageList.prototype.getInterlanguageList = function () { - var interlanguageList = {}; - - Array.prototype.forEach.call( this.listElement.querySelectorAll( '.interlanguage-link-target' ), function ( el ) { - var langCode = convertMediaWikiLanguageCodeToULS( el.lang ); - interlanguageList[ langCode ] = el; - } ); - - return interlanguageList; - }; - - /** - * Get common languages - the most probable languages predicted by ULS. - * - * @param {string[]} languages Language codes - * @return {string[]} List of all common language codes - */ - CompactInterlanguageList.prototype.getCommonLanguages = function ( languages ) { - if ( this.commonInterlanguageList === null ) { - this.commonInterlanguageList = mw.uls.getFrequentLanguageList() - .filter( function ( language ) { - return languages.indexOf( language ) >= 0; - } ); - } - - return this.commonInterlanguageList; - }; - - /** * Hide languages in the interlanguage list. * * The most relevant ones are unhidden in #render. @@ -484,10 +321,13 @@ }; /** - * Add the trigger at the bottom of the language list + * Add the trigger at the bottom of the language list. + * + * Click handler is setup in ext.uls.interface module. */ CompactInterlanguageList.prototype.addTrigger = function () { var trigger = document.createElement( 'button' ); + // TODO: Should we have a different class name where the CLS styles are attached? trigger.className = 'mw-interlanguage-selector mw-ui-button'; trigger.title = mw.message( 'ext-uls-compact-link-info' ).plain(); // Use text() because the message needs {{PLURAL:}} @@ -501,33 +341,30 @@ }; /** - * Performance cost of calling createCompactList(), as of 2018-09-10. + * Performance cost of calling createCompactList(), as of 2021-02-10. * * Summary: - * - DOM Queries: 5 + 1N + * - DOM Queries: 5 * * createCompactList (1 querySelector) - * * getLangsWithBadges (1N querySelector, 1 querySelectorAll) - * * getInterlanguageList (1 querySelectorAll) + * * CompactInterlanguageList constructor (1 querySelectorAll) + * * getLangsWithBadges (1 querySelectorAll) * * getLangsInText (1 querySelectorAll) * * hideOriginal (1 querySelectorAll) * - DOM Writes: 1 + 2N * * addTrigger (1 appendChild) * * hideOriginal (1N Element.style) - * * render (1N Element.style) + * * render (1N Element.style) // N defaults to 9 * - Misc: 1 * * addTrigger (1 mw.Message#parser) */ function createCompactList() { var listElement, compactList; - listElement = document.querySelector( '#p-lang ul' ); + listElement = document.querySelector( '.mw-portlet-lang ul, #p-lang ul' ); if ( !listElement ) { - // Not all namespaces/pages/actions have #p-lang. + // Not all namespaces will have a list of languages. return; } - compactList = new CompactInterlanguageList( listElement, { - // Compact the list to this size - max: 9 - } ); + compactList = new CompactInterlanguageList( listElement ); compactList.init(); } |