resources: Create mw.widgets.visibleCodePointLimitWithDropdown

Use the new function instead of own filter functions at some places.
Also use the colon-seperator message in content language to address the
todo from the Resources.php while moving the code.

Also add mw.widgets.visibleByteLimitWithDropdown

Move the existing code into internal functions as most code is the same

Bug: T301651
Change-Id: I2335adcbcfe5d3ce7809ef35b33bbf999518a080
This commit is contained in:
Umherirrender 2024-03-07 22:34:13 +01:00
parent 16fb214dbf
commit 3b33627619
8 changed files with 108 additions and 153 deletions

View file

@ -1312,8 +1312,6 @@ return [
],
'messages' => [
'protect-unchain-permissions',
// @todo Load this message in content language
'colon-separator',
],
],
'mediawiki.action.view.metadata' => [
@ -2139,11 +2137,6 @@ return [
'mediawiki.widgets',
'oojs-ui-core',
],
'messages' => [
// Used by action.delete.js, special.revisionDelete.js, special.movePage.js, special.undelete.js
// @todo Load this message in content language
'colon-separator',
],
],
// This bundles various small (under 2 KB?) JavaScript files that:
// - .. are only used by logged-in users when a non-default preference was enabled.
@ -2679,8 +2672,19 @@ return [
],
],
'mediawiki.widgets.visibleLengthLimit' => [
'scripts' => [
'resources/src/mediawiki.widgets.visibleLengthLimit/mediawiki.widgets.visibleLengthLimit.js'
'localBasePath' => MW_INSTALL_PATH . '/resources/src/mediawiki.widgets.visibleLengthLimit',
'remoteBasePath' => "$wgResourceBasePath/resources/src/mediawiki.widgets.visibleLengthLimit",
'packageFiles' => [
'mediawiki.widgets.visibleLengthLimit.js',
[
'name' => 'contentMessages.json',
'type' => 'data',
'callback' => static function ( Context $context ) {
return [
'colonSeparator' => $context->msg( 'colon-separator' )->inContentLanguage()->text(),
];
}
],
],
'dependencies' => [
'oojs-ui-core',

View file

@ -199,27 +199,11 @@
toggleUnchainedInputs( !areAllTypesMatching() );
}
var colonSeparator = mw.msg( 'colon-separator' ),
reasonList = OO.ui.infuse( $( '#wpProtectReasonSelection' ) ),
reason = OO.ui.infuse( $( '#mwProtect-reason' ) ),
filterFunction = function ( input ) {
// Should be built the same as in ProtectionForm::save()
var comment = reasonList.getValue();
if ( comment === 'other' ) {
comment = input;
} else if ( input !== '' ) {
// Entry from drop down menu + additional comment
comment += colonSeparator + input;
}
return comment;
};
var reasonList = OO.ui.infuse( $( '#wpProtectReasonSelection' ) ),
reason = OO.ui.infuse( $( '#mwProtect-reason' ) );
// Arbitrary 75 to leave some space for the autogenerated null edit's summary
mw.widgets.visibleCodePointLimit( reason, mw.config.get( 'wgCommentCodePointLimit' ) - 75, filterFunction );
// Keep the remaining counter in sync when reason list changed
reasonList.on( 'change', function () {
reason.emit( 'change' );
} );
mw.widgets.visibleCodePointLimitWithDropdown( reason, reasonList, mw.config.get( 'wgCommentCodePointLimit' ) - 75 );
updateCascadeAndExpire();
}() );

View file

