aboutsummaryrefslogtreecommitdiffstats
path: root/resources/lib/ooui/oojs-ui-widgets.js
diff options
context:
space:
mode:
authorVolker E <volker.e@wikimedia.org>2023-05-18 10:13:26 -0700
committerVolker E <volker.e@wikimedia.org>2023-05-18 12:03:32 -0700
commit5c683fbc1b0b6ede62a0edc72850d9fc5d1b25fd (patch)
tree604dcad86312c454db27b5b6e7fbddfc2f6ce8fc /resources/lib/ooui/oojs-ui-widgets.js
parentd8d768b874eb297af87b885c8eea15df6e7e27eb (diff)
downloadmediawikicore-5c683fbc1b0b6ede62a0edc72850d9fc5d1b25fd.tar.gz
mediawikicore-5c683fbc1b0b6ede62a0edc72850d9fc5d1b25fd.zip
Update OOUI to v0.47.0
Release notes: https://gerrit.wikimedia.org/g/oojs/ui/+/v0.47.0/History.md Bug: T53229 Bug: T285252 Bug: T285252 Bug: T309916 Bug: T313804 Bug: T314661 Bug: T324449 Bug: T326706 Bug: T328492 Bug: T328492 Bug: T328492 Bug: T328492 Bug: T328741 Bug: T329383 Bug: T330424 Bug: T331403 Bug: T333155 Bug: T334492 Bug: T335082 Bug: T335082 Bug: T335214 Depends-On: Ic1c9bf8948e63956119c3bd4befe7f6436f82095 Change-Id: I57a8ccc9b7e6b9a6b68a43085e3c7b5201c516a4
Diffstat (limited to 'resources/lib/ooui/oojs-ui-widgets.js')
-rw-r--r--resources/lib/ooui/oojs-ui-widgets.js178
1 files changed, 173 insertions, 5 deletions
diff --git a/resources/lib/ooui/oojs-ui-widgets.js b/resources/lib/ooui/oojs-ui-widgets.js
index be98d8fe93f7..68e8f2370b0e 100644
--- a/resources/lib/ooui/oojs-ui-widgets.js
+++ b/resources/lib/ooui/oojs-ui-widgets.js
@@ -1,12 +1,12 @@
/*!
- * OOUI v0.46.3
+ * OOUI v0.47.0
* https://www.mediawiki.org/wiki/OOUI
*
* Copyright 2011–2023 OOUI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2023-02-07T00:43:59Z
+ * Date: 2023-05-18T02:15:42Z
*/
( function ( OO ) {
@@ -1344,6 +1344,8 @@ OO.ui.PageLayout.prototype.setActive = function ( active ) {
* @cfg {boolean} [continuous=false] Show all panels, one after another. By default, only one panel
* is displayed at a time.
* @cfg {OO.ui.Layout[]} [items] Panel layouts to add to the stack layout.
+ * @cfg {boolean} [hideUntilFound] Hide panels using hidden="until-found", meaning they will be
+ * shown when matched with the browser's find-and-replace feature if supported.
*/
OO.ui.StackLayout = function OoUiStackLayout( config ) {
// Configuration initialization
@@ -1360,6 +1362,7 @@ OO.ui.StackLayout = function OoUiStackLayout( config ) {
// Properties
this.currentItem = null;
this.continuous = !!config.continuous;
+ this.hideUntilFound = !!config.hideUntilFound;
// Initialization
this.$element.addClass( 'oo-ui-stackLayout' );
@@ -1413,6 +1416,17 @@ OO.ui.StackLayout.prototype.unsetCurrentItem = function () {
};
/**
+ * Set the hideUntilFound config (see contructor)
+ *
+ * @param {boolean} hideUntilFound
+ */
+OO.ui.StackLayout.prototype.setHideUntilFound = function ( hideUntilFound ) {
+ this.hideUntilFound = hideUntilFound;
+ // Force an update of the attributes used to hide/show items
+ this.updateHiddenState( this.items, this.currentItem );
+};
+
+/**
* Add panel layouts to the stack layout.
*
* Panels will be added to the end of the stack layout array unless the optional index parameter
@@ -1559,12 +1573,14 @@ OO.ui.StackLayout.prototype.updateHiddenState = function ( items, selectedItem )
if ( !this.continuous ) {
for ( var i = 0, len = items.length; i < len; i++ ) {
if ( !selectedItem || selectedItem !== items[ i ] ) {
- items[ i ].toggle( false );
+ // jQuery "fixes" the value of the hidden attribute to always be "hidden"
+ // Browsers which don't support 'until-found' will still hide the element
+ items[ i ].$element[ 0 ].setAttribute( 'hidden', this.hideUntilFound ? 'until-found' : 'hidden' );
items[ i ].$element.attr( 'aria-hidden', 'true' );
}
}
if ( selectedItem ) {
- selectedItem.toggle( true );
+ selectedItem.$element[ 0 ].removeAttribute( 'hidden' );
selectedItem.$element.removeAttr( 'aria-hidden' );
}
}
@@ -2466,6 +2482,8 @@ OO.ui.BookletLayout.prototype.selectFirstSelectablePage = function () {
* @cfg {boolean} [autoFocus=true] Focus on the first focusable element when a new tab panel is
* displayed. Disabled on mobile.
* @cfg {boolean} [framed=true] Render the tabs with frames
+ * @cfg {boolean} [openMatchedPanels=true] Automatically switch to a panel when the browser's
+ * find-in-page feature matches content there, in browsers that support it.
*/
OO.ui.IndexLayout = function OoUiIndexLayout( config ) {
// Configuration initialization
@@ -2478,15 +2496,29 @@ OO.ui.IndexLayout = function OoUiIndexLayout( config ) {
this.currentTabPanelName = null;
// Allow infused widgets to pass existing tabPanels
this.tabPanels = config.tabPanels || {};
+ this.openMatchedPanels = config.openMatchedPanels === undefined || !!config.openMatchedPanels;
this.ignoreFocus = false;
+ if ( this.contentPanel ) {
+ this.contentPanel.setHideUntilFound( this.openMatchedPanels );
+ }
this.stackLayout = this.contentPanel || new OO.ui.StackLayout( {
continuous: !!config.continuous,
- expanded: this.expanded
+ expanded: this.expanded,
+ hideUntilFound: this.openMatchedPanels
} );
this.setContentPanel( this.stackLayout );
this.autoFocus = config.autoFocus === undefined || !!config.autoFocus;
+ if ( config.tabSelectWidget ) {
+ // If we are using a custom tabSelectWidget (e.g. infusing) then
+ // ensure the tabPanels are linked to tabItems
+ this.stackLayout.getItems().forEach( function ( tabPanel, i ) {
+ if ( !tabPanel.getTabItem() ) {
+ tabPanel.setTabItem( config.tabSelectWidget.items[ i ] || null );
+ }
+ } );
+ }
// Allow infused widgets to pass an existing tabSelectWidget
this.tabSelectWidget = config.tabSelectWidget || new OO.ui.TabSelectWidget( {
framed: config.framed === undefined || config.framed
@@ -2502,6 +2534,9 @@ OO.ui.IndexLayout = function OoUiIndexLayout( config ) {
this.stackLayout.connect( this, {
set: 'onStackLayoutSet'
} );
+ if ( this.openMatchedPanels ) {
+ this.stackLayout.$element.on( 'beforematch', this.onStackLayoutBeforeMatch.bind( this ) );
+ }
this.tabSelectWidget.connect( this, {
select: 'onTabSelectWidgetSelect'
} );
@@ -2589,6 +2624,29 @@ OO.ui.IndexLayout.prototype.onStackLayoutSet = function ( tabPanel ) {
};
/**
+ * Handle beforematch events triggered by the browser's find-in-page feature
+ *
+ * @param {Event} event 'beforematch' event
+ */
+OO.ui.IndexLayout.prototype.onStackLayoutBeforeMatch = function ( event ) {
+ var tabPanel;
+ // Find TabPanel from DOM node
+ this.stackLayout.getItems().some( function ( item ) {
+ if ( item.$element[ 0 ] === event.target ) {
+ tabPanel = item;
+ return true;
+ }
+ return false;
+ } );
+ if ( tabPanel ) {
+ var tabItem = tabPanel.getTabItem();
+ if ( tabItem ) {
+ this.tabSelectWidget.selectItem( tabItem );
+ }
+ }
+};
+
+/**
* Focus the first input in the current tab panel.
*
* If no tab panel is selected, the first selectable tab panel will be selected.
@@ -2900,6 +2958,111 @@ OO.ui.IndexLayout.prototype.selectFirstSelectableTabPanel = function () {
};
/**
+ * CopyTextLayout is an action field layout containing some readonly text and a button to copy
+ * it to the clipboard.
+ *
+ * @class
+ * @extends OO.ui.ActionFieldLayout
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {string} copyText Text to copy, can also be provided as textInput.value
+ * @cfg {Object} textInput Config for text input
+ * @cfg {Object} button Config for button
+ */
+OO.ui.CopyTextLayout = function OoUiCopyTextLayout( config ) {
+ var TextClass;
+ config = config || {};
+
+ // Properties
+ TextClass = config.multiline ? OO.ui.MultilineTextInputWidget : OO.ui.TextInputWidget;
+ this.textInput = new TextClass( $.extend( {
+ value: config.copyText,
+ readOnly: true
+ }, config.textInput ) );
+ this.button = new OO.ui.ButtonWidget( $.extend( {
+ label: OO.ui.msg( 'ooui-copytextlayout-copy' ),
+ icon: 'articles'
+ }, config.button ) );
+
+ // Parent constructor
+ OO.ui.CopyTextLayout.super.call( this, this.textInput, this.button, config );
+
+ // HACK: When using a multiline text input, remove classes which connect widgets
+ if ( config.multiline ) {
+ this.$input.removeClass( 'oo-ui-actionFieldLayout-input' );
+ this.$button
+ .removeClass( 'oo-ui-actionFieldLayout-button' )
+ .addClass( 'oo-ui-copyTextLayout-multiline-button' );
+ }
+
+ // Events
+ this.button.connect( this, { click: 'onButtonClick' } );
+ this.textInput.$input.on( 'focus', this.onInputFocus.bind( this ) );
+
+ this.$element.addClass( 'oo-ui-copyTextLayout' );
+};
+
+/* Inheritance */
+
+OO.inheritClass( OO.ui.CopyTextLayout, OO.ui.ActionFieldLayout );
+
+/* Events */
+
+/**
+ * When the user has executed a copy command
+ *
+ * @event copy
+ * @param {boolean} Whether the copy command succeeded
+ */
+
+/* Methods */
+
+/**
+ * Handle button click events
+ *
+ * @fires copy
+ */
+OO.ui.CopyTextLayout.prototype.onButtonClick = function () {
+ var copied;
+
+ this.selectText();
+
+ try {
+ copied = document.execCommand( 'copy' );
+ } catch ( e ) {
+ copied = false;
+ }
+ this.emit( 'copy', copied );
+};
+
+/**
+ * Handle text widget focus events
+ */
+OO.ui.CopyTextLayout.prototype.onInputFocus = function () {
+ if ( !this.selecting ) {
+ this.selectText();
+ }
+};
+
+/**
+ * Select the text to copy
+ */
+OO.ui.CopyTextLayout.prototype.selectText = function () {
+ var input = this.textInput.$input[ 0 ],
+ scrollTop = input.scrollTop,
+ scrollLeft = input.scrollLeft;
+
+ this.selecting = true;
+ this.textInput.select();
+ this.selecting = false;
+
+ // Restore scroll position
+ input.scrollTop = scrollTop;
+ input.scrollLeft = scrollLeft;
+};
+
+/**
* ToggleWidget implements basic behavior of widgets with an on/off state.
* Please see OO.ui.ToggleButtonWidget and OO.ui.ToggleSwitchWidget for examples.
*
@@ -5450,10 +5613,15 @@ OO.ui.MenuTagMultiselectWidget.prototype.onResize = function () {
* @inheritdoc
*/
OO.ui.MenuTagMultiselectWidget.prototype.onInputFocus = function () {
+ var valid = this.isValid();
+
// Parent method
OO.ui.MenuTagMultiselectWidget.super.prototype.onInputFocus.call( this );
this.menu.toggle( true );
+ if ( !valid ) {
+ this.menu.highlightItem();
+ }
};
/**