From 6b79105034ecc1abae6cf458380d283580480a32 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bartosz=20Dziewo=C5=84ski?= Date: Wed, 12 Aug 2015 16:56:08 +0200 Subject: [PATCH] TitleInputWidget: Add 'maxLength' of 255 and use $.byteLimit Integrate $.byteLimit functionality into OOjs UI's value preprocessing (#cleanUpValue), rather than just calling in on #$input, to avoid validity state flashing back and forth when the value is limitted. Bug: T106454 Change-Id: I3d24e4bf7427c9bd922ff2e24edc9583ee0aaecb --- includes/widget/TitleInputWidget.php | 2 +- resources/Resources.php | 10 ++++++--- resources/src/jquery/jquery.byteLimit.js | 8 ++++--- .../mw.widgets.TitleInputWidget.js | 22 +++++++++++++++---- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/includes/widget/TitleInputWidget.php b/includes/widget/TitleInputWidget.php index e2b7fda21a..8ac7014eb8 100644 --- a/includes/widget/TitleInputWidget.php +++ b/includes/widget/TitleInputWidget.php @@ -24,7 +24,7 @@ class TitleInputWidget extends \OOUI\TextInputWidget { */ public function __construct( array $config = array() ) { // Parent constructor - parent::__construct( array_merge( array( 'infusable' => true ), $config ) ); + parent::__construct( array_merge( array( 'infusable' => true, 'maxLength' => 255 ), $config ) ); // Properties, which are ignored in PHP and just shipped back to JS if ( isset( $config['namespace'] ) ) { diff --git a/resources/Resources.php b/resources/Resources.php index 5ac00fe444..f8ee1dc46b 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -1826,12 +1826,16 @@ return array( ), ), 'dependencies' => array( + 'oojs-ui', 'mediawiki.widgets.styles', - 'jquery.autoEllipsis', + // DateInputWidget + 'moment', + // TitleInputWidget 'mediawiki.Title', 'mediawiki.api', - 'moment', - 'oojs-ui', + 'jquery.byteLimit', + // TitleOptionWidget + 'jquery.autoEllipsis', ), 'messages' => array( // DateInputWidget diff --git a/resources/src/jquery/jquery.byteLimit.js b/resources/src/jquery/jquery.byteLimit.js index 5551232a55..e2315d2326 100644 --- a/resources/src/jquery/jquery.byteLimit.js +++ b/resources/src/jquery/jquery.byteLimit.js @@ -20,7 +20,7 @@ * @return {string} return.newVal * @return {boolean} return.trimmed */ - function trimValForByteLength( safeVal, newVal, byteLimit, fn ) { + function trimValueForByteLength( safeVal, newVal, byteLimit, fn ) { var startMatches, endMatches, matchesLen, inpParts, oldVal = safeVal; @@ -206,7 +206,7 @@ // See http://www.w3.org/TR/DOM-Level-3-Events/#events-keyboard-event-order for // the order and characteristics of the key events. $el.on( eventKeys, function () { - var res = trimValForByteLength( + var res = trimValueForByteLength( prevSafeVal, this.value, elLimit, @@ -221,13 +221,15 @@ this.value = res.newVal; } // Always adjust prevSafeVal to reflect the input value. Not doing this could cause - // trimValForByteLength to compare the new value to an empty string instead of the + // trimValueForByteLength to compare the new value to an empty string instead of the // old value, resulting in trimming always from the end (bug 40850). prevSafeVal = res.newVal; } ); } ); }; + $.fn.byteLimit.trimValueForByteLength = trimValueForByteLength; + /** * @class jQuery * @mixins jQuery.plugin.byteLimit diff --git a/resources/src/mediawiki.widgets/mw.widgets.TitleInputWidget.js b/resources/src/mediawiki.widgets/mw.widgets.TitleInputWidget.js index 4e3228f70c..3697a1c633 100644 --- a/resources/src/mediawiki.widgets/mw.widgets.TitleInputWidget.js +++ b/resources/src/mediawiki.widgets/mw.widgets.TitleInputWidget.js @@ -29,7 +29,7 @@ var widget = this; // Config initialization - config = config || {}; + config = $.extend( { maxLength: 255 }, config ); // Parent constructor mw.widgets.TitleInputWidget.parent.call( this, $.extend( {}, config, { autocomplete: false } ) ); @@ -39,6 +39,7 @@ // Properties this.limit = config.limit || 10; + this.maxLength = config.maxLength; this.namespace = config.namespace !== undefined ? config.namespace : null; this.relative = config.relative !== undefined ? config.relative : true; this.suggestions = config.suggestions !== undefined ? config.suggestions : true; @@ -282,18 +283,31 @@ }; /** - * Get title object corresponding to #getValue + * Get title object corresponding to given value, or #getValue if not given. * + * @param {string} [value] Value to get a title for * @returns {mw.Title|null} Title object, or null if value is invalid */ - mw.widgets.TitleInputWidget.prototype.getTitle = function () { - var title = this.getValue(), + mw.widgets.TitleInputWidget.prototype.getTitle = function ( value ) { + var title = value !== undefined ? value : this.getValue(), // mw.Title doesn't handle null well titleObj = mw.Title.newFromText( title, this.namespace !== null ? this.namespace : undefined ); return titleObj; }; + /** + * @inheritdoc + */ + mw.widgets.TitleInputWidget.prototype.cleanUpValue = function ( value ) { + var widget = this; + value = mw.widgets.TitleInputWidget.parent.prototype.cleanUpValue.call( this, value ); + return $.fn.byteLimit.trimValueForByteLength( this.value, value, this.maxLength, function ( value ) { + var title = widget.getTitle( value ); + return title ? title.getMain() : value; + } ).newVal; + }; + /** * @inheritdoc */ -- 2.20.1