Daniel Werner has submitted this change and it was merged.

Change subject: (bug 48145) Simplified input extender widget
......................................................................


(bug 48145) Simplified input extender widget

Change-Id: I7091801e90f0f665be4de3634847fdf054ea7b86
---
M ValueView/ValueView.i18n.php
M ValueView/ValueView.resources.mw.php
M ValueView/ValueView.resources.php
M ValueView/resources/jquery.time/jquery.time.timeinput.js
M ValueView/resources/jquery.ui/jquery.ui.inputextender.css
M ValueView/resources/jquery.ui/jquery.ui.inputextender.js
M ValueView/resources/jquery.ui/jquery.ui.listrotator.js
M ValueView/resources/jquery.valueview/valueview.css
M ValueView/resources/jquery.valueview/valueview.experts/experts.TimeInput.js
M ValueView/tests/qunit/jquery.ui/jquery.ui.inputextender.tests.js
10 files changed, 154 insertions(+), 271 deletions(-)

Approvals:
  Daniel Werner: Verified; Looks good to me, approved
  jenkins-bot: Verified



diff --git a/ValueView/ValueView.i18n.php b/ValueView/ValueView.i18n.php
index 0e625d2..71092c1 100644
--- a/ValueView/ValueView.i18n.php
+++ b/ValueView/ValueView.i18n.php
@@ -43,11 +43,11 @@
        // EmptyValue expert:
        'valueview-expert-emptyvalue-empty' => 'empty',
 
+       // TimeInput expert:
+       'valueview-expert-timeinput-precision' => 'Precision:',
+
        'valueview-preview-label' => 'will be displayed as:',
        'valueview-preview-novalue' => 'no valid value recognized',
-
-       'valueview-inputextender-showoptions' => 'show options',
-       'valueview-inputextender-hideoptions' => 'hide options',
 
        'valueview-listrotator-auto' => 'auto',
 );
@@ -63,10 +63,9 @@
        'valueview-expert-unsupportedvalue-unsupporteddatatype' => 'Error shown 
if a data value for a certain data type (see [[d:Wikidata:Glossary]]) should be 
displayed or a form for creating one should be offered while this is not yet 
possible from a technical point of view (e.g. because a valueview widget expert 
handling data values for that data type has not yet been implemented). 
Parameter $1 is the name of the data type which lacks support',
        'valueview-expert-emptyvalue-empty' => 'Message expressing that there 
is currently no value set in a jQuery valueview.
 {{Identical|Empty}}',
+       'valueview-expert-timeinput-precision' => 'Label for the user interface 
element used to set a specific precision (e.g. hour, day, month, year) when 
entering a time value.',
        'valueview-preview-label' => 'Label displayed above the preview of a 
value that is being entered by the user. The preview is the system\'s 
interpretation of the specified value and - since there is no strict definition 
for a user how to specify values - visualizes how the value will be displayed 
later on after the value has been saved.',
        'valueview-preview-novalue' => 'Message displayed instead of an input 
value\'s preview when no value is specified yet or when the specified value 
could not be interpreted by the system.',
-       'valueview-inputextender-showoptions' => 'Message of the link displayed 
next to an input element if there are detailed options for inputting a value. 
This message is shown, when the options are currently invisible. By clicking 
the link, the options are shown and can be adjusted.',
-       'valueview-inputextender-hideoptions' => 'Message of the link displayed 
next to an input element if there are detailed options for inputting a value. 
This message is shown, when the options are currently visible. By clicking the 
link, the options will be hidden.',
        'valueview-listrotator-auto' => 'Label of the link to have the system 
automatically select the most appropriate value from a "listrotator" widget. 
The "listrotator" basically is a facade for a drop-down select box allowing to 
pick a value from a list of values. In addition to the defined values, an 
"automatic" option may be selected that makes the system pick the most 
appropriate value according to an associated input element.',
 );
 
diff --git a/ValueView/ValueView.resources.mw.php 
b/ValueView/ValueView.resources.mw.php
index 462c1a5..856322d 100644
--- a/ValueView/ValueView.resources.mw.php
+++ b/ValueView/ValueView.resources.mw.php
@@ -105,11 +105,8 @@
                        ),
                        'dependencies' => array(
                                'jquery.eachchange',
+                               'jquery.ui.position',
                                'jquery.ui.widget',
-                       ),
-                       'messages' => array(
-                               'valueview-inputextender-showoptions',
-                               'valueview-inputextender-hideoptions',
                        ),
                ),
 
