From ac5eeba3444fe1a43170d39876406d509b766555 Mon Sep 17 00:00:00 2001 From: Volker E Date: Tue, 6 Feb 2018 17:17:20 -0800 Subject: [PATCH] Update OOUI to v0.25.2 Release notes: https://phabricator.wikimedia.org/diffusion/GOJU/browse/master/History.md;v0.25.2 Depends-on: Ib00f16ef5e74732068822dc10d43314098b8fa59 Change-Id: Ie327a10622b64b7f969283497822c494c513585b --- composer.json | 2 +- resources/lib/oojs-ui/i18n/az.json | 6 +- resources/lib/oojs-ui/i18n/is.json | 4 +- resources/lib/oojs-ui/i18n/lzh.json | 8 +- resources/lib/oojs-ui/oojs-ui-apex.js | 4 +- resources/lib/oojs-ui/oojs-ui-core-apex.css | 16 +- .../lib/oojs-ui/oojs-ui-core-wikimediaui.css | 10 +- resources/lib/oojs-ui/oojs-ui-core.js | 339 ++++++++++++------ resources/lib/oojs-ui/oojs-ui-core.js.map | 2 +- .../lib/oojs-ui/oojs-ui-toolbars-apex.css | 4 +- .../oojs-ui/oojs-ui-toolbars-wikimediaui.css | 4 +- resources/lib/oojs-ui/oojs-ui-toolbars.js | 18 +- resources/lib/oojs-ui/oojs-ui-toolbars.js.map | 2 +- .../lib/oojs-ui/oojs-ui-widgets-apex.css | 35 +- .../oojs-ui/oojs-ui-widgets-wikimediaui.css | 35 +- resources/lib/oojs-ui/oojs-ui-widgets.js | 12 +- resources/lib/oojs-ui/oojs-ui-widgets.js.map | 2 +- resources/lib/oojs-ui/oojs-ui-wikimediaui.js | 4 +- .../lib/oojs-ui/oojs-ui-windows-apex.css | 4 +- .../oojs-ui/oojs-ui-windows-wikimediaui.css | 4 +- resources/lib/oojs-ui/oojs-ui-windows.js | 4 +- .../lib/oojs-ui/themes/apex/indicators.json | 5 +- .../themes/wikimediaui/indicators.json | 5 +- 23 files changed, 346 insertions(+), 183 deletions(-) diff --git a/composer.json b/composer.json index b2b02ae071..c79bdfb50c 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ "ext-xml": "*", "liuggio/statsd-php-client": "1.0.18", "mediawiki/at-ease": "1.1.0", - "oojs/oojs-ui": "0.25.1", + "oojs/oojs-ui": "0.25.2", "oyejorge/less.php": "1.7.0.14", "php": ">=5.5.9", "psr/log": "1.0.2", diff --git a/resources/lib/oojs-ui/i18n/az.json b/resources/lib/oojs-ui/i18n/az.json index fc12d1b3dd..96b95d1aad 100644 --- a/resources/lib/oojs-ui/i18n/az.json +++ b/resources/lib/oojs-ui/i18n/az.json @@ -3,11 +3,13 @@ "authors": [ "Cekli829", "Interfase", - "Jduranboger" + "Jduranboger", + "Wertuose" ] }, "ooui-outline-control-move-down": "Bəndi aşağı apar", "ooui-outline-control-move-up": "Bəndi yuxarı apar", "ooui-outline-control-remove": "Bəndi sil", - "ooui-toolbar-more": "Daha artıq" + "ooui-toolbar-more": "Daha artıq", + "ooui-toolgroup-collapse": "Daha az" } diff --git a/resources/lib/oojs-ui/i18n/is.json b/resources/lib/oojs-ui/i18n/is.json index 574c59276e..3814ba2e23 100644 --- a/resources/lib/oojs-ui/i18n/is.json +++ b/resources/lib/oojs-ui/i18n/is.json @@ -2,7 +2,8 @@ "@metadata": { "authors": [ "Maxí", - "Snævar" + "Snævar", + "Sveinn í Felli" ] }, "ooui-outline-control-move-down": "Færa atriði niður", @@ -11,6 +12,7 @@ "ooui-toolbar-more": "Fleira", "ooui-toolgroup-expand": "Fleira", "ooui-toolgroup-collapse": "Færra", + "ooui-item-remove": "Fjarlægja", "ooui-dialog-message-accept": "Í lagi", "ooui-dialog-message-reject": "Hætta við", "ooui-dialog-process-error": "Eitthvað mistókst", diff --git a/resources/lib/oojs-ui/i18n/lzh.json b/resources/lib/oojs-ui/i18n/lzh.json index 2b3ad53c43..d0f1bd2acc 100644 --- a/resources/lib/oojs-ui/i18n/lzh.json +++ b/resources/lib/oojs-ui/i18n/lzh.json @@ -1,8 +1,14 @@ { "@metadata": { "authors": [ - "Joe young yu" + "Joe young yu", + "Itsmine", + "SolidBlock" ] }, + "ooui-outline-control-move-down": "遷下", + "ooui-outline-control-move-up": "遷上", + "ooui-outline-control-remove": "去物", + "ooui-toolbar-more": "餘", "ooui-dialog-message-accept": "可" } diff --git a/resources/lib/oojs-ui/oojs-ui-apex.js b/resources/lib/oojs-ui/oojs-ui-apex.js index 3bbe11c74a..66c874cae9 100644 --- a/resources/lib/oojs-ui/oojs-ui-apex.js +++ b/resources/lib/oojs-ui/oojs-ui-apex.js @@ -1,12 +1,12 @@ /*! - * OOUI v0.25.1 + * OOUI v0.25.2 * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2018 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2018-01-17T01:47:15Z + * Date: 2018-02-07T00:27:24Z */ ( function ( OO ) { diff --git a/resources/lib/oojs-ui/oojs-ui-core-apex.css b/resources/lib/oojs-ui/oojs-ui-core-apex.css index 38098c7b60..05ceda07bf 100644 --- a/resources/lib/oojs-ui/oojs-ui-core-apex.css +++ b/resources/lib/oojs-ui/oojs-ui-core-apex.css @@ -1,12 +1,12 @@ /*! - * OOUI v0.25.1 + * OOUI v0.25.2 * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2018 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2018-01-17T01:47:20Z + * Date: 2018-02-07T00:27:29Z */ .oo-ui-element-hidden { display: none !important; @@ -302,6 +302,12 @@ height: 0.9375em; opacity: 0.8; } +.oo-ui-labelElement .oo-ui-labelElement-label, +.oo-ui-labelElement.oo-ui-labelElement-label { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} .oo-ui-labelElement .oo-ui-labelElement-label-highlight { font-weight: bold; } @@ -357,7 +363,7 @@ .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-help, .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-help { margin-right: 0; - margin-left: -1.875em; + margin-left: -2.5em; } .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field, .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field { @@ -924,7 +930,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { padding: 0; } .oo-ui-checkboxMultiselectInputWidget .oo-ui-fieldLayout { - margin-bottom: 0; + margin-top: 0; } .oo-ui-checkboxMultiselectInputWidget .oo-ui-fieldLayout .oo-ui-fieldLayout-body { padding: 0.3125em 0; @@ -983,7 +989,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { background-color: #f3f3f3; } .oo-ui-radioSelectInputWidget .oo-ui-fieldLayout { - margin-bottom: 0; + margin-top: 0; } .oo-ui-radioSelectInputWidget .oo-ui-fieldLayout .oo-ui-fieldLayout-body { padding: 0.3125em 0; diff --git a/resources/lib/oojs-ui/oojs-ui-core-wikimediaui.css b/resources/lib/oojs-ui/oojs-ui-core-wikimediaui.css index f9183da934..7951abbc9d 100644 --- a/resources/lib/oojs-ui/oojs-ui-core-wikimediaui.css +++ b/resources/lib/oojs-ui/oojs-ui-core-wikimediaui.css @@ -1,12 +1,12 @@ /*! - * OOUI v0.25.1 + * OOUI v0.25.2 * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2018 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2018-01-17T01:47:20Z + * Date: 2018-02-07T00:27:29Z */ /** * WikimediaUI Base v0.10.0 @@ -425,6 +425,12 @@ min-height: 12px; height: 100%; } +.oo-ui-labelElement .oo-ui-labelElement-label, +.oo-ui-labelElement.oo-ui-labelElement-label { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} .oo-ui-labelElement .oo-ui-labelElement-label-highlight { font-weight: bold; } diff --git a/resources/lib/oojs-ui/oojs-ui-core.js b/resources/lib/oojs-ui/oojs-ui-core.js index 96d730f7ad..12e5ef66b6 100644 --- a/resources/lib/oojs-ui/oojs-ui-core.js +++ b/resources/lib/oojs-ui/oojs-ui-core.js @@ -1,12 +1,12 @@ /*! - * OOUI v0.25.1 + * OOUI v0.25.2 * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2018 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2018-01-17T01:47:15Z + * Date: 2018-02-07T00:27:24Z */ ( function ( OO ) { @@ -826,16 +826,16 @@ OO.ui.Element.static.unsafeInfuse = function ( idOrNode, domPromise ) { // rebuild widget // eslint-disable-next-line new-cap obj = new cls( data ); + // If anyone is holding a reference to the old DOM element, + // let's allow them to OO.ui.infuse() it and do what they expect, see T105828. + // Do not use jQuery.data(), as using it on detached nodes leaks memory in 1.x line by design. + $elem[ 0 ].oouiInfused = obj.$element; // now replace old DOM with this new DOM. if ( top ) { // An efficient constructor might be able to reuse the entire DOM tree of the original element, // so only mutate the DOM if we need to. if ( $elem[ 0 ] !== obj.$element[ 0 ] ) { $elem.replaceWith( obj.$element ); - // This element is now gone from the DOM, but if anyone is holding a reference to it, - // let's allow them to OO.ui.infuse() it and do what they expect, see T105828. - // Do not use jQuery.data(), as using it on detached nodes leaks memory in 1.x line by design. - $elem[ 0 ].oouiInfused = obj.$element; } top.resolve(); } @@ -2797,7 +2797,7 @@ OO.ui.mixin.IconElement.prototype.getIconTitle = function () { * @param {Object} [config] Configuration options * @cfg {jQuery} [$indicator] The indicator element created by the class. If this * configuration is omitted, the indicator element will use a generated ``. - * @cfg {string} [indicator] Symbolic name of the indicator (e.g., ‘alert’ or ‘down’). + * @cfg {string} [indicator] Symbolic name of the indicator (e.g., ‘clear’ or ‘down’). * See the [OOUI documentation on MediaWiki][2] for a list of indicators included * in the library. * [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Icons,_Indicators,_and_Labels#Indicators @@ -2827,7 +2827,7 @@ OO.initClass( OO.ui.mixin.IndicatorElement ); /* Static Properties */ /** - * Symbolic name of the indicator (e.g., ‘alert’ or ‘down’). + * Symbolic name of the indicator (e.g., ‘clear’ or ‘down’). * The static property will be overridden if the #indicator configuration is used. * * @static @@ -2873,7 +2873,7 @@ OO.ui.mixin.IndicatorElement.prototype.setIndicatorElement = function ( $indicat }; /** - * Set the indicator by its symbolic name: ‘alert’, ‘down’, ‘next’, ‘previous’, ‘required’, ‘up’. Use `null` to remove the indicator. + * Set the indicator by its symbolic name: ‘clear’, ‘down’, ‘required’, ‘search’, ‘up’. Use `null` to remove the indicator. * * @param {string|null} indicator Symbolic name of indicator, or `null` for no indicator * @chainable @@ -2928,7 +2928,7 @@ OO.ui.mixin.IndicatorElement.prototype.setIndicatorTitle = function ( indicatorT }; /** - * Get the symbolic name of the indicator (e.g., ‘alert’ or ‘down’). + * Get the symbolic name of the indicator (e.g., ‘clear’ or ‘down’). * * @return {string} Symbolic name of indicator */ @@ -3983,19 +3983,19 @@ OO.ui.IconWidget.static.tagName = 'span'; /** * IndicatorWidgets create indicators, which are small graphics that are generally used to draw - * attention to the status of an item or to clarify the function of a control. For a list of + * attention to the status of an item or to clarify the function within a control. For a list of * indicators included in the library, please see the [OOUI documentation on MediaWiki][1]. * * @example * // Example of an indicator widget * var indicator1 = new OO.ui.IndicatorWidget( { - * indicator: 'alert' + * indicator: 'required' * } ); * * // Create a fieldset layout to add a label * var fieldset = new OO.ui.FieldsetLayout(); * fieldset.addItems( [ - * new OO.ui.FieldLayout( indicator1, { label: 'An alert indicator:' } ) + * new OO.ui.FieldLayout( indicator1, { label: 'A required indicator:' } ) * ] ); * $( 'body' ).append( fieldset.$element ); * @@ -6067,7 +6067,7 @@ OO.ui.OptionWidget.static.scrollIntoViewOnSelect = false; * @return {boolean} Item is selectable */ OO.ui.OptionWidget.prototype.isSelectable = function () { - return this.constructor.static.selectable && !this.isDisabled() && this.isVisible(); + return this.constructor.static.selectable && !this.disabled && this.isVisible(); }; /** @@ -6078,7 +6078,7 @@ OO.ui.OptionWidget.prototype.isSelectable = function () { * @return {boolean} Item is highlightable */ OO.ui.OptionWidget.prototype.isHighlightable = function () { - return this.constructor.static.highlightable && !this.isDisabled() && this.isVisible(); + return this.constructor.static.highlightable && !this.disabled && this.isVisible(); }; /** @@ -6088,7 +6088,7 @@ OO.ui.OptionWidget.prototype.isHighlightable = function () { * @return {boolean} Item is pressable */ OO.ui.OptionWidget.prototype.isPressable = function () { - return this.constructor.static.pressable && !this.isDisabled() && this.isVisible(); + return this.constructor.static.pressable && !this.disabled && this.isVisible(); }; /** @@ -8786,6 +8786,13 @@ OO.ui.InputWidget.prototype.setValue = function ( value ) { this.value = value; this.emit( 'change', this.value ); } + // The first time that the value is set (probably while constructing the widget), + // remember it in defaultValue. This property can be later used to check whether + // the value of the input has been changed since it was created. + if ( this.defaultValue === undefined ) { + this.defaultValue = this.value; + this.$input[ 0 ].defaultValue = this.defaultValue; + } return this; }; @@ -9140,6 +9147,13 @@ OO.ui.CheckboxInputWidget.prototype.setSelected = function ( state ) { this.$input.prop( 'checked', this.selected ); this.emit( 'change', this.selected ); } + // The first time that the selection state is set (probably while constructing the widget), + // remember it in defaultSelected. This property can be later used to check whether + // the selection state of the input has been changed since it was created. + if ( this.defaultSelected === undefined ) { + this.defaultSelected = this.selected; + this.$input[ 0 ].defaultChecked = this.defaultSelected; + } return this; }; @@ -9217,6 +9231,9 @@ OO.ui.DropdownInputWidget = function OoUiDropdownInputWidget( config ) { // Properties (must be done before parent constructor which calls #setDisabled) this.dropdownWidget = new OO.ui.DropdownWidget( config.dropdown ); + // Set up the options before parent constructor, which uses them to validate config.value. + // Use this instead of setOptions() because this.$input is not set up yet. + this.setOptionsData( config.options || [] ); // Parent constructor OO.ui.DropdownInputWidget.parent.call( this, config ); @@ -9225,10 +9242,6 @@ OO.ui.DropdownInputWidget = function OoUiDropdownInputWidget( config ) { this.dropdownWidget.getMenu().connect( this, { select: 'onMenuSelect' } ); // Initialization - this.setOptions( config.options || [] ); - // Set the value again, after we did setOptions(). The call from parent doesn't work because the - // widget has no valid options when it happens. - this.setValue( config.value ); this.$element .addClass( 'oo-ui-dropdownInputWidget' ) .append( this.dropdownWidget.$element ); @@ -9271,6 +9284,11 @@ OO.ui.DropdownInputWidget.prototype.setValue = function ( value ) { this.dropdownWidget.getMenu().selectItem( selected ); value = selected ? selected.getData() : ''; OO.ui.DropdownInputWidget.parent.prototype.setValue.call( this, value ); + if ( this.optionsDirty ) { + // We reached this from the constructor or from #setOptions. + // We have to update the ). + // In case the previous value is no longer an available option, select the first valid one. + this.setValue( value ); + + return this; +}; + +/** + * Set the internal list of options, used e.g. by setValue() to see which options are allowed. + * + * This method may be called before the parent constructor, so various properties may not be + * intialized yet. + * + * @param {Object[]} options Array of menu options in the format `{ data: …, label: … }` + * @private + */ +OO.ui.DropdownInputWidget.prototype.setOptionsData = function ( options ) { var - optionWidgets = [], - value = this.getValue(), - $optionsContainer = this.$input, + optionWidgets, widget = this; - this.dropdownWidget.getMenu().clearItems(); - this.$input.empty(); + this.optionsDirty = true; - // Rebuild the dropdown menu: our visible one and the hidden `' ).attr( 'type', 'hidden' ); + // Use this instead of , because hidden inputs do not have separate + // 'value' and 'defaultValue' properties, and InputWidget wants to handle 'defaultValue'. + return $( '' ).addClass( 'oo-ui-element-hidden' ); }; /** @@ -9595,8 +9657,13 @@ OO.ui.RadioSelectInputWidget.prototype.onMenuSelect = function ( item ) { * @inheritdoc */ OO.ui.RadioSelectInputWidget.prototype.setValue = function ( value ) { + var selected; value = this.cleanUpValue( value ); - this.radioSelectWidget.selectItemByData( value ); + // Only allow setting values that are actually present in the dropdown + selected = this.radioSelectWidget.findItemFromData( value ) || + this.radioSelectWidget.findFirstSelectableItem(); + this.radioSelectWidget.selectItem( selected ); + value = selected ? selected.getData() : ''; OO.ui.RadioSelectInputWidget.parent.prototype.setValue.call( this, value ); return this; }; @@ -9617,11 +9684,29 @@ OO.ui.RadioSelectInputWidget.prototype.setDisabled = function ( state ) { * @chainable */ OO.ui.RadioSelectInputWidget.prototype.setOptions = function ( options ) { - var - value = this.getValue(), - widget = this; + var value = this.getValue(); + + this.setOptionsData( options ); + + // Re-set the value to update the visible interface (RadioSelectWidget). + // In case the previous value is no longer an available option, select the first valid one. + this.setValue( value ); + + return this; +}; + +/** + * Set the internal list of options, used e.g. by setValue() to see which options are allowed. + * + * This method may be called before the parent constructor, so various properties may not be + * intialized yet. + * + * @param {Object[]} options Array of menu options in the format `{ data: …, label: … }` + * @private + */ +OO.ui.RadioSelectInputWidget.prototype.setOptionsData = function ( options ) { + var widget = this; - // Rebuild the radioSelect menu this.radioSelectWidget .clearItems() .addItems( options.map( function ( opt ) { @@ -9631,19 +9716,6 @@ OO.ui.RadioSelectInputWidget.prototype.setOptions = function ( options ) { label: opt.label !== undefined ? opt.label : optValue } ); } ) ); - - // Restore the previous value, or reset to something sensible - if ( this.radioSelectWidget.findItemFromData( value ) ) { - // Previous value is still available, ensure consistency with the radioSelect - this.setValue( value ); - } else { - // No longer valid, reset - if ( options.length ) { - this.setValue( options[ 0 ].data ); - } - } - - return this; }; /** @@ -9695,6 +9767,9 @@ OO.ui.CheckboxMultiselectInputWidget = function OoUiCheckboxMultiselectInputWidg // Properties (must be done before parent constructor which calls #setDisabled) this.checkboxMultiselectWidget = new OO.ui.CheckboxMultiselectWidget(); + // Set up the options before parent constructor, which uses them to validate config.value. + // Use this instead of setOptions() because this.$input is not set up yet + this.setOptionsData( config.options || [] ); // Parent constructor OO.ui.CheckboxMultiselectInputWidget.parent.call( this, config ); @@ -9702,20 +9777,15 @@ OO.ui.CheckboxMultiselectInputWidget = function OoUiCheckboxMultiselectInputWidg // Properties this.inputName = config.name; + // Events + this.checkboxMultiselectWidget.connect( this, { select: 'onCheckboxesSelect' } ); + // Initialization this.$element .addClass( 'oo-ui-checkboxMultiselectInputWidget' ) .append( this.checkboxMultiselectWidget.$element ); // We don't use this.$input, but rather the CheckboxInputWidgets inside each option this.$input.detach(); - this.setOptions( config.options || [] ); - // Have to repeat this from parent, as we need options to be set up for this to make sense - this.setValue( config.value ); - - // setValue when checkboxMultiselectWidget changes - this.checkboxMultiselectWidget.on( 'change', function () { - this.setValue( this.checkboxMultiselectWidget.findSelectedItemsData() ); - }.bind( this ) ); }; /* Setup */ @@ -9755,6 +9825,15 @@ OO.ui.CheckboxMultiselectInputWidget.prototype.getInputElement = function () { return $( '' ); }; +/** + * Handles CheckboxMultiselectWidget select events. + * + * @private + */ +OO.ui.CheckboxMultiselectInputWidget.prototype.onCheckboxesSelect = function () { + this.setValue( this.checkboxMultiselectWidget.findSelectedItemsData() ); +}; + /** * @inheritdoc */ @@ -9774,6 +9853,11 @@ OO.ui.CheckboxMultiselectInputWidget.prototype.setValue = function ( value ) { value = this.cleanUpValue( value ); this.checkboxMultiselectWidget.selectItemsByData( value ); OO.ui.CheckboxMultiselectInputWidget.parent.prototype.setValue.call( this, value ); + if ( this.optionsDirty ) { + // We reached this from the constructor or from #setOptions. + // We have to update the and on the