@ -24,22 +24,9 @@
mw.loader.using( 'mediawiki.widgets.SelectWithInputWidget', function () {
widget = OO.ui.Widget.static.infuse( $widget );
maxlengthUnit = widget.getData().maxlengthUnit;
lengthLimiter = maxlengthUnit === 'codepoints' ? 'visibleCodePointLimit' : 'visibleByteLimit ';
mw.widgets[ lengthLimiter ]( widget.textinput, null, function ( input ) {
// Should be built the same as in HTMLSelectAndOtherField::loadDataFromRequest
var comment = widget.dropdowninput.getValue();
if ( comment === 'other' ) {
comment = input;
} else if ( input !== '' ) {
// Entry from drop down menu + additional comment
comment += colonSeparator + input;
}
return comment;
} );
// Keep the remaining counter in sync when reason list changed
widget.dropdowninput.on( 'change', function () {
widget.textinput.emit( 'change' );
} );
lengthLimiter = maxlengthUnit === 'codepoints' ?
'visibleCodePointLimitWithDropdown' : 'visibleByteLimitWithDropdown';
mw.widgets[ lengthLimiter ]( widget.textinput, widget.dropdowninput );
} );
} else {
// cache the current selection to avoid expensive lookup

View file

@ -7,25 +7,9 @@
}
$( function () {
var colonSeparator = mw.msg( 'colon-separator' ),
reasonList = OO.ui.infuse( $( '#wpDeleteReasonList' ) ),
reason = OO.ui.infuse( $( '#wpReason' ) ),
filterFunction = function ( input ) {
// Should be built the same as in DeleteAction::getDeleteReason()
var comment = reasonList.getValue();
if ( comment === 'other' ) {
comment = input;
} else if ( input !== '' ) {
// Entry from drop down menu + additional comment
comment += colonSeparator + input;
}
return comment;
};
var reasonList = OO.ui.infuse( $( '#wpDeleteReasonList' ) ),
reason = OO.ui.infuse( $( '#wpReason' ) );
mw.widgets.visibleCodePointLimit( reason, mw.config.get( 'wgCommentCodePointLimit' ), filterFunction );
// Keep the remaining counter in sync when reason list changed
reasonList.on( 'change', function () {
reason.emit( 'change' );
} );
mw.widgets.visibleCodePointLimitWithDropdown( reason, reasonList, mw.config.get( 'wgCommentCodePointLimit' ) );
} );
}() );

View file

@ -13,24 +13,8 @@
// Infuse for pretty dropdown
OO.ui.infuse( $( '#wpNewTitle' ) );
var colonSeparator = mw.msg( 'colon-separator' ),
wpReasonList = OO.ui.infuse( $( '#wpReasonList' ).closest( '.oo-ui-widget' ) ),
filterFunction = function ( input ) {
// Should be built the same as in SpecialMovePage::execute()
var comment = wpReasonList.getValue();
if ( comment === 'other' ) {
comment = input;
} else if ( input !== '' ) {
// Entry from drop down menu + additional comment
comment += colonSeparator + input;
}
return comment;
};
var wpReasonList = OO.ui.infuse( $( '#wpReasonList' ).closest( '.oo-ui-widget' ) );
mw.widgets.visibleCodePointLimit( wpReason, mw.config.get( 'wgCommentCodePointLimit' ), filterFunction );
// Keep the remaining counter in sync when reason list changed
wpReasonList.on( 'change', function () {
wpReason.emit( 'change' );
} );
mw.widgets.visibleCodePointLimitWithDropdown( wpReason, wpReasonList, mw.config.get( 'wgCommentCodePointLimit' ) );
} );
}() );

View file

@ -6,24 +6,8 @@
return;
}
var colonSeparator = mw.msg( 'colon-separator' ),
wpRevDeleteReasonList = OO.ui.infuse( $( '#wpRevDeleteReasonList' ) ),
wpReason = OO.ui.infuse( $( '#wpReason' ) ),
filterFunction = function ( input ) {
// Should be built the same as in SpecialRevisionDelete::submit()
var comment = wpRevDeleteReasonList.getValue();
if ( comment === 'other' ) {
comment = input;
} else if ( input !== '' ) {
// Entry from drop down menu + additional comment
comment += colonSeparator + input;
}
return comment;
};
var wpRevDeleteReasonList = OO.ui.infuse( $( '#wpRevDeleteReasonList' ) ),
wpReason = OO.ui.infuse( $( '#wpReason' ) );
mw.widgets.visibleCodePointLimit( wpReason, mw.config.get( 'wgCommentCodePointLimit' ), filterFunction );
// Keep the remaining counter in sync when reason list changed
wpRevDeleteReasonList.on( 'change', function () {
wpReason.emit( 'change' );
} );
mw.widgets.visibleCodePointLimitWithDropdown( wpReason, wpRevDeleteReasonList, mw.config.get( 'wgCommentCodePointLimit' ) );
}() );