diff --git a/ValueView/ValueView.resources.php 
b/ValueView/ValueView.resources.php
index f9a294d..6b385a3 100644
--- a/ValueView/ValueView.resources.php
+++ b/ValueView/ValueView.resources.php
@@ -203,6 +203,7 @@
                                'jquery.ui.listrotator',
                        ),
                        'messages' => array(
+                               'valueview-expert-timeinput-precision',
                                'valueview-preview-label',
                                'valueview-preview-novalue',
                        ),
diff --git a/ValueView/resources/jquery.time/jquery.time.timeinput.js 
b/ValueView/resources/jquery.time/jquery.time.timeinput.js
index d1f6265..78c0b93 100644
--- a/ValueView/resources/jquery.time/jquery.time.timeinput.js
+++ b/ValueView/resources/jquery.time/jquery.time.timeinput.js
@@ -45,7 +45,7 @@
                 */
                destroy: function() {
                        this.element.removeClass( this.widgetName );
-                       $.ui.Widget.prototype.destroy.call( this );
+                       $.Widget.prototype.destroy.call( this );
                },
 
                /**
diff --git a/ValueView/resources/jquery.ui/jquery.ui.inputextender.css 
b/ValueView/resources/jquery.ui/jquery.ui.inputextender.css
index 4554dff..23efbde 100644
--- a/ValueView/resources/jquery.ui/jquery.ui.inputextender.css
+++ b/ValueView/resources/jquery.ui/jquery.ui.inputextender.css
@@ -5,25 +5,18 @@
  * @author H. Snater < [email protected] >
  */
 
