Santhosh has uploaded a new change for review. https://gerrit.wikimedia.org/r/120488
Change subject: Reorganzie the compact links code, make it a jquery plugin ...................................................................... Reorganzie the compact links code, make it a jquery plugin No change in functionality. Refactored the code a lot and made it as a jquery plugin, similar to the other components of ULS Change-Id: I69199ba37b13ec7fd4a9b7b8eba5b3aa28f0edb5 --- M resources/js/ext.uls.compactlinks.js M resources/js/ext.uls.init.js 2 files changed, 241 insertions(+), 234 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/UniversalLanguageSelector refs/changes/88/120488/1 diff --git a/resources/js/ext.uls.compactlinks.js b/resources/js/ext.uls.compactlinks.js index 59c7879..05f1baa 100644 --- a/resources/js/ext.uls.compactlinks.js +++ b/resources/js/ext.uls.compactlinks.js @@ -21,232 +21,257 @@ 'use strict'; /** - * Add a language to the interlanguage list - * @param {string} name Name of language in Autonym font - * @param {string} url Link of the article in the respective language wiki + * For the given array, remove duplicates + * @param {Array} originalArray + * @return de-duplicated array */ - function addLanguage( name, url ) { - var $linkNode, - $listNode, - $interlanguageList; + function unique( originalArray ) { + var uniqueArray = []; - $linkNode = $( '<a>' ) - .addClass( 'active' ) - .attr( 'href', url ) - .text( name ); - - $listNode = $( '<li>' ) - .append( $linkNode ); - - $interlanguageList = $( '#p-lang > div > ul' ); - $interlanguageList.append( $listNode ); - } - - /** - * Find out the existing languages supported - * by article and fetch their href - * @return {Object} List of exiting language codes and their hrefs - */ - function getInterlanguageList() { - var interlangList = {}, - selectedElement; - $( '#p-lang > div > ul > li > a' ).each( function() { - selectedElement = $( this ); - interlangList[ selectedElement.attr( 'lang' ) ] = selectedElement.attr( 'href' ); + $.each( originalArray, function ( i, v ) { + if ( $.inArray( v, uniqueArray ) === -1 ) { + uniqueArray.push( v ); + } } ); - return interlangList; + return uniqueArray; } /** - * Fetch list of language names(in Autonym) which are supported by the article - * @return {Object} List of Language names in Autonym supported by article + * @class */ - function getCurrentLanguages() { - var acceptedLanglist = {}, - interlangList = getInterlanguageList(), i; - for ( i in interlangList ) { - if( interlangList.hasOwnProperty( i ) ) { - acceptedLanglist[ i ] = $.uls.data.getAutonym(i); + function CompactInterlanguageList( interlanguageList, options ) { + this.$interlanguageList = $( interlanguageList ); + this.options = $.extend( {}, $.fn.compactInterlanguageList.defaults, options ); + this.interlanguageList = {}; + this.compactList = {}; + this.$trigger = null; + this.compactSize = 0; + this.listSize = 0; + this.init(); + } + + CompactInterlanguageList.prototype = { + /** + * Initialize the plugin + */ + init: function () { + this.interlanguageList = this.getInterlanguageList(); + this.listSize = this.getListSize(); + + if ( this.listSize <= this.options.max ) { + return; } - } - return acceptedLanglist; - } - /** - * Frequently spoken languages which are supported by the article for - * the Common Languages section of the ULS - * @return {Array} List of those language codes which are supported by article and appears - * in the Common Languages section of ULS - */ - function getCommonLanguages() { - // From ext.uls.init.js - var frequentLang = mw.uls.getFrequentLanguageList(), - $acceptedLang = $.map( getCurrentLanguages(), function ( element, index ) { + // if the interlanguage list is of moderate size, the compact size is 7. + this.compactSize = ( this.listSize <= 12 ) ? 7 : this.options.max; + this.hideOriginal(); + this.compactList = this.getCompactList(); + this.render(); + this.listen(); + }, + + /** + * Render the compacted interlanguage list and triggers + */ + render: function () { + var language; + + for ( language in this.compactList ) { + this.addLanguage( language ); + } + this.addTrigger(); + }, + + /** + * Bind to event handlers and listen for events + */ + listen: function () { + var cl = this, + triggerPosition = this.$trigger.offset(), + ulsLanguageList = {}, + languages; + + languages = $.map( this.compactList, function ( language, languageCode ) { + ulsLanguageList[ languageCode ] = language.autonym; + return languageCode; + } ); + + // Attach ULS to the trigger + this.$trigger.uls( { + onReady: function () { + this.$menu.addClass( 'interlanguage-uls-menu' ); + }, + /** + * Language selection handler + * @param {string} language language code + */ + onSelect: function ( language ) { + var previousLanguages = mw.uls.getPreviousLanguages(); + previousLanguages.push( language ); + previousLanguages = unique( previousLanguages ); + mw.uls.setPreviousLanguages( previousLanguages ); + window.location.href = cl.compactList[ language ].href; + }, + compact: true, + left: triggerPosition.left + cl.$trigger.width() + 50 + 'px', + top: triggerPosition.top - cl.$trigger.height() / 2 - 250 + 'px', + languages: ulsLanguageList, + quickList: cl.filterByCommonLanguages( languages ) + } ); + }, + + /** + * Get the compacted interlanguage list as associative array + * @return {Object} + */ + getCompactList: function () { + var language, languages, compactLanguages, index, compactedList = {}; + languages = $.map( this.interlanguageList, function ( element, index ) { return index; - } ), - commonLanguages = [], i; - for ( i = 0; i < frequentLang.length; i++ ) { - if ( $.inArray( frequentLang[i], $acceptedLang ) >= 0 ) { - commonLanguages.push( frequentLang[i] ); + } ); + compactLanguages = this.compact( languages ); + for ( index = 0; index < compactLanguages.length; index++ ) { + language = compactLanguages[ index ]; + compactedList[ language ] = this.interlanguageList[ language ]; } + return compactedList; + }, + + /** + * Compact a given array of languages + * @param {Array} languages + * @return {Array} compacted array + */ + compact: function ( languages ) { + var compactLanguages = []; + + // Add previous language selections to this array. Previous languages are always + // the better suggestion because user had explicitly choosen them. + compactLanguages = compactLanguages.concat( mw.uls.getPreviousLanguages() ); + // Add all common languages to the begginning of array. These are the most probable + // languages predicted by ULS + compactLanguages = compactLanguages.concat( this.filterByCommonLanguages( languages ) ); + // Finally add the whole languages array too. We will remove duplicate and cut down + // to required size. + compactLanguages = compactLanguages.concat( languages ); + // Remove duplicates + compactLanguages = unique( compactLanguages ); + // Cut to compact size and sort + compactLanguages = compactLanguages.slice( 0, this.compactSize ).sort(); + return compactLanguages; + }, + + /** + * Filter the language list by common languages. Common languages are the most + * probable languages predicted by ULS + * @return {Array} List of those language codes which are supported by article + */ + filterByCommonLanguages: function ( languages ) { + var commonLanguages; + + commonLanguages = mw.uls.getFrequentLanguageList(); + return $.grep( commonLanguages, function ( language ) { + return $.inArray( language, languages ) >= 0; + } ); + }, + /** + * Find out the existing languages supported + * by article and fetch their href + * @return {Object} List of exiting language codes and their hrefs + */ + getInterlanguageList: function getInterlanguageList() { + var interlanguageList = {}; + + this.$interlanguageList.find( 'li.interlanguage-link > a' ).each( function () { + var $this = $( this ); + interlanguageList[ $this.attr( 'lang' ) ] = { + href: $this.attr( 'href' ), + autonym: $this.text() + }; + } ); + return interlanguageList; + }, + + /** + * Get the size of the inter language list + */ + getListSize: function () { + return $.map( this.interlanguageList, function ( item, index ) { + return index; + } ).length; + }, + + /** + * Hide the original interlanguage list + */ + hideOriginal: function () { + this.$interlanguageList.find( '.interlanguage-link' ).hide(); + }, + + /** + * Add the trigger at the bottom of the language list + */ + addTrigger: function () { + var $trigger, $triggerLabel; + + $trigger = $( '<div>' ) + .addClass( 'mw-interlanguage-selector mw-ui-button active' ) + .html( '…' ); // '…' + + $triggerLabel = $( '<label>' ) + .attr( 'id', 'more-lang-label' ) + .text( $.i18n( 'ext-uls-compact-link-count', this.listSize - this.compactSize ) ); + this.$interlanguageList.append( $trigger, $triggerLabel ); + this.$trigger = $trigger; + }, + + /** + * Add a language to the interlanguage list + * @param {string} language + */ + addLanguage: function ( language ) { + var $link, $listItem, languageLink; + + languageLink = this.interlanguageList[ language ]; + $link = $( '<a>' ) + .addClass( 'active' ) + .attr( 'href', languageLink.href ) + .text( languageLink.autonym ); + $listItem = $( '<li>' ) + .addClass( 'interlanguage-link interwiki-' + language ) + .append( $link ); + this.$interlanguageList.append( $listItem ); } - return commonLanguages; - } + }; - /** - * Push the selected language into the previous languages list - * @param {string} Language code of language selected (clicked on) - */ - function insertPreviousLanguage( currentLang ) { - mw.uls.insertPreviousLanguage( currentLang ); - } + /* CompactInterlanguageList Plugin + * =========================== */ - /** - * Add a ULS trigger beneath the interlanguage links - */ - function addULSlink() { - var $newLinknode, - $interlanguageList, - supportedLangs, - posOfTrigger; + $.fn.compactInterlanguageList = function ( option ) { + return this.each( function () { + var $this = $( this ), + data = $this.data( 'compactinterlanguagelist' ), + options = typeof option === 'object' && option; - $newLinknode = $( '<div>' ) - .addClass( 'mw-interlanguage-selector mw-ui-button active' ) - .html( '…' ) - .append( $newLinknode ); + if ( !data ) { + $this.data( 'compactinterlanguagelist', ( data = new CompactInterlanguageList( this, options ) ) ); + } - $interlanguageList = $( '#p-lang > div > ul' ); - $interlanguageList.append( $newLinknode ); - posOfTrigger = $newLinknode.offset(); - - $( '.mw-interlanguage-selector' ).uls( { - onReady: function() { - this.$menu.addClass( 'interlanguage-uls-menu' ); - }, - - onSelect: function( language ) { - supportedLangs = getInterlanguageList(); - // To set selected language as a previous language - insertPreviousLanguage( language ); - window.location.href = supportedLangs[language]; - }, - - compact: true, - left: posOfTrigger.left + $newLinknode.width() + 50 + 'px', - top: posOfTrigger.top - $newLinknode.height()/2 - 250 + 'px', - languages: getCurrentLanguages(), - quickList: getCommonLanguages() + if ( typeof option === 'string' ) { + data[ option ](); + } } ); - } + }; /** - * Hide existing languages displayed on the page + * Defaults */ - function hideLanguages() { - var $languages = $( '.interlanguage-link' ); - $languages.hide(); - } + $.fn.compactInterlanguageList.defaults = { + max: 9 // Compact the list to this size + }; - /** - * Returns all languages returned by the commonLanguages function - * and randomly some more if the number falls short of numberOfLanguagesToShow parameter - * @param {number} numberOfLanguagesToShow Number of languages to be shown in sidebar - * @return {Array} Language codes of the final list to be displayed - */ - function displayLanguages( numberOfLanguagesToShow ) { - var commonLang = getCommonLanguages(), - acceptedLangs = $.map( getCurrentLanguages(), function ( element, index ) { - return index; - } ), i, - prevLangs = mw.uls.getPreviousLanguages(), - count, - finalList = []; - - // Add languages in the common list and accepted by article - for ( i = 0; i < commonLang.length; i++ ) { - finalList.push( commonLang[i] ); - } - - // Add languages in previous choices to list if not already in it - for ( i = 0; i < prevLangs.length; i++ ) { - if ( - $.inArray( prevLangs[i], finalList ) < 0 && - $.inArray( prevLangs[i], acceptedLangs ) >= 0 - ) { - finalList.push( prevLangs[i] ); - } - } - - // Add random languages to make the language list long enough, if it isn't already - count = finalList.length; - if ( count < numberOfLanguagesToShow ) { - for ( i = 0; i < acceptedLangs.length; i++ ) { - if ( $.inArray( acceptedLangs[i], finalList ) < 0 ) { - finalList.push( acceptedLangs[i] ); - count++; - if ( count === numberOfLanguagesToShow ) { - break; - } - } - } - } - - // Sorting the language list in alphabetical order of ISO codes - finalList = finalList.sort(); - return finalList; - } - - /* - * Adds a label stating the number of more languages - * beneath the ULS link - * @param {Number} numberOfLanguagesSupported Number of languages supported by article - * @param {Number} numberOfLanguagesToShow Number of languages to be shown in the sidebar - */ - function addLabel( numberOfLanguagesSupported, numberOfLanguagesToShow ) { - var $interlanguageList = $( '#p-lang > div > ul' ), - newLabel = $( '<label>' ) - .attr( 'id', 'more-lang-label' ), - numberOfLanguagesHidden = numberOfLanguagesSupported - numberOfLanguagesToShow; - newLabel.text( $.i18n( 'ext-uls-compact-link-count', numberOfLanguagesHidden ) ); - $interlanguageList.append( newLabel ); - } - - /* - * Driver function to manipulate interlanguage list - * Computes number of languages to be shown - * and passes appropriate parameters to displayLanguages - * and addLabel functions - */ - function manageInterlaguageList() { - var $numOfLangCurrently = $( '.interlanguage-link' ).length, - currentLangs = getInterlanguageList(), - numLanguages = 9, - minLanguages = 7, - flagForNumberOfLangs = 0, i, - finalList; //Final list of languages to be displayed on page - - if ( $numOfLangCurrently > 9 ) { - hideLanguages(); - if ( $numOfLangCurrently > 9 && $numOfLangCurrently <= 12 ) { - finalList = displayLanguages( minLanguages ); - } else { - flagForNumberOfLangs = 1; - finalList = displayLanguages( numLanguages ); - } - - for ( i in finalList ) { - addLanguage( $.uls.data.getAutonym( finalList[i] ), currentLangs[ finalList[i] ] ); - } - - addULSlink(); - if ( !flagForNumberOfLangs ) { - addLabel( $numOfLangCurrently, minLanguages ); - } else { - addLabel( $numOfLangCurrently, numLanguages ); - } - } - } - - $( document ).ready( manageInterlaguageList() ); + $( document ).ready( function () { + $( '#p-lang-list' ).compactInterlanguageList(); + } ); }( jQuery, mediaWiki ) ); diff --git a/resources/js/ext.uls.init.js b/resources/js/ext.uls.init.js index 9507e7f..04a8535 100644 --- a/resources/js/ext.uls.init.js +++ b/resources/js/ext.uls.init.js @@ -26,7 +26,7 @@ slice = Array.prototype.slice; return function ( name ) { - var list = lists[name] || ( lists[name] = $.Callbacks( 'memory' ) ); + var list = lists[ name ] || ( lists[ name ] = $.Callbacks( 'memory' ) ); return { add: list.add, @@ -42,7 +42,7 @@ mw.uls = mw.uls || {}; mw.uls.previousLanguagesCookie = 'uls-previous-languages'; mw.uls.previousLanguageAutonymCookie = 'uls-previous-language-autonym'; - mw.uls.languageSettingsModules = ['ext.uls.inputsettings', 'ext.uls.displaysettings']; + mw.uls.languageSettingsModules = [ 'ext.uls.inputsettings', 'ext.uls.displaysettings' ]; // What was the last thing that the user did to select the language: // * 'map' - clicked the map @@ -104,8 +104,9 @@ mw.uls.setPreviousLanguages = function ( previousLanguages ) { $.cookie( mw.uls.previousLanguagesCookie, - $.toJSON( previousLanguages ), - { path: '/' } + $.toJSON( previousLanguages ), { + path: '/' + } ); }; @@ -121,25 +122,6 @@ }; /** - * Push the selected language into the previous languages list - * if it isn't there already - * @param {string} Language code of language to be pushed into list - */ - mw.uls.insertPreviousLanguage = function ( prevLangCode ) { - var previousLanguages = mw.uls.getPreviousLanguages() || [], - currentLangIndex; - // Checking if it already exists in array - currentLangIndex = $.inArray( prevLangCode, previousLanguages ); - if ( currentLangIndex < 0 ) { - previousLanguages.push( prevLangCode ); - } else { - previousLanguages.splice( currentLangIndex, 1 ); - previousLanguages.push( prevLangCode ); - } - mw.uls.setPreviousLanguages( previousLanguages ); - }; - - /** * Returns the browser's user interface language or the system language. * The caller should check the validity of the returned language code. * @@ -150,7 +132,7 @@ // userLanguage is only for IE and returns system locale. // Empty string is a fallback in case both are undefined // to avoid runtime error with split(). - return ( window.navigator.language || window.navigator.userLanguage || '' ).split( '-' )[0]; + return ( window.navigator.language || window.navigator.userLanguage || '' ).split( '-' )[ 0 ]; }; /*jshint camelcase:false*/ @@ -201,7 +183,7 @@ var target; // If the language is already known and defined, just use it - if ( $.fn.uls.defaults.languages[langCode] !== undefined ) { + if ( $.fn.uls.defaults.languages[ langCode ] !== undefined ) { return true; } @@ -212,7 +194,7 @@ if ( target ) { // Check that the redirect's target is known // to this instance of ULS - return $.fn.uls.defaults.languages[target] !== undefined; + return $.fn.uls.defaults.languages[ target ] !== undefined; } return false; @@ -229,13 +211,13 @@ function isBrowserSupported() { var blacklist = { 'msie': [ - ['<=', 7] + [ '<=', 7 ] ] }; // jquery.client changed in MediaWiki 1.22. // FIXME: Remove when ULS minimum MW version is 1.22. - if ( parseInt( mw.config.get( 'wgVersion' ).split( '.' )[1], '10' ) < 22 ) { + if ( parseInt( mw.config.get( 'wgVersion' ).split( '.' )[ 1 ], '10' ) < 22 ) { return !/MSIE [67]/i.test( navigator.userAgent ); } -- To view, visit https://gerrit.wikimedia.org/r/120488 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I69199ba37b13ec7fd4a9b7b8eba5b3aa28f0edb5 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/UniversalLanguageSelector Gerrit-Branch: master Gerrit-Owner: Santhosh <santhosh.thottin...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits