From 9ca24dc486eea049a62313eeb50cd62753369b41 Mon Sep 17 00:00:00 2001 From: "James D. Forrester" Date: Mon, 4 May 2015 17:48:51 -0700 Subject: [PATCH] Update OOjs UI to v0.11.1 Release notes: https://git.wikimedia.org/blob/oojs%2Fui.git/v0.11.1/History.md Change-Id: I8774390ed8393801212f2270a786984687794aeb --- composer.json | 2 +- resources/lib/oojs-ui/i18n/ps.json | 10 +- .../oojs-ui/oojs-ui-mediawiki-noimages.css | 79 +- resources/lib/oojs-ui/oojs-ui-mediawiki.js | 4 +- resources/lib/oojs-ui/oojs-ui.js | 758 +++++++++++++++++- .../themes/mediawiki/icons-interactions.json | 6 +- .../themes/mediawiki/icons-moderation.json | 2 +- .../lib/oojs-ui/themes/mediawiki/icons.json | 7 +- .../images/icons/block-destructive.png | Bin 0 -> 461 bytes .../images/icons/block-destructive.svg | 4 + .../{clear-invert.png => cancel-invert.png} | Bin .../{clear-invert.svg => cancel-invert.svg} | 2 +- .../themes/mediawiki/images/icons/cancel.png | Bin 0 -> 351 bytes .../themes/mediawiki/images/icons/cancel.svg | 6 + .../themes/mediawiki/images/icons/clear.png | Bin 351 -> 316 bytes .../themes/mediawiki/images/icons/clear.svg | 6 +- .../mediawiki/images/icons/closeInput.png | Bin 316 -> 0 bytes .../mediawiki/images/icons/closeInput.svg | 4 - .../images/icons/magnifyingGlass-ltr.png | Bin 380 -> 0 bytes .../images/icons/magnifyingGlass-ltr.svg | 4 - .../images/icons/magnifyingGlass-rtl.png | Bin 371 -> 0 bytes .../images/icons/magnifyingGlass-rtl.svg | 4 - .../mediawiki/images/icons/search-invert.png | Bin 278 -> 0 bytes .../mediawiki/images/icons/search-invert.svg | 6 - .../images/icons/search-ltr-invert.png | Bin 0 -> 372 bytes .../images/icons/search-ltr-invert.svg | 6 + .../mediawiki/images/icons/search-ltr.png | Bin 0 -> 350 bytes .../mediawiki/images/icons/search-ltr.svg | 6 + .../images/icons/search-rtl-invert.png | Bin 0 -> 376 bytes .../images/icons/search-rtl-invert.svg | 6 + .../mediawiki/images/icons/search-rtl.png | Bin 0 -> 341 bytes .../mediawiki/images/icons/search-rtl.svg | 6 + .../themes/mediawiki/images/icons/search.png | Bin 246 -> 0 bytes .../themes/mediawiki/images/icons/search.svg | 6 - .../images/indicators/search-ltr-invert.png | Bin 0 -> 251 bytes .../images/indicators/search-ltr-invert.svg | 6 + .../images/indicators/search-ltr.png | Bin 0 -> 231 bytes .../images/indicators/search-ltr.svg | 6 + .../images/indicators/search-rtl-invert.png | Bin 0 -> 261 bytes .../images/indicators/search-rtl-invert.svg | 6 + .../images/indicators/search-rtl.png | Bin 0 -> 234 bytes .../images/indicators/search-rtl.svg | 6 + .../oojs-ui/themes/mediawiki/indicators.json | 6 +- 43 files changed, 876 insertions(+), 88 deletions(-) create mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/block-destructive.png create mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/block-destructive.svg rename resources/lib/oojs-ui/themes/mediawiki/images/icons/{clear-invert.png => cancel-invert.png} (100%) rename resources/lib/oojs-ui/themes/mediawiki/images/icons/{clear-invert.svg => cancel-invert.svg} (96%) create mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/cancel.png create mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/cancel.svg delete mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/closeInput.png delete mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/closeInput.svg delete mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/magnifyingGlass-ltr.png delete mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/magnifyingGlass-ltr.svg delete mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/magnifyingGlass-rtl.png delete mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/magnifyingGlass-rtl.svg delete mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/search-invert.png delete mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/search-invert.svg create mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/search-ltr-invert.png create mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/search-ltr-invert.svg create mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/search-ltr.png create mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/search-ltr.svg create mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/search-rtl-invert.png create mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/search-rtl-invert.svg create mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/search-rtl.png create mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/search-rtl.svg delete mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/search.png delete mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/icons/search.svg create mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-ltr-invert.png create mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-ltr-invert.svg create mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-ltr.png create mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-ltr.svg create mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-rtl-invert.png create mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-rtl-invert.svg create mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-rtl.png create mode 100644 resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-rtl.svg diff --git a/composer.json b/composer.json index 3ea2f22fe0..6dc72e73b5 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,7 @@ "ext-iconv": "*", "leafo/lessphp": "0.5.0", "liuggio/statsd-php-client": "1.0.12", - "oojs/oojs-ui": "0.11.0", + "oojs/oojs-ui": "0.11.1", "php": ">=5.3.3", "psr/log": "1.0.0", "wikimedia/cdb": "1.0.1", diff --git a/resources/lib/oojs-ui/i18n/ps.json b/resources/lib/oojs-ui/i18n/ps.json index 94bc7df429..ebffe53972 100644 --- a/resources/lib/oojs-ui/i18n/ps.json +++ b/resources/lib/oojs-ui/i18n/ps.json @@ -6,5 +6,13 @@ }, "ooui-outline-control-move-down": "توکی ښکته راوړل", "ooui-outline-control-move-up": "توکی پورته راوړل", - "ooui-toolbar-more": "نور" + "ooui-outline-control-remove": "توکی غورځول", + "ooui-toolbar-more": "نور", + "ooui-toolgroup-expand": "نور", + "ooui-toolgroup-collapse": "لږ تر لږ", + "ooui-dialog-message-accept": "ښه", + "ooui-dialog-message-reject": "ناگارل", + "ooui-dialog-process-error": "يوه ستونزه رامنځ ته شوه", + "ooui-dialog-process-dismiss": "تړل", + "ooui-dialog-process-retry": "بيا هڅه" } diff --git a/resources/lib/oojs-ui/oojs-ui-mediawiki-noimages.css b/resources/lib/oojs-ui/oojs-ui-mediawiki-noimages.css index 806fab1132..297739d223 100644 --- a/resources/lib/oojs-ui/oojs-ui-mediawiki-noimages.css +++ b/resources/lib/oojs-ui/oojs-ui-mediawiki-noimages.css @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.11.0 + * OOjs UI v0.11.1 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2015 OOjs Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2015-04-30T01:42:35Z + * Date: 2015-05-05T00:40:57Z */ @-webkit-keyframes oo-ui-progressBarWidget-slide { from { @@ -459,6 +459,15 @@ .oo-ui-bookletLayout-outlinePanel > .oo-ui-outlineControlsWidget { box-shadow: 0 0 0.25em rgba(0, 0, 0, 0.25); } +.oo-ui-indexLayout > .oo-ui-menuLayout-menu { + height: 3em; +} +.oo-ui-indexLayout > .oo-ui-menuLayout-content { + top: 3em; +} +.oo-ui-indexLayout-stackLayout > .oo-ui-panelLayout { + padding: 1.5em; +} .oo-ui-fieldLayout { display: block; margin-bottom: 1em; @@ -1525,11 +1534,11 @@ border-width: 9px; } .oo-ui-popupWidget-transitioning .oo-ui-popupWidget-popup { - -webkit-transition: width 100ms ease-in-out, height 100ms ease-in-out, left 100ms ease-in-out; - -moz-transition: width 100ms ease-in-out, height 100ms ease-in-out, left 100ms ease-in-out; - -ms-transition: width 100ms ease-in-out, height 100ms ease-in-out, left 100ms ease-in-out; - -o-transition: width 100ms ease-in-out, height 100ms ease-in-out, left 100ms ease-in-out; - transition: width 100ms ease-in-out, height 100ms ease-in-out, left 100ms ease-in-out; + -webkit-transition: width 0.1s ease-in-out, height 0.1s ease-in-out, left 0.1s ease-in-out; + -moz-transition: width 0.1s ease-in-out, height 0.1s ease-in-out, left 0.1s ease-in-out; + -ms-transition: width 0.1s ease-in-out, height 0.1s ease-in-out, left 0.1s ease-in-out; + -o-transition: width 0.1s ease-in-out, height 0.1s ease-in-out, left 0.1s ease-in-out; + transition: width 0.1s ease-in-out, height 0.1s ease-in-out, left 0.1s ease-in-out; } .oo-ui-popupWidget-head { height: 2.5em; @@ -1813,11 +1822,11 @@ border: solid 1px #cccccc; box-shadow: inset 0 0 0 0 #347bff; border-radius: 0.1em; - -webkit-transition: box-shadow 0.1s; - -moz-transition: box-shadow 0.1s; - -ms-transition: box-shadow 0.1s; - -o-transition: box-shadow 0.1s; - transition: box-shadow 0.1s; + -webkit-transition: box-shadow 0.1s ease-in-out; + -moz-transition: box-shadow 0.1s ease-in-out; + -ms-transition: box-shadow 0.1s ease-in-out; + -o-transition: box-shadow 0.1s ease-in-out; + transition: box-shadow 0.1s ease-in-out; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; @@ -1831,11 +1840,11 @@ } .oo-ui-textInputWidget.oo-ui-widget-enabled input, .oo-ui-textInputWidget.oo-ui-widget-enabled textarea { - -webkit-transition: border 0.2s cubic-bezier(0.39, 0.575, 0.565, 1) box-shadow 0.2s cubic-bezier(0.39, 0.575, 0.565, 1); - -moz-transition: border 0.2s cubic-bezier(0.39, 0.575, 0.565, 1) box-shadow 0.2s cubic-bezier(0.39, 0.575, 0.565, 1); - -ms-transition: border 0.2s cubic-bezier(0.39, 0.575, 0.565, 1) box-shadow 0.2s cubic-bezier(0.39, 0.575, 0.565, 1); - -o-transition: border 0.2s cubic-bezier(0.39, 0.575, 0.565, 1) box-shadow 0.2s cubic-bezier(0.39, 0.575, 0.565, 1); - transition: border 0.2s cubic-bezier(0.39, 0.575, 0.565, 1) box-shadow 0.2s cubic-bezier(0.39, 0.575, 0.565, 1); + -webkit-transition: border 0.2s cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 0.2s cubic-bezier(0.39, 0.575, 0.565, 1); + -moz-transition: border 0.2s cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 0.2s cubic-bezier(0.39, 0.575, 0.565, 1); + -ms-transition: border 0.2s cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 0.2s cubic-bezier(0.39, 0.575, 0.565, 1); + -o-transition: border 0.2s cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 0.2s cubic-bezier(0.39, 0.575, 0.565, 1); + transition: border 0.2s cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 0.2s cubic-bezier(0.39, 0.575, 0.565, 1); } .oo-ui-textInputWidget.oo-ui-widget-enabled input:focus, .oo-ui-textInputWidget.oo-ui-widget-enabled textarea:focus { @@ -2135,6 +2144,42 @@ margin: 0.5em 0 0.5em 0.5em; opacity: 0.2; } +.oo-ui-tabSelectWidget { + text-align: left; + white-space: nowrap; + overflow: hidden; + background-color: #dddddd; +} +.oo-ui-tabOptionWidget { + display: inline-block; + vertical-align: bottom; + padding: 0.35em 1em; + margin: 0.5em 0 0 0.75em; + border: 1px solid transparent; + border-bottom: none; + border-top-left-radius: 2px; + border-top-right-radius: 2px; + color: #666666; + font-weight: bold; +} +.oo-ui-tabOptionWidget:hover { + background-color: rgba(255, 255, 255, 0.3); +} +.oo-ui-tabOptionWidget:active { + background-color: rgba(255, 255, 255, 0.8); +} +.oo-ui-tabOptionWidget.oo-ui-indicatorElement .oo-ui-labelElement-label { + padding-right: 1.5em; +} +.oo-ui-tabOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator { + opacity: 0.5; +} +.oo-ui-selectWidget-pressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected, +.oo-ui-selectWidget-depressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected, +.oo-ui-tabOptionWidget.oo-ui-optionWidget-selected:hover { + background-color: #ffffff; + color: #333333; +} .oo-ui-comboBoxWidget { display: inline-block; position: relative; diff --git a/resources/lib/oojs-ui/oojs-ui-mediawiki.js b/resources/lib/oojs-ui/oojs-ui-mediawiki.js index dbbd8f5d02..b013b1a9d5 100644 --- a/resources/lib/oojs-ui/oojs-ui-mediawiki.js +++ b/resources/lib/oojs-ui/oojs-ui-mediawiki.js @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.11.0 + * OOjs UI v0.11.1 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2015 OOjs Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2015-04-30T01:42:23Z + * Date: 2015-05-05T00:40:50Z */ /** * @class diff --git a/resources/lib/oojs-ui/oojs-ui.js b/resources/lib/oojs-ui/oojs-ui.js index 6dd1b62b3e..f6d6128d77 100644 --- a/resources/lib/oojs-ui/oojs-ui.js +++ b/resources/lib/oojs-ui/oojs-ui.js @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.11.0 + * OOjs UI v0.11.1 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2015 OOjs Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2015-04-30T01:42:23Z + * Date: 2015-05-05T00:40:50Z */ ( function ( OO ) { @@ -150,6 +150,38 @@ OO.ui.contains = function ( containers, contained, matchContainers ) { return false; }; +/** + * Return a function, that, as long as it continues to be invoked, will not + * be triggered. The function will be called after it stops being called for + * N milliseconds. If `immediate` is passed, trigger the function on the + * leading edge, instead of the trailing. + * + * Ported from: http://underscorejs.org/underscore.js + * + * @param {Function} func + * @param {number} wait + * @param {boolean} immediate + * @return {Function} + */ +OO.ui.debounce = function ( func, wait, immediate ) { + var timeout; + return function () { + var context = this, + args = arguments, + later = function () { + timeout = null; + if ( !immediate ) { + func.apply( context, args ); + } + }; + if ( immediate && !timeout ) { + func.apply( context, args ); + } + clearTimeout( timeout ); + timeout = setTimeout( later, wait ); + }; +}; + /** * Reconstitute a JavaScript object corresponding to a widget created by * the PHP implementation. @@ -5338,9 +5370,9 @@ OO.ui.IndicatorElement.prototype.getIndicatorTitle = function () { * @param {Object} [config] Configuration options * @cfg {jQuery} [$label] The label element created by the class. If this * configuration is omitted, the label element will use a generated ``. - * @cfg {jQuery|string|Function} [label] The label text. The label can be specified as a plaintext string, - * a jQuery selection of elements, or a function that will produce a string in the future. See the - * [OOjs UI documentation on MediaWiki] [2] for examples. + * @cfg {jQuery|string|Function|OO.ui.HtmlSnippet} [label] The label text. The label can be specified + * as a plaintext string, a jQuery selection of elements, or a function that will produce a string + * in the future. See the [OOjs UI documentation on MediaWiki] [2] for examples. * [2]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Labels * @cfg {boolean} [autoFitLabel=true] Fit the label to the width of the parent element. * The label will be truncated to fit if necessary. @@ -9094,7 +9126,7 @@ OO.ui.BookletLayout.prototype.setPage = function ( name ) { if ( this.outlined ) { selectedItem = this.outlineSelectWidget.getSelectedItem(); if ( selectedItem && selectedItem.getData() !== name ) { - this.outlineSelectWidget.selectItem( this.outlineSelectWidget.getItemFromData( name ) ); + this.outlineSelectWidget.selectItemByData( name ); } } if ( page ) { @@ -9131,6 +9163,459 @@ OO.ui.BookletLayout.prototype.selectFirstSelectablePage = function () { return this; }; +/** + * IndexLayouts contain {@link OO.ui.CardLayout card layouts} as well as + * {@link OO.ui.TabSelectWidget tabs} that allow users to easily navigate through the cards and + * select which one to display. By default, only one card is displayed at a time. When a user + * navigates to a new card, the index layout automatically focuses on the first focusable element, + * unless the default setting is changed. + * + * TODO: This class is similar to BookletLayout, we may want to refactor to reduce duplication + * + * @example + * // Example of a IndexLayout that contains two CardLayouts. + * + * function CardOneLayout( name, config ) { + * CardOneLayout.super.call( this, name, config ); + * this.$element.append( '

First card

' ); + * } + * OO.inheritClass( CardOneLayout, OO.ui.CardLayout ); + * CardOneLayout.prototype.setupTabItem = function () { + * this.tabItem.setLabel( 'Card One' ); + * }; + * + * function CardTwoLayout( name, config ) { + * CardTwoLayout.super.call( this, name, config ); + * this.$element.append( '

Second card

' ); + * } + * OO.inheritClass( CardTwoLayout, OO.ui.CardLayout ); + * CardTwoLayout.prototype.setupTabItem = function () { + * this.tabItem.setLabel( 'Card Two' ); + * }; + * + * var card1 = new CardOneLayout( 'one' ), + * card2 = new CardTwoLayout( 'two' ); + * + * var index = new OO.ui.IndexLayout(); + * + * index.addCards ( [ card1, card2 ] ); + * $( 'body' ).append( index.$element ); + * + * @class + * @extends OO.ui.MenuLayout + * + * @constructor + * @param {Object} [config] Configuration options + * @cfg {boolean} [continuous=false] Show all cards, one after another + * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when a new card is displayed. + */ +OO.ui.IndexLayout = function OoUiIndexLayout( config ) { + // Configuration initialization + config = $.extend( {}, config, { menuPosition: 'top' } ); + + // Parent constructor + OO.ui.IndexLayout.super.call( this, config ); + + // Properties + this.currentCardName = null; + this.cards = {}; + this.ignoreFocus = false; + this.stackLayout = new OO.ui.StackLayout( { continuous: !!config.continuous } ); + this.$content.append( this.stackLayout.$element ); + this.autoFocus = config.autoFocus === undefined || !!config.autoFocus; + + this.tabSelectWidget = new OO.ui.TabSelectWidget(); + this.tabPanel = new OO.ui.PanelLayout(); + this.$menu.append( this.tabPanel.$element ); + + this.toggleMenu( true ); + + // Events + this.stackLayout.connect( this, { set: 'onStackLayoutSet' } ); + this.tabSelectWidget.connect( this, { select: 'onTabSelectWidgetSelect' } ); + if ( this.autoFocus ) { + // Event 'focus' does not bubble, but 'focusin' does + this.stackLayout.$element.on( 'focusin', this.onStackLayoutFocus.bind( this ) ); + } + + // Initialization + this.$element.addClass( 'oo-ui-indexLayout' ); + this.stackLayout.$element.addClass( 'oo-ui-indexLayout-stackLayout' ); + this.tabPanel.$element + .addClass( 'oo-ui-indexLayout-tabPanel' ) + .append( this.tabSelectWidget.$element ); +}; + +/* Setup */ + +OO.inheritClass( OO.ui.IndexLayout, OO.ui.MenuLayout ); + +/* Events */ + +/** + * A 'set' event is emitted when a card is {@link #setCard set} to be displayed by the index layout. + * @event set + * @param {OO.ui.CardLayout} card Current card + */ + +/** + * An 'add' event is emitted when cards are {@link #addCards added} to the index layout. + * + * @event add + * @param {OO.ui.CardLayout[]} card Added cards + * @param {number} index Index cards were added at + */ + +/** + * A 'remove' event is emitted when cards are {@link #clearCards cleared} or + * {@link #removeCards removed} from the index. + * + * @event remove + * @param {OO.ui.CardLayout[]} cards Removed cards + */ + +/* Methods */ + +/** + * Handle stack layout focus. + * + * @private + * @param {jQuery.Event} e Focusin event + */ +OO.ui.IndexLayout.prototype.onStackLayoutFocus = function ( e ) { + var name, $target; + + // Find the card that an element was focused within + $target = $( e.target ).closest( '.oo-ui-cardLayout' ); + for ( name in this.cards ) { + // Check for card match, exclude current card to find only card changes + if ( this.cards[ name ].$element[ 0 ] === $target[ 0 ] && name !== this.currentCardName ) { + this.setCard( name ); + break; + } + } +}; + +/** + * Handle stack layout set events. + * + * @private + * @param {OO.ui.PanelLayout|null} card The card panel that is now the current panel + */ +OO.ui.IndexLayout.prototype.onStackLayoutSet = function ( card ) { + var layout = this; + if ( card ) { + card.scrollElementIntoView( { complete: function () { + if ( layout.autoFocus ) { + layout.focus(); + } + } } ); + } +}; + +/** + * Focus the first input in the current card. + * + * If no card is selected, the first selectable card will be selected. + * If the focus is already in an element on the current card, nothing will happen. + * @param {number} [itemIndex] A specific item to focus on + */ +OO.ui.IndexLayout.prototype.focus = function ( itemIndex ) { + var $input, card, + items = this.stackLayout.getItems(); + + if ( itemIndex !== undefined && items[ itemIndex ] ) { + card = items[ itemIndex ]; + } else { + card = this.stackLayout.getCurrentItem(); + } + + if ( !card ) { + this.selectFirstSelectableCard(); + card = this.stackLayout.getCurrentItem(); + } + if ( !card ) { + return; + } + // Only change the focus if is not already in the current card + if ( !card.$element.find( ':focus' ).length ) { + $input = card.$element.find( ':input:first' ); + if ( $input.length ) { + $input[ 0 ].focus(); + } + } +}; + +/** + * Find the first focusable input in the index layout and focus + * on it. + */ +OO.ui.IndexLayout.prototype.focusFirstFocusable = function () { + var i, len, + found = false, + items = this.stackLayout.getItems(), + checkAndFocus = function () { + if ( OO.ui.isFocusableElement( $( this ) ) ) { + $( this ).focus(); + found = true; + return false; + } + }; + + for ( i = 0, len = items.length; i < len; i++ ) { + if ( found ) { + break; + } + // Find all potentially focusable elements in the item + // and check if they are focusable + items[i].$element + .find( 'input, select, textarea, button, object' ) + .each( checkAndFocus ); + } +}; + +/** + * Handle tab widget select events. + * + * @private + * @param {OO.ui.OptionWidget|null} item Selected item + */ +OO.ui.IndexLayout.prototype.onTabSelectWidgetSelect = function ( item ) { + if ( item ) { + this.setCard( item.getData() ); + } +}; + +/** + * Get the card closest to the specified card. + * + * @param {OO.ui.CardLayout} card Card to use as a reference point + * @return {OO.ui.CardLayout|null} Card closest to the specified card + */ +OO.ui.IndexLayout.prototype.getClosestCard = function ( card ) { + var next, prev, level, + cards = this.stackLayout.getItems(), + index = $.inArray( card, cards ); + + if ( index !== -1 ) { + next = cards[ index + 1 ]; + prev = cards[ index - 1 ]; + // Prefer adjacent cards at the same level + level = this.tabSelectWidget.getItemFromData( card.getName() ).getLevel(); + if ( + prev && + level === this.tabSelectWidget.getItemFromData( prev.getName() ).getLevel() + ) { + return prev; + } + if ( + next && + level === this.tabSelectWidget.getItemFromData( next.getName() ).getLevel() + ) { + return next; + } + } + return prev || next || null; +}; + +/** + * Get the tabs widget. + * + * @return {OO.ui.TabSelectWidget} Tabs widget + */ +OO.ui.IndexLayout.prototype.getTabs = function () { + return this.tabSelectWidget; +}; + +/** + * Get a card by its symbolic name. + * + * @param {string} name Symbolic name of card + * @return {OO.ui.CardLayout|undefined} Card, if found + */ +OO.ui.IndexLayout.prototype.getCard = function ( name ) { + return this.cards[ name ]; +}; + +/** + * Get the current card. + * + * @return {OO.ui.CardLayout|undefined} Current card, if found + */ +OO.ui.IndexLayout.prototype.getCurrentCard = function () { + var name = this.getCurrentCardName(); + return name ? this.getCard( name ) : undefined; +}; + +/** + * Get the symbolic name of the current card. + * + * @return {string|null} Symbolic name of the current card + */ +OO.ui.IndexLayout.prototype.getCurrentCardName = function () { + return this.currentCardName; +}; + +/** + * Add cards to the index layout + * + * When cards are added with the same names as existing cards, the existing cards will be + * automatically removed before the new cards are added. + * + * @param {OO.ui.CardLayout[]} cards Cards to add + * @param {number} index Index of the insertion point + * @fires add + * @chainable + */ +OO.ui.IndexLayout.prototype.addCards = function ( cards, index ) { + var i, len, name, card, item, currentIndex, + stackLayoutCards = this.stackLayout.getItems(), + remove = [], + items = []; + + // Remove cards with same names + for ( i = 0, len = cards.length; i < len; i++ ) { + card = cards[ i ]; + name = card.getName(); + + if ( Object.prototype.hasOwnProperty.call( this.cards, name ) ) { + // Correct the insertion index + currentIndex = $.inArray( this.cards[ name ], stackLayoutCards ); + if ( currentIndex !== -1 && currentIndex + 1 < index ) { + index--; + } + remove.push( this.cards[ name ] ); + } + } + if ( remove.length ) { + this.removeCards( remove ); + } + + // Add new cards + for ( i = 0, len = cards.length; i < len; i++ ) { + card = cards[ i ]; + name = card.getName(); + this.cards[ card.getName() ] = card; + item = new OO.ui.TabOptionWidget( { data: name } ); + card.setTabItem( item ); + items.push( item ); + } + + if ( items.length ) { + this.tabSelectWidget.addItems( items, index ); + this.selectFirstSelectableCard(); + } + this.stackLayout.addItems( cards, index ); + this.emit( 'add', cards, index ); + + return this; +}; + +/** + * Remove the specified cards from the index layout. + * + * To remove all cards from the index, you may wish to use the #clearCards method instead. + * + * @param {OO.ui.CardLayout[]} cards An array of cards to remove + * @fires remove + * @chainable + */ +OO.ui.IndexLayout.prototype.removeCards = function ( cards ) { + var i, len, name, card, + items = []; + + for ( i = 0, len = cards.length; i < len; i++ ) { + card = cards[ i ]; + name = card.getName(); + delete this.cards[ name ]; + items.push( this.tabSelectWidget.getItemFromData( name ) ); + card.setTabItem( null ); + } + if ( items.length ) { + this.tabSelectWidget.removeItems( items ); + this.selectFirstSelectableCard(); + } + this.stackLayout.removeItems( cards ); + this.emit( 'remove', cards ); + + return this; +}; + +/** + * Clear all cards from the index layout. + * + * To remove only a subset of cards from the index, use the #removeCards method. + * + * @fires remove + * @chainable + */ +OO.ui.IndexLayout.prototype.clearCards = function () { + var i, len, + cards = this.stackLayout.getItems(); + + this.cards = {}; + this.currentCardName = null; + this.tabSelectWidget.clearItems(); + for ( i = 0, len = cards.length; i < len; i++ ) { + cards[ i ].setTabItem( null ); + } + this.stackLayout.clearItems(); + + this.emit( 'remove', cards ); + + return this; +}; + +/** + * Set the current card by symbolic name. + * + * @fires set + * @param {string} name Symbolic name of card + */ +OO.ui.IndexLayout.prototype.setCard = function ( name ) { + var selectedItem, + $focused, + card = this.cards[ name ]; + + if ( name !== this.currentCardName ) { + selectedItem = this.tabSelectWidget.getSelectedItem(); + if ( selectedItem && selectedItem.getData() !== name ) { + this.tabSelectWidget.selectItemByData( name ); + } + if ( card ) { + if ( this.currentCardName && this.cards[ this.currentCardName ] ) { + this.cards[ this.currentCardName ].setActive( false ); + // Blur anything focused if the next card doesn't have anything focusable - this + // is not needed if the next card has something focusable because once it is focused + // this blur happens automatically + if ( this.autoFocus && !card.$element.find( ':input' ).length ) { + $focused = this.cards[ this.currentCardName ].$element.find( ':focus' ); + if ( $focused.length ) { + $focused[ 0 ].blur(); + } + } + } + this.currentCardName = name; + this.stackLayout.setItem( card ); + card.setActive( true ); + this.emit( 'set', card ); + } + } +}; + +/** + * Select the first selectable card. + * + * @chainable + */ +OO.ui.IndexLayout.prototype.selectFirstSelectableCard = function () { + if ( !this.tabSelectWidget.getSelectedItem() ) { + this.tabSelectWidget.selectItem( this.tabSelectWidget.getFirstSelectableItem() ); + } + + return this; +}; + /** * PanelLayouts expand to cover the entire area of their parent. They can be configured with scrolling, padding, * and a frame, and are often used together with {@link OO.ui.StackLayout StackLayouts}. @@ -9187,6 +9672,145 @@ OO.ui.PanelLayout = function OoUiPanelLayout( config ) { OO.inheritClass( OO.ui.PanelLayout, OO.ui.Layout ); +/** + * CardLayouts are used within {@link OO.ui.IndexLayout index layouts} to create cards that users can select and display + * from the index's optional {@link OO.ui.TabSelectWidget tab} navigation. Cards are usually not instantiated directly, + * rather extended to include the required content and functionality. + * + * Each card must have a unique symbolic name, which is passed to the constructor. In addition, the card's tab + * item is customized (with a label) using the #setupTabItem method. See + * {@link OO.ui.IndexLayout IndexLayout} for an example. + * + * @class + * @extends OO.ui.PanelLayout + * + * @constructor + * @param {string} name Unique symbolic name of card + * @param {Object} [config] Configuration options + */ +OO.ui.CardLayout = function OoUiCardLayout( name, config ) { + // Allow passing positional parameters inside the config object + if ( OO.isPlainObject( name ) && config === undefined ) { + config = name; + name = config.name; + } + + // Configuration initialization + config = $.extend( { scrollable: true }, config ); + + // Parent constructor + OO.ui.CardLayout.super.call( this, config ); + + // Properties + this.name = name; + this.tabItem = null; + this.active = false; + + // Initialization + this.$element.addClass( 'oo-ui-cardLayout' ); +}; + +/* Setup */ + +OO.inheritClass( OO.ui.CardLayout, OO.ui.PanelLayout ); + +/* Events */ + +/** + * An 'active' event is emitted when the card becomes active. Cards become active when they are + * shown in a index layout that is configured to display only one card at a time. + * + * @event active + * @param {boolean} active Card is active + */ + +/* Methods */ + +/** + * Get the symbolic name of the card. + * + * @return {string} Symbolic name of card + */ +OO.ui.CardLayout.prototype.getName = function () { + return this.name; +}; + +/** + * Check if card is active. + * + * Cards become active when they are shown in a {@link OO.ui.IndexLayout index layout} that is configured to display + * only one card at a time. Additional CSS is applied to the card's tab item to reflect the active state. + * + * @return {boolean} Card is active + */ +OO.ui.CardLayout.prototype.isActive = function () { + return this.active; +}; + +/** + * Get tab item. + * + * The tab item allows users to access the card from the index's tab + * navigation. The tab item itself can be customized (with a label, level, etc.) using the #setupTabItem method. + * + * @return {OO.ui.TabOptionWidget|null} Tab option widget + */ +OO.ui.CardLayout.prototype.getTabItem = function () { + return this.tabItem; +}; + +/** + * Set or unset the tab item. + * + * Specify a {@link OO.ui.TabOptionWidget tab option} to set it, + * or `null` to clear the tab item. To customize the tab item itself (e.g., to set a label or tab + * level), use #setupTabItem instead of this method. + * + * @param {OO.ui.TabOptionWidget|null} tabItem Tab option widget, null to clear + * @chainable + */ +OO.ui.CardLayout.prototype.setTabItem = function ( tabItem ) { + this.tabItem = tabItem || null; + if ( tabItem ) { + this.setupTabItem(); + } + return this; +}; + +/** + * Set up the tab item. + * + * Use this method to customize the tab item (e.g., to add a label or tab level). To set or unset + * the tab item itself (with a {@link OO.ui.TabOptionWidget tab option} or `null`), use + * the #setTabItem method instead. + * + * @param {OO.ui.TabOptionWidget} tabItem Tab option widget to set up + * @chainable + */ +OO.ui.CardLayout.prototype.setupTabItem = function () { + return this; +}; + +/** + * Set the card to its 'active' state. + * + * Cards become active when they are shown in a index layout that is configured to display only one card at a time. Additional + * CSS is applied to the tab item to reflect the card's active state. Outside of the index + * context, setting the active state on a card does nothing. + * + * @param {boolean} value Card is active + * @fires active + */ +OO.ui.CardLayout.prototype.setActive = function ( active ) { + active = !!active; + + if ( active !== this.active ) { + this.active = active; + this.$element.toggleClass( 'oo-ui-cardLayout-active', this.active ); + this.emit( 'active', this.active ); + } +}; + /** * PageLayouts are used within {@link OO.ui.BookletLayout booklet layouts} to create pages that users can select and display * from the booklet's optional {@link OO.ui.OutlineSelectWidget outline} navigation. Pages are usually not instantiated directly, @@ -10209,7 +10833,7 @@ OO.ui.ItemWidget.prototype.setElementGroup = function ( group ) { /** * OutlineControlsWidget is a set of controls for an {@link OO.ui.OutlineSelectWidget outline select widget}. * Controls include moving items up and down, removing items, and adding different kinds of items. - * ####Currently, this class is only used by {@link OO.ui.BookletLayout BookletLayouts}.#### + * ####Currently, this class is only used by {@link OO.ui.BookletLayout booklet layouts}.#### * * @class * @extends OO.ui.Widget @@ -10899,7 +11523,7 @@ OO.ui.ActionWidget.prototype.toggle = function () { * popup: { * $content: $( '

Additional options here.

' ), * padded: true, - * align: 'left' + * align: 'force-left' * } * } ); * // Append the button to the DOM. @@ -11834,10 +12458,7 @@ OO.ui.DropdownInputWidget.prototype.onMenuSelect = function ( item ) { * @inheritdoc */ OO.ui.DropdownInputWidget.prototype.setValue = function ( value ) { - var item = this.dropdownWidget.getMenu().getItemFromData( value ); - if ( item ) { - this.dropdownWidget.getMenu().selectItem( item ); - } + this.dropdownWidget.getMenu().selectItemByData( value ); OO.ui.DropdownInputWidget.super.prototype.setValue.call( this, value ); return this; }; @@ -12089,6 +12710,7 @@ OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) { this.$icon.on( 'mousedown', this.onIconMouseDown.bind( this ) ); this.$indicator.on( 'mousedown', this.onIndicatorMouseDown.bind( this ) ); this.on( 'labelChange', this.updatePosition.bind( this ) ); + this.connect( this, { change: 'onChange' } ); // Initialization this.$element @@ -12105,7 +12727,7 @@ OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) { this.$input.attr( 'autofocus', 'autofocus' ); } if ( config.required ) { - this.$input.attr( 'required', 'true' ); + this.$input.attr( 'required', 'required' ); } if ( this.label || config.autosize ) { this.installParentChangeDetector(); @@ -12194,25 +12816,14 @@ OO.ui.TextInputWidget.prototype.onElementAttach = function () { }; /** - * @inheritdoc - */ -OO.ui.TextInputWidget.prototype.onEdit = function () { - this.adjustSize(); - - // Parent method - return OO.ui.TextInputWidget.super.prototype.onEdit.call( this ); -}; - -/** - * @inheritdoc + * Handle change events. + * + * @param {string} value + * @private */ -OO.ui.TextInputWidget.prototype.setValue = function ( value ) { - // Parent method - OO.ui.TextInputWidget.super.prototype.setValue.call( this, value ); - +OO.ui.TextInputWidget.prototype.onChange = function () { this.setValidityFlag(); this.adjustSize(); - return this; }; /** @@ -12418,6 +13029,11 @@ OO.ui.TextInputWidget.prototype.setValidation = function ( validate ) { OO.ui.TextInputWidget.prototype.setValidityFlag = function () { var widget = this; this.isValid().done( function ( valid ) { + if ( !valid ) { + widget.$input.attr( 'aria-invalid', 'true' ); + } else { + widget.$input.removeAttr( 'aria-invalid' ); + } widget.setFlags( { invalid: !valid } ); } ); }; @@ -13416,6 +14032,38 @@ OO.ui.OutlineOptionWidget.prototype.setLevel = function ( level ) { return this; }; +/** + * TabOptionWidget is an item in a {@link OO.ui.TabSelectWidget TabSelectWidget}. + * + * Currently, this class is only used by {@link OO.ui.IndexLayout index layouts}, which contain + * {@link OO.ui.CardLayout card layouts}. See {@link OO.ui.IndexLayout IndexLayout} + * for an example. + * + * @class + * @extends OO.ui.OptionWidget + * + * @constructor + * @param {Object} [config] Configuration options + */ +OO.ui.TabOptionWidget = function OoUiTabOptionWidget( config ) { + // Configuration initialization + config = config || {}; + + // Parent constructor + OO.ui.TabOptionWidget.super.call( this, config ); + + // Initialization + this.$element.addClass( 'oo-ui-tabOptionWidget' ); +}; + +/* Setup */ + +OO.inheritClass( OO.ui.TabOptionWidget, OO.ui.OptionWidget ); + +/* Static Properties */ + +OO.ui.TabOptionWidget.static.highlightable = false; + /** * PopupWidget is a container for content. The popup is overlaid and positioned absolutely. * By default, each popup has an anchor that points toward its origin. @@ -14484,6 +15132,22 @@ OO.ui.SelectWidget.prototype.highlightItem = function ( item ) { return this; }; +/** + * Programmatically select an option by its data. If the `data` parameter is omitted, + * or if the item does not exist, all options will be deselected. + * + * @param {Object|string} [data] Value of the item to select, omit to deselect all + * @fires select + * @chainable + */ +OO.ui.SelectWidget.prototype.selectItemByData = function ( data ) { + var itemFromData = this.getItemFromData( data ); + if ( data === undefined || !itemFromData ) { + return this.selectItem(); + } + return this.selectItem( itemFromData ); +}; + /** * Programmatically select an option by its reference. If the `item` parameter is omitted, * all options will be deselected. @@ -15167,7 +15831,7 @@ OO.ui.TextInputMenuSelectWidget.prototype.position = function () { * OutlineSelectWidget is a structured list that contains {@link OO.ui.OutlineOptionWidget outline options} * A set of controls can be provided with an {@link OO.ui.OutlineControlsWidget outline controls} widget. * - * ####Currently, this class is only used by {@link OO.ui.BookletLayout BookletLayouts}.#### + * ####Currently, this class is only used by {@link OO.ui.BookletLayout booklet layouts}.#### * * @class * @extends OO.ui.SelectWidget @@ -15198,6 +15862,40 @@ OO.ui.OutlineSelectWidget = function OoUiOutlineSelectWidget( config ) { OO.inheritClass( OO.ui.OutlineSelectWidget, OO.ui.SelectWidget ); OO.mixinClass( OO.ui.OutlineSelectWidget, OO.ui.TabIndexedElement ); +/** + * TabSelectWidget is a list that contains {@link OO.ui.TabOptionWidget tab options} + * + * ####Currently, this class is only used by {@link OO.ui.IndexLayout index layouts}.#### + * + * @class + * @extends OO.ui.SelectWidget + * @mixins OO.ui.TabIndexedElement + * + * @constructor + * @param {Object} [config] Configuration options + */ +OO.ui.TabSelectWidget = function OoUiTabSelectWidget( config ) { + // Parent constructor + OO.ui.TabSelectWidget.super.call( this, config ); + + // Mixin constructors + OO.ui.TabIndexedElement.call( this, config ); + + // Events + this.$element.on( { + focus: this.bindKeyDownListener.bind( this ), + blur: this.unbindKeyDownListener.bind( this ) + } ); + + // Initialization + this.$element.addClass( 'oo-ui-tabSelectWidget' ); +}; + +/* Setup */ + +OO.inheritClass( OO.ui.TabSelectWidget, OO.ui.SelectWidget ); +OO.mixinClass( OO.ui.TabSelectWidget, OO.ui.TabIndexedElement ); + /** * ToggleSwitches are switches that slide on and off. Their state is represented by a Boolean * value (`true` for ‘on’, and `false` otherwise, the default). The ‘off’ state is represented diff --git a/resources/lib/oojs-ui/themes/mediawiki/icons-interactions.json b/resources/lib/oojs-ui/themes/mediawiki/icons-interactions.json index 3c8376b6cc..497a3014d2 100644 --- a/resources/lib/oojs-ui/themes/mediawiki/icons-interactions.json +++ b/resources/lib/oojs-ui/themes/mediawiki/icons-interactions.json @@ -12,8 +12,8 @@ "ltr": "images/icons/browser-ltr.svg", "rtl": "images/icons/browser-rtl.svg" } }, + "clear": { "file": "images/icons/clear.svg" }, "clock": { "file": "images/icons/clock.svg" }, - "closeInput": { "file": "images/icons/closeInput.svg" }, "funnel": { "file": { "ltr": "images/icons/funnel-ltr.svg", "rtl": "images/icons/funnel-rtl.svg" @@ -31,10 +31,6 @@ "ltr": "images/icons/logOut-ltr.svg", "rtl": "images/icons/logOut-rtl.svg" } }, - "magnifyingGlass": { "file": { - "ltr": "images/icons/magnifyingGlass-ltr.svg", - "rtl": "images/icons/magnifyingGlass-rtl.svg" - } }, "newWindow": { "file": { "ltr": "images/icons/newWindow-ltr.svg", "rtl": "images/icons/newWindow-rtl.svg" diff --git a/resources/lib/oojs-ui/themes/mediawiki/icons-moderation.json b/resources/lib/oojs-ui/themes/mediawiki/icons-moderation.json index 36c8777f28..1f12f2ae2b 100644 --- a/resources/lib/oojs-ui/themes/mediawiki/icons-moderation.json +++ b/resources/lib/oojs-ui/themes/mediawiki/icons-moderation.json @@ -20,7 +20,7 @@ } }, "images": { - "block": { "file": "images/icons/block.svg" }, + "block": { "file": "images/icons/block.svg", "variants": [ "destructive" ] }, "blockUndo": { "file": { "ltr": "images/icons/blockUndo-ltr.svg", "rtl": "images/icons/blockUndo-rtl.svg" diff --git a/resources/lib/oojs-ui/themes/mediawiki/icons.json b/resources/lib/oojs-ui/themes/mediawiki/icons.json index 6d8e4ad5e3..948ae6c7d6 100644 --- a/resources/lib/oojs-ui/themes/mediawiki/icons.json +++ b/resources/lib/oojs-ui/themes/mediawiki/icons.json @@ -24,9 +24,9 @@ "add": { "file": "images/icons/add.svg", "variants": [ "constructive" ] }, "advanced": { "file": "images/icons/advanced.svg" }, "alert": { "file": "images/icons/alert.svg", "variants": [ "warning" ] }, + "cancel": { "file": "images/icons/cancel.svg" }, "check": { "file": "images/icons/check.svg", "variants": [ "constructive", "progressive" ] }, "circle": { "file": "images/icons/circle.svg", "variants": [ "constructive" ] }, - "clear": { "file": "images/icons/clear.svg" }, "close": { "file": { "ltr": "images/icons/close-ltr.svg", "rtl": "images/icons/close-rtl.svg" @@ -60,7 +60,10 @@ "rtl": "images/icons/arched-arrow-rtl.svg" } }, "remove": { "file": "images/icons/remove.svg", "variants": [ "destructive" ] }, - "search": { "file": "images/icons/search.svg" }, + "search": { "file": { + "ltr": "images/icons/search-ltr.svg", + "rtl": "images/icons/search-rtl.svg" + } }, "settings": { "file": "images/icons/settings.svg" }, "tag": { "file": "images/icons/tag.svg" }, "undo": { "file": { diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/block-destructive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/block-destructive.png new file mode 100644 index 0000000000000000000000000000000000000000..3e919971ac73365cf5cbb58398f2ad9c35966cac GIT binary patch literal 461 zcmV;;0W$uHP)KlDkd($BfNqEjMauqgp$am5#!ES2uAn9?iv#<_{y2H=giFh zz>dF$`~FZPyl)6cDCEwDKNkSff1dFk4+7kcTG@uv9R z>nvU{AWAI57|(iN>y8bWtV&q(wGjzX*`;oSq!8A8g9wWDTGU=(RvER9HJ+w{Ht8H4 z$VUQY?LF6@{F^v7P>P3u%6*$GAOz|={2VH#Rv1&8o8wzY0D&6}gqj=x7+?rDeFO57 zS(hO7umK9VJ{>4itIlbmU;w1`#`$j!EMF~9(>qS~}{ z{D@aKjqf|}9PXb8QCS4V%{wPh9||o9H{H&% + + + diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/clear-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/cancel-invert.png similarity index 100% rename from resources/lib/oojs-ui/themes/mediawiki/images/icons/clear-invert.png rename to resources/lib/oojs-ui/themes/mediawiki/images/icons/cancel-invert.png diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/clear-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/cancel-invert.svg similarity index 96% rename from resources/lib/oojs-ui/themes/mediawiki/images/icons/clear-invert.svg rename to resources/lib/oojs-ui/themes/mediawiki/images/icons/cancel-invert.svg index 6d3bc588f8..8a9d3d4d2a 100644 --- a/resources/lib/oojs-ui/themes/mediawiki/images/icons/clear-invert.svg +++ b/resources/lib/oojs-ui/themes/mediawiki/images/icons/cancel-invert.svg @@ -1,6 +1,6 @@ - + diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/cancel.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/cancel.png new file mode 100644 index 0000000000000000000000000000000000000000..51a33ff8019bdf3d6542eb7bac51d0accba22bc2 GIT binary patch literal 351 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ za0`PlBg3pYKpl*Xo-U3d9-VJ5dwVfEinu+@*I<#!;F!s>NkLxYkxK!$o`Yb`8IkLc z#X>HuapF0)#beIaZOyx!gqr33Da^VN2C{>$uJ zAU=5(<6O0uZtv~f4Gwv)ou?}K$Ts|f{BLvLPg-*i->KvZNayo(-j!Q!+4Q*~#`i_9 z_qRvCRopL3`nKiBH6G7a^EJ;o62hxomX?U_-g-}qk2x;MSUhgJ$kwTRhAXZz=ll`< uH+$Ka4!I?{+Dn*ikKJ1IA@!eQ9Yg8%aMd8Dd+UKA#Ng@b=d#Wzp$P!xq=q;E literal 0 HcmV?d00001 diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/cancel.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/cancel.svg new file mode 100644 index 0000000000..bfc1b44baf --- /dev/null +++ b/resources/lib/oojs-ui/themes/mediawiki/images/icons/cancel.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/clear.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/clear.png index 51a33ff8019bdf3d6542eb7bac51d0accba22bc2..b18e2e689da3721a513af25386ab445dfd58eda0 100644 GIT binary patch delta 252 zcmVOQVACo3wi7jfJqibxicm({49U8PfZcyRn9{A4yIQJp0 zDb{WT{N}0@zVx>(tLPk<*Bi`p*i%Qq2WDAqg>`bjjB;_0000YSn;EVB&SxI_=17~v6TXe|og#|J8W z;Tip?D-_sS1pXbM12k&A4z5v#I9t-Lt-Qi5Rwj(w4oQJ#j(^}Hz()a}Cb^0JX^x;5 zlbQjYCh11+K1VRZORb(I8R9)x&>#CZP4X(8!`yiaP-hNFL%MBuIfC - - - + + + diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/closeInput.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/closeInput.png deleted file mode 100644 index b18e2e689da3721a513af25386ab445dfd58eda0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 316 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ za0`PlBg3pYARYHST^vI^I^SM#%sXTt((E89}vC8b|g~ZmF|in;fM(v zHcX7s?vx2Am&{!9MDySA%1-&oYKfh?S#uU==WM88`O_sUwZ%3s;NerbALkh?zALWN zyq3rE=h-TeeP6cgu6`jij;v2#42iVghb6ZP`_V;ZKG2SzMkK^6Vx1$59=GuRc z7AklbF{ACv!RR?f5#incV*9teh!EN!*}#7_s%9#S&YkbG<35B5Iart^^WRF>oMRBp zr~IJWrk_*c%(PP-@a}K;gvT>FVdQ I&MBb@0BTZzIRF3v diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/closeInput.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/closeInput.svg deleted file mode 100644 index 5d29e3c86c..0000000000 --- a/resources/lib/oojs-ui/themes/mediawiki/images/icons/closeInput.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/magnifyingGlass-ltr.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/magnifyingGlass-ltr.png deleted file mode 100644 index 6f06dfe9ca8fb769697e930346098a51bc7bad30..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 380 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ za0`PlBg3pYKpl*7o-U3d9-VJ5+j==Wim*QLXYDoPnx?q>f|^#EGFx__piWM3R#?L7 z-USgXF%DMQ6FHiqHv}D25b8ERzogPW*=H%c-r?kPw$JC88~=HHesP;w)r)_7NzW$)Q*#$S)<;*J$;7CtMaY9>iUO5AIKe-_~I12 zm!;gc;C(XBuZ1gvnylq_ypL>oIp^8R87q@`<{jDgXgW-HcpP@qK!k5mk5`?)YIp00-^~Ar*H5FaU5+^OnO6@%JMB>gv9{Gqv zN_HO`g737MT$pfY*Sr2jPZlgy@QiCRdf}y(-}1hVQ}yQbIoG+%>Z5Ir%A~2Q&g<0w Xo)D1xD>FeF7<>$#u6{1-oD!M<3ci>1 diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/magnifyingGlass-ltr.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/magnifyingGlass-ltr.svg deleted file mode 100644 index 49e598ce3c..0000000000 --- a/resources/lib/oojs-ui/themes/mediawiki/images/icons/magnifyingGlass-ltr.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/magnifyingGlass-rtl.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/magnifyingGlass-rtl.png deleted file mode 100644 index 358048d7469083c27cc5c10c9d6960a358daaf7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 371 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ za0`PlBg3pYKpl*to-U3d9-VKecxN#=3bgG%dCZ+pp`)VH!EBc6IYpP4?p-JK5<2*g zR0uHd65P{iB<-)bLc)C4i&;L#3ob96Jl9^t*607%(9(;>1=nMzbsgaN(AeCD+ zvLgP-?kge|9zn+r&K7;Y{_iJ6wUfan!WI3qn6xA3%W&Da7tP^1lahP%hs}f7dC&RI z{?TM#V|Y9-uA#moo%x9=t4)H>4@FFd2y#N$pS-- N!PC{xWt~$(697&sinag% diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/magnifyingGlass-rtl.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/magnifyingGlass-rtl.svg deleted file mode 100644 index c9695b69f3..0000000000 --- a/resources/lib/oojs-ui/themes/mediawiki/images/icons/magnifyingGlass-rtl.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/search-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/search-invert.png deleted file mode 100644 index 3e15dafc05391fd36bf6675502d4d7c4e1567557..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 278 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ za0`PlBg3pYARRkAT^vI^I^UjE%wtLvaeZk1U}X~P8wS^=>}Am}q_Q~KI#(Xs#I{OH zYvPVoT0D!UwKU8Wa5}#?!YI>fa*4xV_kGjv=qpY23Qe=#{+II)!~IEay}jO2Oz8=F zFFh|wXyo`yF*cMxSlhDihTV<4>o+q(|5Qg#TkEww)WycdWjkj=uC@N%BG26&H?A@M z^9ho-xE1G7#TM5n{NdyKkJ>2=I*qm;QmeT{4y-YJBL3xL+zGd!=V=~VrStVtr}T@x TdRq7o=m!Q*S3j3^P6 - - - - - diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/search-ltr-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/search-ltr-invert.png new file mode 100644 index 0000000000000000000000000000000000000000..4b6ecd2f760c62d126db9ef96cfbdc09a8f52823 GIT binary patch literal 372 zcmV-)0gL{LP)Klut@RaTJ9wPpMU;)EbgT zq2M-LLbL$Ga1#w0w16--A+#5f8l{c;&S}tn&_JI(Gl=L+ev@<0ckl0C#J_&EB=vzQ zu;4=r;K6q9Tfw%Qz?~}u+}dvL1SrFSrKF+lmhD1PThbMxp71uSx#TU!9f37FRfkbt7fXS(3oT6Dm zzM%0=kcbFLU0?#t^DmkM_rT5GAe&@+{5K$yE`cTRBI#o9fP@^{KKPOFzpr-*NvIA% SW0&>-0000 + + + + + diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/search-ltr.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/search-ltr.png new file mode 100644 index 0000000000000000000000000000000000000000..c10dc664e49013fa929e3e813c826bbfd8e76fb5 GIT binary patch literal 350 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ za0`PlBg3pYKpl(>o-U3d9-VKe_;MXG5NNeu`$9A13s0B!#tYdMEFT%V9;wFc_`tAe zZ!^a|*RFMcA|p#Ca+U>3U)JjQp}?b>f6x7-%7^RQPczpjFgUH$K5$klhT+)(-Nds; zrh8faVc}`un!vv5fPjU&!nIFI4|~<;rLkPv$ok`wg~1QEN71*Km@?N$)R=yJo5Q%! zd(Cx~;FuGRSvMJ0c-_6tWEQlWt>NB%m0d|s7S;XjnKjK~YeV;sTiX}{KCe|& zzS3yrAS>a1XnW=%$GZW%hHE{eI97OXap_IcC}s4y&sn+bq_%)Ma{}*^ial%A)vPy8 tIku|5YI~o<`@0XLR2TeM`9c1=?A0Uwsj_dI0)PR;;OXk;vd$@?2>^2>iNOE> literal 0 HcmV?d00001 diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/search-ltr.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/search-ltr.svg new file mode 100644 index 0000000000..cdcbc30dcf --- /dev/null +++ b/resources/lib/oojs-ui/themes/mediawiki/images/icons/search-ltr.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/search-rtl-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/search-rtl-invert.png new file mode 100644 index 0000000000000000000000000000000000000000..7868dc117b25875a77f76df08b45adab69dd7ec5 GIT binary patch literal 376 zcmV-;0f+vHP)KltD_vKp2Gwo1&MHik`vZ zN>q9buOJ?vQhN#uF1&!Xhv>$$)auUG)%Tv88HlAOOsa^`w@F}LzVDw5NeJ8go7nCF z6JQP~UY{hLZwhV$53UGsZ@b+{kl?^VQeRTXcFXpGq#IzFBu%F8mEgzgI+D6cV*4z2 z`iX5z>R0t74dNiNHCbLI}WfNiv8BT1YyQberJ7C>w5jSoH;$ zzT}bZVk0 + + + + + diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/search-rtl.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/search-rtl.png new file mode 100644 index 0000000000000000000000000000000000000000..dab4ff14ec4fd578d278914b17301b53ba0bcf78 GIT binary patch literal 341 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ za0`PlBg3pYARXU5T^vI^I^SM7?b+-o(fW{G_@bK1B2$fZE~=?Fnj#!jmT@ubU22%6 zv}xlsiMyFGm62z7{58mcvGS5 z&M2>E`Y#r=vTZAD%v4XHHJ)j=3j#y_qj5 zni<6y7v*mj&YpQ}dBk?3n5c)znFlnkUFMno%$<9srIp|`JJGz;HnI;)i`thm7Q}PD zdL{Crq* + + + + + diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/search.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/search.png deleted file mode 100644 index 39d3ab8c50661dfc8868c9d25710b7b7f19f45f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ za0`PlBg3pYARRM2T^vI^I^SMg$mf_Sa^U0r7b^Y_cvWVn?P*F6@D&t|{K})^D3U)} z#Wf(;&Cs~1AboT6JKp)T_r=?!TmLWUShS);uB_s5OW=vevU@f-$S2=1 - - - - - diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-ltr-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-ltr-invert.png new file mode 100644 index 0000000000000000000000000000000000000000..2840bef1f4ab2d3106921a9f1c9b38f2fb9682e9 GIT binary patch literal 251 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&kmSQK*5Dp-y;YjHK@;M7UB8wRq zxP?KOkzv*x383IyPZ!4!jfqqHeYp+=@UT6$Zf7lAST5MVu%n*aJnqctDeJnH3zRxEA;6{}V^$u?G> ztGuK>r{ULR=C!-DBekl2iC9hhEtGcG^LW$T#@SK4e>XD9IdI1`-oAcZS*hq;aOwKI tt6s6?Cl3ete~OO!r>uMR<9Vk@{rY*+Te)_7JOVnD!PC{xWt~$(696;WU3vfj literal 0 HcmV?d00001 diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-ltr-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-ltr-invert.svg new file mode 100644 index 0000000000..f46b1eeb6d --- /dev/null +++ b/resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-ltr-invert.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-ltr.png b/resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-ltr.png new file mode 100644 index 0000000000000000000000000000000000000000..df1c61ed54629f8698e608d37f618792ef768cc5 GIT binary patch literal 231 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&kmSQK*5Dp-y;YjHK@;M7UB8wRq zxP?KOkzv*x37}x7r;B5V#>A=TPjem$5NLgP{>nlHJsyfW=HZ{u2}{%>J8Cr(7tC@B! z5v#P?6Mnxfb8Sd;m+Z?b?Kcu%&%jY + + + + + diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-rtl-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-rtl-invert.png new file mode 100644 index 0000000000000000000000000000000000000000..665a088ba99875803240ea78b7fdf23ed79ed113 GIT binary patch literal 261 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&kmSQK*5Dp-y;YjHK@;M7UB8wRq zxP?KOkzv*x383I|PZ!4!jfqqH9KDzWMOg0lvj;k#NG*9PxXGxk;Yp61T8G{j3CYz~ z-05b|_-C|j*IXqZTbdfhzv}g>suindU%M5Z{np~QW9>8Z_Xh+W?w&oV{lNXMTBh>t zzNMw>H?Z5O?_8zj$!vG!`l?k&=bu}2SnVCF? + + + + + diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-rtl.png b/resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-rtl.png new file mode 100644 index 0000000000000000000000000000000000000000..c9443d79eb3fee596b8d1c5157111473879899b9 GIT binary patch literal 234 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&kmSQK*5Dp-y;YjHK@;M7UB8wRq zxP?KOkzv*x37}w)r;B5V#>A-?tho*ah_pP^FI2Rfu;!3z#7+io?PP%?SGzJ6Zr#C< zeB_XFhuS0`(=&gH^bP0l+XkKl~PpP literal 0 HcmV?d00001 diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-rtl.svg b/resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-rtl.svg new file mode 100644 index 0000000000..5368fd7ccf --- /dev/null +++ b/resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-rtl.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/resources/lib/oojs-ui/themes/mediawiki/indicators.json b/resources/lib/oojs-ui/themes/mediawiki/indicators.json index ced5e79250..d83e57e61f 100644 --- a/resources/lib/oojs-ui/themes/mediawiki/indicators.json +++ b/resources/lib/oojs-ui/themes/mediawiki/indicators.json @@ -20,6 +20,10 @@ "ltr": "images/indicators/arrow-rtl.svg", "rtl": "images/indicators/arrow-ltr.svg" } }, - "required": { "file": "images/indicators/required.svg" } + "required": { "file": "images/indicators/required.svg" }, + "search": { "file": { + "ltr": "images/indicators/search-ltr.svg", + "rtl": "images/indicators/search-rtl.svg" + } } } } -- 2.20.1