-.ui-inputextender .ui-inputextender-input {
-       display: inline;
-}
-
-.ui-inputextender .ui-inputextender-extender {
-       display: inline;
-}
-
-.ui-inputextender .ui-inputextender-contentcontainer {
+.ui-inputextender-extension {
        position: absolute;
-       z-index: 1;
-       left: 2px;
-       font-size: 84%;
        padding: 2px;
+       font-size: 84%;
        box-shadow: 2px 2px 6px -1px grey;
 }
 
-.ui-inputextener .ui-inputextender-extendedcontent {
-       margin-top: 5px;
-       padding-top: 5px;
-       border-top: 1px dashed #CCC;
+.ui-inputextender-extension > * {
+       font-size: 84%;
+}
+
+.ui-inputextender-extension .ui-inputextender-contentnode {
+       float: left;
+       clear: both;
 }
diff --git a/ValueView/resources/jquery.ui/jquery.ui.inputextender.js 
b/ValueView/resources/jquery.ui/jquery.ui.inputextender.js
index 04e081e..6a28e8d 100644
--- a/ValueView/resources/jquery.ui/jquery.ui.inputextender.js
+++ b/ValueView/resources/jquery.ui/jquery.ui.inputextender.js
@@ -22,17 +22,6 @@
  *         hidden when the associated input element is empty.
  *         Default value: true
  *
- * @option {Object} [messages] Strings used within the widget.
- *         Messages should be specified using mwMsgOrString(<resource loader 
module message key>,
- *         <fallback message>) in order to use the messages specified in the 
resource loader module
- *         (if loaded).
- *         messages['show options'] {String} (optional) Label of the link 
showing any additional
- *         contents.
- *         Default value: 'show options'
- *         messages['hide options'] {String} (optional) Label of the link 
hiding any additional
- *         contents.
- *         Default value: 'hide options'
- *
  * @event toggle: Triggered when the visibility of the extended content is 
toggled.
  *        (1) {jQuery.Event}
  *
@@ -43,31 +32,11 @@
        'use strict';
 
        /**
-        * Whether loaded in MediaWiki context.
+        * Caches whether the widget is used in a rtl context. This, however, 
depends on using an "rtl"
+        * class on the document body like it is done in MediaWiki.
         * @type {boolean}
         */
-       var IS_MW_CONTEXT = ( typeof mw !== 'undefined' && mw.msg );
-
-       /**
-        * Whether actual inputextender resource loader module is loaded.
-        * @type {boolean}
-        */
-       var IS_MODULE_LOADED = (
-               IS_MW_CONTEXT
-               && $.inArray( 'jquery.ui.inputextender', 
mw.loader.getModuleNames() ) !== -1
-       );
-
-       /**
-        * Returns a message from the MediaWiki context if the input extender 
module has been loaded.
-        * If it has not been loaded, the corresponding string defined in the 
options will be returned.
-        *
-        * @param {String} msgKey
-        * @param {String} string
-        * @return {String}
-        */
-       function mwMsgOrString( msgKey, string ) {
-               return ( IS_MODULE_LOADED ) ? mw.msg( msgKey ) : string;
-       }
+       var isRtl = $( 'body' ).hasClass( 'rtl' );
 
        $.widget( 'ui.inputextender', {
                /**
@@ -76,56 +45,20 @@
                 */
                options: {
                        content: [],
-                       extendedContent: [],
                        initCallback: null,
                        hideWhenInputEmpty: true,
-                       messages: {
-                               'show options': mwMsgOrString( 
'valueview-inputextender-showoptions', 'show options' ),
-                               'hide options': mwMsgOrString( 
'valueview-inputextender-hideoptions', 'hide options' )
+                       position: {
+                               my: ( isRtl ) ? 'right top' : 'left top',
+                               at: ( isRtl ) ? 'right bottom' : 'left bottom',
+                               collision: 'none'
                        }
                },
 
                /**
-                * The widget parent's node.
+                * The input extension's node.
                 * @type {jQuery}
                 */
-               $parent: null,
-
-               /**
-                * Container node wrapping the widget's whole DOM structure.
-                * @type {jQuery}
-                */
-               $container: null,
-
-               /**
-                * Container node containing the input element and the extender.
-                * @type {jQuery}
-                */
-               $inputContainer: null,
-
-               /**
-                * Node of the link to extended the extenders additional 
content.
-                * @type {jQuery}
-                */
-               $extender: null,
-
-               /**
-                * Node containing all the extension content.
-                * @type {jQuery}
-                */
-               $contentContainer: null,
-
-               /**
-                * Node of the default/"fixed" extension content.
-                * @type {jQuery}
-                */
-               $content: null,
-
-               /**
-                * Node of the additional extension content shown/hidden by the 
extender link.
-                * @type {jQuery}
-                */
-               $extendedContent: null,
+               $extension: null,
 
                /**
                 * Caches the timeout when the actual "blur" action should kick 
in.
@@ -139,78 +72,43 @@
                _create: function() {
                        var self = this;
 
-                       this.$parent = this.element.parent();
+                       this.element
+                       .addClass( this.widgetBaseClass + '-input' );
 
-                       if( !this.$parent.length ) {
-                               throw new Error( 'Input extender widget needs 
to be in the DOM when initializing.' );
-                       }
-
-                       this.$container = $( '<div/>' )
-                       .addClass( this.widgetBaseClass )
-                       .appendTo( this.$parent );
-
-                       this.$inputContainer = $( '<div />' )
-                       .addClass( this.widgetBaseClass + '-inputcontainer' )
-                       .append( this.element.addClass( this.widgetBaseClass + 
'-input' ).detach() )
-                       .appendTo( this.$container );
-
-                       this.$extender = $( '<a/>' )
-                       .addClass( this.widgetBaseClass + '-extender' )
-                       .attr( 'href', 'javascript:void(0);' )
-                       .text( this.options.messages['show options'] )
-                       .appendTo( this.$inputContainer )
-                       .on( 'click', function( event ) {
-                               clearTimeout( self._blurTimeout );
-                               self._toggleExtension();
-                       } )
-                       .on( 'keydown', function( event ) {
-                               if( event.keyCode === $.ui.keyCode.ENTER ) {
-                                       clearTimeout( self._blurTimeout );
-                                       self._toggleExtension();
-                               }
-                       } )
-                       .on( 'focus', function( event ) {
-                               clearTimeout( self._blurTimeout );
-                       } )
-                       .hide();
-
-                       this.$contentContainer = $( '<div/>' )
-                       .addClass( this.widgetBaseClass + '-contentcontainer 
ui-widget-content' )
-                       .appendTo( this.$container )
+                       this.$extension = $( '<div/>' )
+                       .addClass( this.widgetBaseClass + '-extension 
ui-widget-content' )
                        .on( 'click.' + this.widgetName, function( event ) {
                                clearTimeout( self._blurTimeout );
-                       } );
+                               event.stopPropagation();
+                               self.showExtension();
+                       } )
+                       .appendTo( $( 'body' ) );
 
-                       this.$content = $( '<div/>' )
-                       .addClass( this.widgetBaseClass + '-content' )
-                       .appendTo( this.$contentContainer );
-
-                       this.$extendedContent = $( '<div/>' )
-                       .addClass( this.widgetBaseClass + '-extendedcontent' )
-                       .appendTo( this.$contentContainer );
-
-                       this.element.add( this.$extender )
+                       this.element
                        .on( 'focus.' + this.widgetName, function( event ) {
                                if( !self.options.hideWhenInputEmpty || 
self.element.val() !== '' ) {
                                        clearTimeout( self._blurTimeout );
-                                       self.showContent();
+                                       self.showExtension();
                                }
                        } )
-                       // TODO: Do not hide when tabbing into the 
inputextender's contents
+                       // TODO: Allow direct tabbing into the extension
                        .on( 'blur.' + this.widgetName, function( event ) {
                                self._blurTimeout = setTimeout( function() {
-                                       self.hideContent( function() {
-                                               self._toggleExtension( { 
forceHide: true } );
-                                       } );
+                                       self.hideExtension();
                                }, 150 );
+                       } )
+                       .on( 'keydown.' + this.widgetName, function( event ) {
+                               if( event.keyCode === $.ui.keyCode.ESCAPE ) {
+                                       self.hideExtension();
+                               }
                        } );
 
                        if( this.options.hideWhenInputEmpty ) {
                                this.element.eachchange( function( event, 
oldValue ) {
-                                       if( self.element.val() === '' && 
!self.$extendedContent.is( ':visible' ) ) {
-                                               self.hideContent();
+                                       if( self.element.val() === '' ) {
+                                               self.hideExtension();
                                        } else if ( oldValue === '' ) {
-                                               self.showContent();
+                                               self.showExtension();
                                        }
                                } );
                        }
@@ -226,9 +124,7 @@
                                                        $( event.target 
).closest( widget.$container ).length === 0
                                                        && !widget.element.is( 
':focus' )
                                                ) {
-                                                       widget.hideContent( 
function() {
-                                                               
widget._toggleExtension( { forceHide: true } );
-                                                       } );
+                                                       widget.hideExtension();
                                                }
                                        } );
                                } );
@@ -240,17 +136,18 @@
                                this.options.initCallback();
                        }
 
-                       this.$contentContainer.hide();
-                       this.$extendedContent.hide();
+                       $.each( this.options.content, function( i, node ) {
+                               $( node ).addClass( self.widgetBaseClass + 
'-contentnode' );
+                       } );
+
+                       this.$extension.hide();
                },
 
                /**
                 * @see jQuery.Widget.destroy
                 */
                destroy: function() {
-                       var $input = this.element.detach();
-                       this.$container.remove();
-                       this.$parent.append( $input );
+                       this.$extension.remove();
                        if( $( ':' + this.widgetBaseClass ).length === 0 ) {
                                $( 'html' ).off( '.' + this.widgetName );
                        }
@@ -258,71 +155,34 @@
                },
 
                /**
-                * Draws the widget according to its current state.
+                * Draws the widget.
                 */
                _draw: function() {
                        var self = this;
 
-                       this.$content.empty();
-
-                       // Only show the extender when there are any additional 
options to extend:
-                       this.$extender[ ( this.options.extendedContent.length ) 
? 'show' : 'hide' ]();
+                       this.$extension.empty();
 
                        $.each( this.options.content, function( i, $node ) {
-                               self.$content.append( $node );
-                       } );
-
-                       $.each( this.options.extendedContent, function( i, 
$node ) {
-                               self.$extendedContent.append( $node );
+                               self.$extension.append( $node );
                        } );
                },
 
                /**
-                * Toggles the visibility of the additional options.
-                *
-                * @param {Object|undefined} customOptions
-                */
-               _toggleExtension: function( customOptions ) {
-                       var self = this,
-                               options = {
-                                       moveFocus: true,
-                                       forceHide: false
-                               };
-
-                       $.extend( options, customOptions );
-
-                       function hideExtendedContent() {
-                               self.$extendedContent.slideUp( 150, function() {
-                                       self.$extender.text( 
self.options.messages['show options'] );
-                                       self._trigger( 'toggle' );
-                               } );
-                       }
-
-                       if( options.forceHide ) {
-                               hideExtendedContent();
-                               return;
-                       }
-
-                       if( this.$extendedContent.is( ':visible' ) ) {
-                               this.showContent( hideExtendedContent );
-                       } else {
-                               this.showContent( function() {
-                                       self.$extendedContent.slideDown( 150, 
function() {
-                                               self.$extender.text( 
self.options.messages['hide options'] );
-                                               self._trigger( 'toggle' );
-                                       } );
-                               } );
-                       }
-
-               },
-
-               /**
-                * Shows all the extension contents.
+                * Shows the extension.
                 *
                 * @param {Function} [callback] Invoked as soon as the contents 
are visible.
                 */
-               showContent: function( callback ) {
-                       this.$contentContainer.stop( true, true ).fadeIn( 150, 
function() {
+               showExtension: function( callback ) {
+                       // Element needs to be visible to use 
jquery.ui.position.
+                       if( !this.$extension.is( ':visible' ) ) {
+                               this.$extension.show();
+                               this.$extension.position( $.extend( {
+                                       of: this.element
+                               }, this.options.position ) );
+                               this.$extension.hide();
+                       }
+
+                       this.$extension.stop( true, true ).fadeIn( 150, 
function() {
                                if( $.isFunction( callback ) ) {
                                        callback();
                                }
@@ -330,12 +190,12 @@
                },
 
                /**
-                * Hides all the extension contents.
+                * Hides the extension.
                 *
                 * @param {Function} [callback] Invoked as soon as the contents 
are hidden.
                 */
-               hideContent: function( callback ) {
-                       this.$contentContainer.stop( true, true ).fadeOut( 150, 
function() {
+               hideExtension: function( callback ) {
+                       this.$extension.stop( true, true ).fadeOut( 150, 
function() {
                                if( $.isFunction( callback ) ) {
                                        callback();
                                }
diff --git a/ValueView/resources/jquery.ui/jquery.ui.listrotator.js 
b/ValueView/resources/jquery.ui/jquery.ui.listrotator.js
index 1d139aa..b73a0d8 100644
--- a/ValueView/resources/jquery.ui/jquery.ui.listrotator.js
+++ b/ValueView/resources/jquery.ui/jquery.ui.listrotator.js
@@ -173,7 +173,7 @@
                                self._trigger( 'auto' );
                        } )
                        .addClass( 'ui-state-active' );
-                       this.$auto.children( 'a' ).text( 
this.options.messages['show options'] );
+                       this.$auto.children( 'a' ).text( 
this.options.messages['auto'] );
 
                        // Construct the basic sections:
                        this.$curr = this._createSection( 'curr', function( 
event ) {
@@ -294,10 +294,10 @@
                                if( width > currMaxWidth ) {
                                        currMaxWidth = width;
                                }
-                               if( i > 0 && width > prevMaxWidth ) {
+                               if( i < stringWidths.length && width > 
prevMaxWidth ) {
                                        prevMaxWidth = width;
                                }
-                               if( i < stringWidths.length && width > 
nextMaxWidth ) {
+                               if( i > 0 && width > nextMaxWidth ) {
                                        nextMaxWidth = width;
                                }
                        } );
diff --git a/ValueView/resources/jquery.valueview/valueview.css 
b/ValueView/resources/jquery.valueview/valueview.css
index 6bdf022..faa1393 100644
--- a/ValueView/resources/jquery.valueview/valueview.css
+++ b/ValueView/resources/jquery.valueview/valueview.css
@@ -39,16 +39,16 @@
        background-color: white;
 }
 
-.valueview .valueview-preview-value {
-       font-size: 119%; /* Reset to default 100% */
-}
-
-.valueview .valueview-preview-novalue {
-       font-style: italic;
-}
-
 .valueview-ineditmode.linkedsingleinputvalueview a,
 .valueview-ineditmode.linkedsingleinputvalueview a {
        /* make sure input box which still is inside a doesn't display text as 
links */
        color: inherit;
 }
+
+.valueview-preview-value {
+       font-size: 119%; /* Reset to default 100% */
+}
+
+.valueview-preview-novalue {
+       font-style: italic;
+}
diff --git 
a/ValueView/resources/jquery.valueview/valueview.experts/experts.TimeInput.js 
b/ValueView/resources/jquery.valueview/valueview.experts/experts.TimeInput.js
index 4525de1..2d9fa59 100644
--- 
a/ValueView/resources/jquery.valueview/valueview.experts/experts.TimeInput.js
+++ 
b/ValueView/resources/jquery.valueview/valueview.experts/experts.TimeInput.js
@@ -51,6 +51,12 @@
                $previewValue: null,
 
                /**
+                * Node of the widget used to specify the precision.
+                * @type {jQuery}
+                */
+               $precision: null,
+
+               /**
                 * @see jQuery.valueview.Expert._init
                 */
                _init: function() {
@@ -77,14 +83,14 @@
 
                        this.$precision = $( '<div/>' )
                        .listrotator( { values: precisionValues.reverse(), 
deferInit: true } )
-                       .on( 'listrotatorauto', function( event ) {
+                       .on( 'listrotatorauto.' + this.uiBaseClass, function( 
event ) {
                                var value = new Time( self.$input.val() );
                                $( this ).data( 'listrotator' ).rotate( 
value.precision() );
                                self._setRawValue( value );
                                self._updatePreview( value );
                                self._viewNotifier.notify( 'change' );
                        } )
-                       .on( 'listrotatorselected', function( event, precision 
) {
+                       .on( 'listrotatorselected.' + this.uiBaseClass, 
function( event, precision ) {
                                var value = new Time( self.$input.val(), 
precision );
                                self._setRawValue( value );
                                self._updatePreview( value );
@@ -106,13 +112,12 @@
                        // TODO: Move input extender out of here to a more 
generic place since it is not
                        // TimeInput specific.
                        .inputextender( {
-                               content: [ this.$preview ],
-                               extendedContent: [ this.$precision ],
+                               content: [ this.$preview, this.$precision ],
                                initCallback: function() {
                                        self.$precision.data( 'listrotator' 
).initWidths();
                                }
                        } )
-                       .on( 'timeinputupdate', function( event, value ) {
+                       .on( 'timeinputupdate.' + this.uiBasClass, function( 
event, value ) {
                                self._updatePreview( value );
                                if( value && value.isValid() ) {
                                        self.$precision.data( 'listrotator' 
).rotate( value.precision() );
@@ -120,6 +125,21 @@
                                self._viewNotifier.notify( 'change' );
                        } );
 
+               },
+
+               /**
+                * @see jQuery.valueview.Expert.destroy
+                */
+               destroy: function() {
+                       this.$precision.data( 'listrotator' ).destroy();
+                       this.$precision.remove();
+                       this.$previewValue.remove();
+                       this.$preview.remove();
+                       this.$input.data( 'inputextender' ).destroy();
+                       this.$input.data( 'timeinput' ).destroy();
+                       this.$input.remove();
+
+                       PARENT.prototype.destroy.call( this );
                },
 
                /**
@@ -147,7 +167,7 @@
                },
 
                /**
-                * @see Query.valueview.Expert.parser
+                * @see jQuery.valueview.Expert.parser
                 */
                parser: function() {
                        return new vp.TimeParser();
diff --git a/ValueView/tests/qunit/jquery.ui/jquery.ui.inputextender.tests.js 
b/ValueView/tests/qunit/jquery.ui/jquery.ui.inputextender.tests.js
index 598c654..ff20094 100644
--- a/ValueView/tests/qunit/jquery.ui/jquery.ui.inputextender.tests.js
+++ b/ValueView/tests/qunit/jquery.ui/jquery.ui.inputextender.tests.js
@@ -9,7 +9,6 @@
 ( function( $, QUnit ) {
        'use strict';
 
-       // TODO: Tests for toggling additional contents
        // TODO: Tests for hideWhenInputEmptyOption
 
        /**
@@ -18,68 +17,82 @@
        var newTestInputextender = function( options ) {
                if( !options ) {
                        options = {
-                               content: [ $( '<span/>' ).addClass( 
'defaultContent' ).text( 'default content' ) ],
-                               extendedContent: [ $( '<span/>' ).addClass( 
'extendedContent' ).text( 'extended content' ) ]
+                               content: [ $( '<span/>' ).addClass( 
'defaultContent' ).text( 'default content' ) ]
                        }
                }
 
-               return $( '<input/>' )
+               var $input = $( '<input/>' )
                        .addClass( 'test_inputextender' )
                        .appendTo( $( 'body' ) )
                        .inputextender( options );
+
+               return $input.data( 'inputextender' );
        };
 
        QUnit.module( 'jquery.ui.inputextender', QUnit.newMwEnvironment( {
                teardown: function() {
                        $( '.test_inputextender' ).each( function( i, node ) {
-                               $( node ).data( 'inputextender' ).destroy();
+                               if( $( node ).data( 'inputextender' ) ) {
+                                       $( node ).data( 'inputextender' 
).destroy();
+                               }
                                $( node ).remove();
                        } );
                }
        } ) );
 
-       QUnit.test( 'Initialization', 1, function( assert ) {
-               var $input = newTestInputextender(),
-                       extender = $input.data( 'inputextender' );
+       QUnit.test( 'Initialization', 4, function( assert ) {
+               var extender = newTestInputextender(),
+                       widgetBaseClass = extender.widgetBaseClass;
+
+               assert.equal(
+                       $( '.test_inputextender' ).data( 'inputextender' ),
+                       extender,
+                       'Initialized widget.'
+               );
 
                assert.ok(
-                       !extender.$contentContainer.is( ':visible' ),
-                       'Content is not visible.'
+                       !extender.$extension.is( ':visible' ),
+                       'Extension is not visible.'
+               );
+
+               extender.destroy();
+
+               assert.ok(
+                       $( '.test_inputextender' ).data( 'inputextender' ) === 
undefined,
+                       'Destroyed widget.'
+               );
+
+               assert.equal(
+                       $( '.' + widgetBaseClass + '-extension' ).length,
+                       0,
+                       'Removed extension node from DOM.'
                );
        } );
 
-       QUnit.test( 'Show/Hide basic content', 4, function( assert ) {
-               var $input = newTestInputextender(),
-                       extender = $input.data( 'inputextender' );
-
-               extender.showContent( function() {
-                       assert.ok(
-                               extender.$contentContainer.is( ':visible' ),
-                               'Content visible after focusing input element.'
-                       );
-
-                       assert.ok(
-                               extender.$content.is( ':visible' ),
-                               'Default content is visible.'
-                       );
-
-                       assert.ok(
-                               !extender.$extendedContent.is( ':visible' ),
-                               'Additional content is hidden.'
-                       );
-               } );
+       QUnit.test( 'Show/Hide', 2, function( assert ) {
+               var extender = newTestInputextender();
 
                QUnit.stop();
 
-               extender.hideContent( function() {
+               extender.showExtension( function() {
                        assert.ok(
-                               !extender.$contentContainer.is( ':visible' ),
-                               'Content is hidden after blurring the input 
element.'
+                               extender.$extension.is( ':visible' ),
+                               'showExtension()'
                        );
+
+                       QUnit.stop();
+
+                       extender.hideExtension( function() {
+                               assert.ok(
+                                       !extender.$extension.is( ':visible' ),
+                                       'hideExtension()'
+                               );
+
+                               QUnit.start();
+                       } );
 
                        QUnit.start();
                } );
-
        } );
 
 }( jQuery, QUnit ) );

-- 
To view, visit https://gerrit.wikimedia.org/r/62586
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I7091801e90f0f665be4de3634847fdf054ea7b86
Gerrit-PatchSet: 13
Gerrit-Project: mediawiki/extensions/DataValues
Gerrit-Branch: master
Gerrit-Owner: Henning Snater <[email protected]>
Gerrit-Reviewer: Daniel Werner <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to