TitleInputWidget: Add 'maxLength' of 255 and use $.byteLimit
authorBartosz Dziewoński <matma.rex@gmail.com>
Wed, 12 Aug 2015 14:56:08 +0000 (16:56 +0200)
committerBartosz Dziewoński <matma.rex@gmail.com>
Thu, 20 Aug 2015 15:25:18 +0000 (17:25 +0200)
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
resources/Resources.php
resources/src/jquery/jquery.byteLimit.js
resources/src/mediawiki.widgets/mw.widgets.TitleInputWidget.js

index e2b7fda..8ac7014 100644 (file)
@@ -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'] ) ) {
index 5ac00fe..f8ee1dc 100644 (file)
@@ -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
index 5551232..e2315d2 100644 (file)
@@ -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;
 
                        // 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,
                                        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
index 4e3228f..3697a1c 100644 (file)
@@ -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;
        };
 
        /**
-        * 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
         */