diff options
Diffstat (limited to 'www/wiki/extensions/UniversalLanguageSelector/resources/js/ext.uls.languagesettings.js')
-rw-r--r-- | www/wiki/extensions/UniversalLanguageSelector/resources/js/ext.uls.languagesettings.js | 314 |
1 files changed, 314 insertions, 0 deletions
diff --git a/www/wiki/extensions/UniversalLanguageSelector/resources/js/ext.uls.languagesettings.js b/www/wiki/extensions/UniversalLanguageSelector/resources/js/ext.uls.languagesettings.js new file mode 100644 index 00000000..44bdd15f --- /dev/null +++ b/www/wiki/extensions/UniversalLanguageSelector/resources/js/ext.uls.languagesettings.js @@ -0,0 +1,314 @@ +/*! + * ULS-based language settings dialog for MediaWiki. + * + * Copyright (C) 2012 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 closeRow, settingsMenu, settingsPanel, windowTemplate, panelsRow, buttonsRow; + + closeRow = '<div class="row">' + + '<div class="uls-language-settings-close-block eight columns offset-by-four"><span id="languagesettings-close" class="uls-icon-close"></span></div>' + + '</div>'; + settingsMenu = '<div class="four columns languagesettings-menu">' + + '<h1 data-i18n="ext-uls-language-settings-title"></h1>' + + '<div class="settings-menu-items">' + + '</div>' + + '</div>'; + settingsPanel = '<div id="languagesettings-settings-panel" class="eight columns">' + + '</div>'; + // Apply and Cancel buttons + buttonsRow = '<div class="row collapse language-settings-buttons">' + + '<div class="twelve columns">' + + '<button class="mw-ui-button uls-settings-cancel" data-i18n="ext-uls-language-settings-cancel"></button>' + + '<button class="mw-ui-button mw-ui-progressive active uls-settings-apply" data-i18n="ext-uls-language-settings-apply" disabled></button>' + + '</div>' + + '</div>' + + '</div>'; + panelsRow = '<div class="row" id="languagesettings-panels">' + + settingsMenu + + settingsPanel + + '</div>'; + windowTemplate = '<div style="display: block;" id="language-settings-dialog" class="language-settings-dialog grid uls-menu uls-wide">' + + closeRow + + panelsRow + + buttonsRow + + '</div>'; + + function LanguageSettings( element, options ) { + this.$element = $( element ); + this.options = $.extend( {}, $.fn.languagesettings.defaults, options ); + this.$window = $( this.options.template ); + this.shown = false; + this.initialized = false; + this.left = this.options.left; + this.top = this.options.top; + this.modules = {}; + this.$settingsPanel = this.$window.find( '#languagesettings-settings-panel' ); + this.init(); + this.listen(); + } + + LanguageSettings.prototype = { + constructor: LanguageSettings, + + init: function () { + $( 'body' ).append( this.$window ); + this.hide(); + }, + + // Register all event listeners to the ULS language settings here. + listen: function () { + this.$element.on( 'click', this.click.bind( this ) ); + + this.$window.find( '#languagesettings-close, button.uls-settings-cancel' ) + .on( 'click', mw.hook( 'mw.uls.settings.cancel' ).fire.bind( this ) ); + this.$window.find( 'button.uls-settings-apply' ) + .on( 'click', mw.hook( 'mw.uls.settings.apply' ).fire.bind( this ) ); + // Hide the window when clicked outside + $( 'html' ).on( 'click', this.hide.bind( this ) ); + + // ... but when clicked on window do not hide. + this.$window.on( 'click', function ( event ) { + event.stopPropagation(); + } ); + + // Map Escape to same action as the close button. This is keyup (and not keydown) + // because ULS also listens to keyup and we need to stop propagation. + this.$window.on( 'keyup', function ( event ) { + if ( event.which === 27 ) { + event.stopPropagation(); + mw.hook( 'mw.uls.settings.cancel' ).fire(); + } + } ); + }, + + render: function () { + var modules, + languageSettings = this, + defaultModule = this.options.defaultModule; + + // Get the name of all registered modules and list them in left side menu. + // Sort the modules based on id + modules = Object.keys( $.fn.languagesettings.modules ).sort(); + modules.forEach( function ( moduleName ) { + if ( !defaultModule ) { + defaultModule = moduleName; + } + + // Call render function on the current setting module. + languageSettings.initModule( moduleName, defaultModule === moduleName ); + } ); + }, + + /** + * Initialize the module. + * Render the link and settings area for a language setting module. + * + * @param {string} moduleName Name of the setting module + * @param {boolean} active boolean Make this module active and show by default + */ + initModule: function ( moduleName, active ) { + var $settingsTitle, $settingsText, $settingsLink, + languageSettings = this, + module = new $.fn.languagesettings.modules[ moduleName ]( languageSettings ), + $settingsMenuItems = languageSettings.$window.find( '.settings-menu-items' ); + + $settingsTitle = $( '<div>' ) + .addClass( 'settings-title' ) + .attr( 'data-i18n', module.nameI18n ); + $settingsText = $( '<span>' ) + .addClass( 'settings-text' ) + .attr( 'data-i18n', module.descriptionI18n ); + $settingsLink = $( '<button>' ) + .addClass( moduleName + '-settings-block menu-section' ) + .prop( 'id', moduleName + '-panel-trigger' ) + .data( 'module', module ) + .append( + $settingsTitle, + $settingsText + ); + + if ( active ) { + $settingsLink.addClass( 'active' ); + } + + $settingsMenuItems.append( $settingsLink ); + + $settingsLink.on( 'click', function () { + var $this = $( this ); + + $this.data( 'module' ).render(); + if ( languageSettings.$window.is( ':visible' ) ) { + languageSettings.$window.scrollIntoView(); + } + $settingsMenuItems.find( '.menu-section' ).removeClass( 'active' ); + $this.addClass( 'active' ); + } ); + + this.modules[ moduleName ] = module; + + // Register cancel and apply hooks + mw.hook( 'mw.uls.settings.cancel' ).add( module.cancel.bind( module ) ); + mw.hook( 'mw.uls.settings.apply' ).add( module.apply.bind( module ) ); + }, + + position: function () { + this.top = this.top || this.$element.offset().top + this.$element.outerHeight(); + this.left = this.left || '25%'; + this.$window.css( { + top: this.top, + left: this.left + } ); + }, + + i18n: function () { + this.$window.i18n(); + }, + + show: function () { + this.position(); + + if ( !this.initialized ) { + this.render(); + this.initialized = true; + } + // Close other modal windows which listen to click events outside them + $( 'html' ).trigger( 'click' ); + this.i18n(); + // Every time we show this window, make sure the current + // settings panels is up-to-date. So just click on active menu item. + this.$window.find( '.settings-menu-items > .active' ).trigger( 'click' ); + + this.shown = true; + this.$window.show(); + this.visible(); + this.$window.scrollIntoView(); + // For keyboard navigation, put the focus on an element inside the dialog + this.$window.find( '.menu-section.active' ).trigger( 'focus' ); + }, + + /** + * A "hook" that runs after the ULS panel becomes visible + * by using the show method. + * + * To use it, pass a function as the onVisible parameter + * in the options when initializing ULS. + */ + visible: function () { + if ( this.options.onVisible ) { + this.options.onVisible.call( this ); + } + }, + + /** + * Hide this window. + * Will be used when moving to a different context and + * need coming back. + */ + hide: function () { + this.shown = false; + this.$window.hide(); + }, + + /** + * Put the language settings panel in busy mode. + * Busy mode means displaying a progress cursor, + * and showing the 'apply' button as disabled and with + * a different label. + * + * @param {boolean} busy set true to put the panel in busy mode, + * false to unset the busy mode. + */ + setBusy: function ( busy ) { + var $applyButton = this.$window.find( 'button.uls-settings-apply' ); + + if ( busy ) { + this.$window.addClass( 'waiting' ); + $applyButton + .text( $.i18n( 'ext-uls-language-settings-applying' ) ) + .prop( 'disabled', true ); + } else { + this.$window.removeClass( 'waiting' ); + $applyButton.text( $.i18n( 'ext-uls-language-settings-apply' ) ); + } + }, + + /** + * Close this language settings window, and + * call onClose if defined from the previous context. + */ + close: function () { + if ( !this.shown ) { + return; + } + + this.hide(); + + // optional callback + if ( this.options.onClose ) { + this.options.onClose(); + } + + }, + + click: function ( e ) { + e.stopPropagation(); + e.preventDefault(); + + if ( this.shown ) { + this.hide(); + } else { + this.show(); + } + }, + + disableApplyButton: function () { + this.$window.find( 'button.uls-settings-apply' ).prop( 'disabled', true ); + } + }; + + $.fn.languagesettings = function ( option ) { + return this.each( function () { + var $this = $( this ), + data = $this.data( 'languagesettings' ), + options = typeof option === 'object' && option; + + if ( !data ) { + $this.data( 'languagesettings', ( data = new LanguageSettings( this, options ) ) ); + } + + if ( typeof option === 'string' ) { + data[ option ](); + } + } ); + }; + + $.fn.languagesettings.modules = {}; + $.fn.languagesettings.defaults = { + template: windowTemplate, + defaultModule: false, // Name of the default module + onClose: null, // An onClose event handler. + top: null, // Top position of this window + left: null, // Left position of this window + onVisible: null // A callback that runs after the ULS panel becomes visible + }; + + $.fn.languagesettings.Constructor = LanguageSettings; + +}() ); |