View file

@ -20,19 +20,7 @@
wpComment = OO.ui.infuse( $widget );
var colonSeparator = mw.msg( 'colon-separator' ),
wpCommentList = OO.ui.infuse( $( '#wpCommentList' ).closest( '.oo-ui-widget' ) ),
filterFunction = function ( input ) {
// Should be built the same as in SpecialUndelete::loadRequest()
var comment = wpCommentList.getValue();
if ( comment === 'other' ) {
comment = input;
} else if ( input !== '' ) {
// Entry from drop down menu + additional comment
comment += colonSeparator + input;
}
return comment;
};
var wpCommentList = OO.ui.infuse( $( '#wpCommentList' ).closest( '.oo-ui-widget' ) );
$( '#mw-undelete-invert' ).on( 'click', function () {
$( '.mw-undelete-revlist input[type="checkbox"]' ).prop( 'checked', function ( i, val ) {
@ -40,10 +28,6 @@
} );
} );
mw.widgets.visibleCodePointLimit( wpComment, mw.config.get( 'wgCommentCodePointLimit' ), filterFunction );
// Keep the remaining counter in sync when reason list changed
wpCommentList.on( 'change', function () {
wpComment.emit( 'change' );
} );
mw.widgets.visibleCodePointLimitWithDropdown( wpComment, wpCommentList, mw.config.get( 'wgCommentCodePointLimit' ) );
} );
}() );

View file

@ -1,31 +1,30 @@
( function () {
var byteLength = require( 'mediawiki.String' ).byteLength,
codePointLength = require( 'mediawiki.String' ).codePointLength;
codePointLength = require( 'mediawiki.String' ).codePointLength,
colonSeparator = require( './contentMessages.json' ).colonSeparator;
/**
* Loaded from `mediawiki.widgets.visibleLengthLimit` module.
* Add a visible byte limit label to a TextInputWidget.
*
* Uses jQuery#byteLimit to enforce the limit.
*
* @param {OO.ui.TextInputWidget} textInputWidget Text input widget
* @param {number} [limit] Byte limit, defaults to $input's maxlength
* @param {Function} [filterFunction] Function to call on the string before assessing the length.
* @internal
* @param {string} lengthLimiter
* @param {OO.ui.TextInputWidget} textInputWidget
* @param {number} [limit]
* @param {Function} [filterFunction]
*/
mw.widgets.visibleByteLimit = function ( textInputWidget, limit, filterFunction ) {
function internalVisibleLimit( lengthLimiter, textInputWidget, limit, filterFunction ) {
limit = limit || +textInputWidget.$input.attr( 'maxlength' );
if ( !filterFunction || typeof filterFunction !== 'function' ) {
filterFunction = undefined;
}
var lengthFunction = lengthLimiter === 'byteLimit' ? byteLength : codePointLength;
function updateCount() {
var value = textInputWidget.getValue(),
remaining;
if ( filterFunction ) {
value = filterFunction( value );
}
remaining = limit - byteLength( value );
remaining = limit - lengthFunction( value );
if ( remaining > 99 ) {
remaining = '';
} else {
@ -38,7 +37,48 @@
updateCount();
// Actually enforce limit
textInputWidget.$input.byteLimit( limit, filterFunction );
textInputWidget.$input[ lengthLimiter ]( limit, filterFunction );
}
/**
* @internal
* @param {string} lengthLimiter
* @param {OO.ui.TextInputWidget} textInputWidget
* @param {OO.ui.DropdownInputWidget} dropdownInputWidget Dropdown input widget
* @param {number} [limit]
*/
function internalVisibleLimitWithDropdown( lengthLimiter, textInputWidget, dropdownInputWidget, limit ) {
var filterFunction = function ( input ) {
var comment = dropdownInputWidget.getValue();
if ( comment === 'other' ) {
comment = input;
} else if ( input !== '' ) {
// Entry from drop down menu + additional comment
comment += colonSeparator + input;
}
return comment;
};
internalVisibleLimit( lengthLimiter, textInputWidget, limit, filterFunction );
// Keep the remaining counter in sync when reason list changed
dropdownInputWidget.on( 'change', function () {
textInputWidget.emit( 'change' );
} );
}
/**
* Loaded from `mediawiki.widgets.visibleLengthLimit` module.
* Add a visible byte limit label to a TextInputWidget.
*
* Uses jQuery#byteLimit to enforce the limit.
*
* @param {OO.ui.TextInputWidget} textInputWidget Text input widget
* @param {number} [limit] Byte limit, defaults to $input's maxlength
* @param {Function} [filterFunction] Function to call on the string before assessing the length.
*/
mw.widgets.visibleByteLimit = function ( textInputWidget, limit, filterFunction ) {
internalVisibleLimit( 'byteLimit', textInputWidget, limit, filterFunction );
};
/**
@ -52,31 +92,35 @@
* @param {Function} [filterFunction] Function to call on the string before assessing the length.
*/
mw.widgets.visibleCodePointLimit = function ( textInputWidget, limit, filterFunction ) {
limit = limit || +textInputWidget.$input.attr( 'maxlength' );
if ( !filterFunction || typeof filterFunction !== 'function' ) {
filterFunction = undefined;
}
internalVisibleLimit( 'codePointLimit', textInputWidget, limit, filterFunction );
};
function updateCount() {
var value = textInputWidget.getValue(),
remaining;
if ( filterFunction ) {
value = filterFunction( value );
}
remaining = limit - codePointLength( value );
if ( remaining > 99 ) {
remaining = '';
} else {
remaining = mw.language.convertNumber( remaining );
}
textInputWidget.setLabel( remaining );
}
textInputWidget.on( 'change', updateCount );
// Initialise value
updateCount();
/**
* Loaded from `mediawiki.widgets.visibleLengthLimit` module.
* Add a visible byte limit label to a TextInputWidget/DropdownInputWidget
*
* Uses jQuery#byteLimit to enforce the limit.
*
* @param {OO.ui.TextInputWidget} textInputWidget Text input widget
* @param {OO.ui.DropdownInputWidget} dropdownInputWidget Dropdown input widget
* @param {number} [limit] Code point limit, defaults to $input's maxlength
*/
mw.widgets.visibleByteLimitWithDropdown = function ( textInputWidget, dropdownInputWidget, limit ) {
internalVisibleLimitWithDropdown( 'byteLimit', textInputWidget, dropdownInputWidget, limit );
};
// Actually enforce limit
textInputWidget.$input.codePointLimit( limit, filterFunction );
/**
* Loaded from `mediawiki.widgets.visibleLengthLimit` module.
* Add a visible codepoint (character) limit label to a TextInputWidget/DropdownInputWidget
*
* Uses jQuery#codePointLimit to enforce the limit.
*
* @param {OO.ui.TextInputWidget} textInputWidget Text input widget
* @param {OO.ui.DropdownInputWidget} dropdownInputWidget Dropdown input widget
* @param {number} [limit] Code point limit, defaults to $input's maxlength
*/
mw.widgets.visibleCodePointLimitWithDropdown = function ( textInputWidget, dropdownInputWidget, limit ) {
internalVisibleLimitWithDropdown( 'codePointLimit', textInputWidget, dropdownInputWidget, limit );
};
}() );