Henning Snater has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/172507

Change subject: Implemented EditableTemplated widget
......................................................................

Implemented EditableTemplated widget

TemplatedWidget is supposed to be the common base constructor for all 
wikibase.*view
widgets. ->72666

Change-Id: Ib21c2d50d1acd0c32024ad226956cd0840fe3e13
---
M lib/resources/Resources.php
A lib/resources/jquery.ui/jquery.ui.EditableTemplatedWidget.js
M lib/resources/jquery.wikibase/jquery.wikibase.aliasesview.js
M lib/resources/jquery.wikibase/resources.php
A lib/tests/qunit/jquery.ui/jquery.ui.EditableTemplatedWidget.tests.js
M lib/tests/qunit/jquery.wikibase/jquery.wikibase.aliasesview.tests.js
M lib/tests/qunit/resources.php
7 files changed, 487 insertions(+), 155 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase 
refs/changes/07/172507/1

diff --git a/lib/resources/Resources.php b/lib/resources/Resources.php
index bd7ce2a..689f73a 100644
--- a/lib/resources/Resources.php
+++ b/lib/resources/Resources.php
@@ -140,6 +140,17 @@
                        ),
                ),
 
+               'jquery.ui.EditableTemplatedWidget' => $moduleTemplate + array(
+                       'scripts' => array(
+                               
'jquery.ui/jquery.ui.EditableTemplatedWidget.js',
+                       ),
+                       'dependencies' => array(
+                               'jquery.ui.TemplatedWidget',
+                               'util.inherit',
+                               'wikibase.templates',
+                       ),
+               ),
+
                'jquery.ui.tagadata' => $moduleTemplate + array(
                        'scripts' => array(
                                'jquery.ui/jquery.ui.tagadata.js',
diff --git a/lib/resources/jquery.ui/jquery.ui.EditableTemplatedWidget.js 
b/lib/resources/jquery.ui/jquery.ui.EditableTemplatedWidget.js
new file mode 100644
index 0000000..5d9daa2
--- /dev/null
+++ b/lib/resources/jquery.ui/jquery.ui.EditableTemplatedWidget.js
@@ -0,0 +1,257 @@
+/**
+ * @licence GNU GPL v2+
+ * @author H. Snater < [email protected] >
+ */
+( function( $ ) {
+       'use strict';
+
+       var PARENT =  $.ui.TemplatedWidget;
+
+/**
+ * TemplatedWidget enhanced with editing capabilities.
+ * @constructor
+ * @abstract
+ * @extends jQuery.ui.TemplatedWidget
+ * @since 0.5
+ *
+ * @option {*} [value]
+ *
+ * @event afterstartediting
+ *        Triggered after having started the widget's edit mode and edit mode 
has been rendered.
+ *        - {jQuery.Event}
+ *
+ * @event stopediting
+ *        Triggered when stopping the widget's edit mode, immediately before 
re-drawing.
+ *        - {jQuery.Event}
+ *        - {boolean} dropValue
+ *          Whether the widget's value will be reset to the one from before 
starting edit mode.
+ *
+ * @event afterstopediting
+ *        Triggered after having stopped the widget's edit mode and non-edit 
mode is redrawn.
+ *        - {jQuery.Event}
+ *        - {boolean} dropValue
+ *          Whether the widget's value has been reset to the one from before 
starting edit mode.
+ *
+ * @event change
+ *        Triggered whenever the widget's value is changed.
+ *        - {jQuery.Event} event
+ *
+ * @event toggleerror
+ *        Triggered when an error occurred or has been resolved.
+ *        - {jQuery.Event}
+ *        - {Error|undefined}
+ */
+$.widget( 'ui.EditableTemplatedWidget', PARENT, {
+       /**
+        * @see jQuery.ui.TemplatedWidget.options
+        */
+       options: $.extend( true, {}, PARENT.prototype.options, {
+               value: null
+       } ),
+
+       /**
+        * @see jQuery.ui.TemplatedWidget._create
+        */
+       _create: function() {
+               PARENT.prototype._create.call( this );
+       },
+
+       /**
+        * @see jQuery.ui.TemplatedWidget.destroy
+        */
+       destroy: function() {
+               this.element.removeClass( 'wb-edit' );
+               PARENT.prototype.destroy.call( this );
+       },
+
+       /**
+        * Draws the widget according to whether it is in edit mode or not.
+        *
+        * @return {Object} jQuery.Promise
+        *         No resolved parameters.
+        *         Rejected parameters:
+        *         - {Error}
+        */
+       _draw: util.abstractMember,
+
+       /**
+        * Starts the widget's edit mode.
+        *
+        * @return {Object} jQuery.Promise
+        *         No resolved parameters.
+        *         Rejected parameters:
+        *         - {Error}
+        */
+       startEditing: function() {
+               var deferred = $.Deferred();
+
+               if( this.isInEditMode() ) {
+                       return deferred.resolve().promise();
+               }
+
+               var self = this;
+
+               self.element.addClass( 'wb-edit' );
+
+               this._draw()
+               .done( function() {
+                       self._trigger( 'afterstartediting' );
+                       deferred.resolve();
+               } )
+               .fail( function( error ) {
+                       deferred.reject( error );
+               } );
+
+               return deferred.promise();
+       },
+
+       /**
+        * Stops the widget's edit mode.
+        *
+        * @param {boolean} dropValue
+        * @return {Object} jQuery.Promise
+        *         Resolved parameters:
+        *         - {boolean} dropValue
+        *         Rejected parameters:
+        *         - {Error}
+        */
+       stopEditing: function( dropValue ) {
+               var self = this,
+                       deferred = $.Deferred();
+
+               if( !this.isInEditMode() || ( !this.isValid() || 
this.isInitialValue() ) && !dropValue ) {
+                       return deferred.resolve().promise();
+               }
+
+               this._trigger( 'stopediting', null, [dropValue] );
+
+               this.disable();
+
+               if( dropValue ) {
+                       return this._afterStopEditing( dropValue );
+               } else {
+                       this._save()
+                       .done( function() {
+                               self.options.value = self.value();
+                               self._afterStopEditing( dropValue )
+                               .done( function() {
+                                       deferred.resolve( dropValue );
+                               } )
+                               .fail( function( error ) {
+                                       deferred.reject( error );
+                               } );
+                       } )
+                       .fail( function( error ) {
+                               self.setError( error );
+                               deferred.reject( error );
+                       } );
+               }
+
+               return deferred.promise();
+       },
+
+       /**
+        * @return {Object} jQuery.Promise
+        *         No resolved parameters.
+        *         Rejected parameters:
+        *         - {Error}
+        */
+       _save: util.abstractMember,
+
+       /**
+        * @param {boolean} dropValue
+        * @return {Object} jQuery.Promise
+        *         No resolved parameters.
+        *         Rejected parameters:
+        *         - {Error}
+        */
+       _afterStopEditing: function( dropValue ) {
+               var self = this,
+                       deferred = $.Deferred();
+
+               self.element.removeClass( 'wb-edit' );
+
+               this._draw()
+               .done( function() {
+                       self.enable();
+                       self._trigger( 'afterstopediting', null, [dropValue] );
+                       deferred.resolve( dropValue );
+               } )
+               .fail( function( error ) {
+                       self.setError( error );
+                       deferred.reject( error );
+               } );
+
+               return deferred.promise();
+       },
+
+       /**
+        * Cancels the widget's edit mode.
+        */
+       cancelEditing: function() {
+               this.stopEditing( true );
+       },
+
+       /**
+        * Returns whether the widget is in edit mode.
+        */
+       isInEditMode: function() {
+               return this.element.hasClass( 'wb-edit' );
+       },
+
+       /**
+        * Sets/Gets the widget's current value.
+        * When the widget is in edit mode, this.option( 'value' ) may be used 
to retrieve the widget's
+        * value from before edit mode has been started.
+        *
+        * @param {*} [value]
+        * @return {*|undefined}
+        */
+       value: util.abstractMember,
+
+       /**
+        * Returns whether the widget features any value (may it be valid or 
invalid).
+        *
+        * @return {boolean}
+        */
+       isEmpty: util.abstractMember,
+
+       /**
+        * Returns whether the widget's value is valid.
+        *
+        * @return {boolean}
+        */
+       isValid: util.abstractMember,
+
+       /**
+        * Returns whether the widget's value is the widget's value from before 
starting edit mode.
+        * (Always returns "true" in non-edit mode.)
+        *
+        * @return {boolean}
+        */
+       isInitialValue: util.abstractMember,
+
+       /**
+        * Toggles error state.
+        *
+        * @param {Error} [error]
+        */
+       setError: function( error ) {
+               if( error ) {
+                       this.element.addClass( 'wb-error' );
+                       this._trigger( 'toggleerror', null, [error] );
+               } else {
+                       this.removeError();
+                       this._trigger( 'toggleerror', null, [null] );
+               }
+       },
+
+       /**
+        * Removes error state without triggering an event.
+        */
+       removeError: function() {
+               this.element.removeClass( 'wb-error' );
+       }
+} );
+
+}( jQuery ) );
diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.aliasesview.js 
b/lib/resources/jquery.wikibase/jquery.wikibase.aliasesview.js
index f94ded8..635ea8d 100644
--- a/lib/resources/jquery.wikibase/jquery.wikibase.aliasesview.js
+++ b/lib/resources/jquery.wikibase/jquery.wikibase.aliasesview.js
@@ -5,12 +5,12 @@
 ( function( $, mw, wb ) {
        'use strict';
 
-       var PARENT = $.ui.TemplatedWidget;
+       var PARENT = $.ui.EditableTemplatedWidget;
 
 /**
- * Manages a aliases.
+ * Manages aliases.
  * @since 0.5
- * @extends jQuery.ui.TemplatedWidget
+ * @extends jQuery.ui.EditableTemplatedWidget
  *
  * @option {wikibase.datamodel.MultiTerm} value
  *
@@ -21,7 +21,7 @@
  */
 $.widget( 'wikibase.aliasesview', PARENT, {
        /**
-        * @see jQuery.ui.TemplatedWidget.options
+        * @see jQuery.ui.EditableTemplatedWidget.options
         */
        options: {
                template: 'wikibase-aliasesview',
@@ -41,14 +41,7 @@
        },
 
        /**
-        * @type {boolean}
-        */
-       _isInEditMode: false,
-
-       /**
         * @see jQuery.ui.TemplatedWidget._create
-        *
-        * @throws {Error} if required parameters are not specified properly.
         */
        _create: function() {
                if(
@@ -69,29 +62,14 @@
        },
 
        /**
-        * @see jQuery.ui.TemplatedWidget.destroy
-        */
-       destroy: function() {
-               if( this._isInEditMode ) {
-                       var self = this;
-
-                       this.element.one( this.widgetEventPrefix + 
'afterstopediting', function( event ) {
-                               PARENT.prototype.destroy.call( self );
-                       } );
-
-                       this.cancelEditing();
-               } else {
-                       PARENT.prototype.destroy.call( this );
-               }
-       },
-
-       /**
-        * Main draw routine.
+        * @see jQuery.ui.EditableTemplatedWidget._draw
         */
        _draw: function() {
                this.$list.off( '.' + this.widgetName );
 
-               if( !this._isInEditMode ) {
+               if( this.isInEditMode() ) {
+                       this._initTagadata();
+               } else {
                        var self = this,
                                tagadata = this.$list.data( 'tagadata' );
 
@@ -99,22 +77,14 @@
                                tagadata.destroy();
                        }
 
-                       this.element.removeClass( 'wb-edit' );
-
                        this.$list.empty();
 
-                       if( this.options.value ) {
-                               $.each( this.options.value.getTexts(), 
function() {
-                                       self.$list.append( mw.wbTemplate( 
'wikibase-aliasesview-list-item', this ) );
-                               } );
-                       }
-
-                       return;
+                       $.each( this.options.value.getTexts(), function() {
+                               self.$list.append( mw.wbTemplate( 
'wikibase-aliasesview-list-item', this ) );
+                       } );
                }
 
-               this.element.addClass( 'wb-edit' );
-
-               this._initTagadata();
+               return $.Deferred().resolve().promise();
        },
 
        /**
@@ -172,114 +142,24 @@
        },
 
        /**
-        * Starts the widget's edit mode.
-        */
-       startEditing: function() {
-               if( this._isInEditMode ) {
-                       return;
-               }
-
-               this._isInEditMode = true;
-               this._draw();
-
-               this._trigger( 'afterstartediting' );
-       },
-
-       /**
-        * Stops the widget's edit mode.
-        *
-        * @param {boolean} dropValue
-        */
-       stopEditing: function( dropValue ) {
-               var self = this;
-
-               if( !this._isInEditMode || ( !this.isValid() || 
this.isInitialValue() ) && !dropValue ) {
-                       return;
-               }
-
-               if( dropValue ) {
-                       this._afterStopEditing( dropValue );
-                       return;
-               }
-
-               this.disable();
-
-               this._trigger( 'stopediting', null, [dropValue] );
-
-               // TODO: Performing API interaction should be managed in parent 
component (probably
-               // entityview)
-               this._save()
-               .done( function() {
-                       self.enable();
-                       self._afterStopEditing( dropValue );
-               } )
-               .fail( function( error ) {
-                       self.setError( error );
-               } );
-       },
-
-       /**
-        * @return {jQuery.Promise}
+        * @see jQuery.ui.EditableTemplatedWidget.save
         */
        _save: function() {
                return this.options.aliasesChanger.setAliases( this.value() );
        },
 
        /**
-        * Cancels the widget's edit mode.
-        */
-       cancelEditing: function() {
-               this.stopEditing( true );
-       },
-
-       /**
-        * Callback tearing down edit mode.
-        *
-        * @param {boolean} dropValue
-        */
-       _afterStopEditing: function( dropValue ) {
-               if( !dropValue ) {
-                       this.options.value = this.value();
-               }
-
-               this._isInEditMode = false;
-               this._draw();
-
-               this._trigger( 'afterstopediting', null, [dropValue] );
-       },
-
-       /**
-        * @return {boolean}
+        * @see jQuery.ui.EditableTemplatedWidget.isValid
         */
        isValid: function() {
-               // Function required by edittoolbar.
                return true;
        },
 
        /**
-        * @return {boolean}
+        * @see jQuery.ui.EditableTemplatedWidget.isValid
         */
        isInitialValue: function() {
                return this.value().equals( this.options.value );
-       },
-
-       /**
-        * Toggles error state.
-        *
-        * @param {Error} error
-        */
-       setError: function( error ) {
-               if( error ) {
-                       this.element.addClass( 'wb-error' );
-                       this._trigger( 'toggleerror', null, [error] );
-               } else {
-                       this.removeError();
-                       this._trigger( 'toggleerror' );
-               }
-       },
-
-       removeError: function() {
-               this.element.removeClass( 'wb-error' );
        },
 
        /**
@@ -292,7 +172,7 @@
 
                var response = PARENT.prototype._setOption.call( this, key, 
value );
 
-               if( key === 'disabled' && this._isInEditMode ) {
+               if( key === 'disabled' && this.isInEditMode() ) {
                        this.$list.data( 'tagadata' ).option( 'disabled', value 
);
                }
 
@@ -311,7 +191,7 @@
                        return;
                }
 
-               if( !this._isInEditMode ) {
+               if( !this.isInEditMode() ) {
                        return this.option( 'value' );
                }
 
@@ -329,7 +209,7 @@
         * @see jQuery.ui.TemplatedWidget.focus
         */
        focus: function() {
-               if( this._isInEditMode ) {
+               if( this.isInEditMode() ) {
                        this.$list.data( 'tagadata' ).getHelperTag().find( 
'input' ).focus();
                } else {
                        this.element.focus();
diff --git a/lib/resources/jquery.wikibase/resources.php 
b/lib/resources/jquery.wikibase/resources.php
index dbf4971..5add62c 100644
--- a/lib/resources/jquery.wikibase/resources.php
+++ b/lib/resources/jquery.wikibase/resources.php
@@ -29,7 +29,7 @@
                        'dependencies' => array(
                                'jquery.inputautoexpand',
                                'jquery.ui.tagadata',
-                               'jquery.ui.TemplatedWidget',
+                               'jquery.ui.EditableTemplatedWidget',
                                'jquery.wikibase.edittoolbar',
                                'jquery.wikibase.toolbarcontroller',
                                'wikibase.datamodel.MultiTerm',
diff --git 
a/lib/tests/qunit/jquery.ui/jquery.ui.EditableTemplatedWidget.tests.js 
b/lib/tests/qunit/jquery.ui/jquery.ui.EditableTemplatedWidget.tests.js
new file mode 100644
index 0000000..0f1301d
--- /dev/null
+++ b/lib/tests/qunit/jquery.ui/jquery.ui.EditableTemplatedWidget.tests.js
@@ -0,0 +1,85 @@
+/**
+ * @licence GNU GPL v2+
+ * @author H. Snater < [email protected] >
+ */
+( function( mw, $, QUnit ) {
+       'use strict';
+
+QUnit.module( 'jquery.ui.EditableTemplatedWidget', QUnit.newMwEnvironment( {
+       setup: function() {
+               $.widget( 'test.editablewidget', {
+                       _create: function() {
+                               this._initialValue = this.options.value;
+                       },
+                       _draw: function() {},
+                       _save: function() {
+                               return $.Deferred().resolve().promise();
+                       },
+                       value: function( value ) {
+                               if( value === undefined ) {
+                                       this.option( 'value', value );
+                               } else {
+                                       return this.option( 'value' );
+                               }
+                       },
+                       isEmpty: function() {
+                               return !this.option( 'value' );
+                       },
+                       isValid: function() {
+                               return !!this.option( 'value' );
+                       },
+                       isInitialValue: function() {
+                               return this.option( 'value' ) === 
this._initialValue;
+                       }
+               } );
+       },
+       teardown: function() {
+               delete( $.test.editablewidget );
+
+               $( '.test_edittoolbar' ).each( function() {
+                       var $edittoolbar = $( this ),
+                               edittoolbar = $edittoolbar.data( 'edittoolbar' 
);
+
+                       if( edittoolbar ) {
+                               edittoolbar.destroy();
+                       }
+
+                       $edittoolbar.remove();
+               } );
+       }
+} ) );
+
+QUnit.test( 'Create & destroy', function( assert ) {
+       var testSets = [
+               [
+                       '<div><span>$1</span></div>',
+                       {
+                               templateParams: ['test']
+                       }
+               ]
+       ];
+
+       for( var i = 0; i < testSets.length; i++ ) {
+               mw.wbTemplates.store.set( 'templatedWidget-test', 
testSets[i][0] );
+
+               var $subject = $( '<div/>' );
+
+               $subject.editablewidget( $.extend( {
+                       template: 'templatedWidget-test'
+               }, testSets[i][1] ) );
+
+               assert.ok(
+                       $subject.data( 'editablewidget' ) instanceof 
$.test.editablewidget,
+                       'Test set #' + i + ': Initialized widget.'
+               );
+
+               $subject.data( 'editablewidget' ).destroy();
+
+               assert.ok(
+                       $subject.data( 'editablewidget' ) === undefined,
+                       'Destroyed widget.'
+               );
+       }
+} );
+
+}( mediaWiki, jQuery, QUnit ) );
diff --git 
a/lib/tests/qunit/jquery.wikibase/jquery.wikibase.aliasesview.tests.js 
b/lib/tests/qunit/jquery.wikibase/jquery.wikibase.aliasesview.tests.js
index 6b037b0..8108d8c 100644
--- a/lib/tests/qunit/jquery.wikibase/jquery.wikibase.aliasesview.tests.js
+++ b/lib/tests/qunit/jquery.wikibase/jquery.wikibase.aliasesview.tests.js
@@ -68,6 +68,30 @@
        );
 } );
 
+QUnit.test( 'Instantiating tagadata widget on startEditing()', function( 
assert ) {
+       var $aliasesview = createAliasesview(),
+               aliasesview = $aliasesview.data( 'aliasesview' );
+
+       QUnit.stop();
+
+       aliasesview.startEditing()
+       .done( function() {
+               assert.ok(
+                       aliasesview.$list.data( 'tagadata' ) !== undefined,
+                       'Instantiated tagadata widget.'
+               );
+       } )
+       .fail( function() {
+               assert.ok(
+                       false,
+                       'Failed to start edit mode.'
+               );
+       } )
+       .always( function() {
+               QUnit.start();
+       } );
+} );
+
 QUnit.test( 'startEditing() & stopEditing()', 7, function( assert ) {
        var $aliasesview = createAliasesview(),
                aliasesview = $aliasesview.data( 'aliasesview' );
@@ -86,29 +110,94 @@
                );
        } );
 
-       aliasesview.startEditing();
+       /**
+        * @param {Function} func
+        * @param {boolean} expectingEvent
+        * @return {Object} jQuery.Promise
+        */
+       function testEditModeChange( func, expectingEvent ) {
+               var deferred = $.Deferred();
 
-       assert.ok(
-               aliasesview.$list.data( 'tagadata' ) !== undefined,
-               'Instantiated tagadata widget.'
-       );
+               if( !expectingEvent ) {
+                       func();
+                       return deferred.resolve().promise();
+               }
 
-       aliasesview.startEditing(); // should not trigger event
-       aliasesview.stopEditing( true );
-       aliasesview.stopEditing( true ); // should not trigger event
-       aliasesview.stopEditing(); // should not trigger event
+               $aliasesview
+               .one( 'aliasesviewafterstartediting.aliasesviewtest', function( 
event ) {
+                       $aliasesview.off( '.aliasesviewtest' );
+                       deferred.resolve();
+               } )
+               .one( 'aliasesviewafterstopediting.aliasesviewtest', function( 
event, dropValue ) {
+                       $aliasesview.off( '.aliasesviewtest' );
+                       deferred.resolve();
+               } );
 
-       aliasesview.startEditing();
+               func();
 
-       aliasesview.$list.data( 'tagadata' ).getTags().first().find( 'input' 
).val( 'b' );
+               return deferred.promise();
+       }
 
-       aliasesview.stopEditing();
-       aliasesview.startEditing();
+       var $queue = $( {} );
 
-       aliasesview.$list.data( 'tagadata' ).getTags().first().removeClass( 
'tagadata-choice-equal' )
-               .find( 'input' ).val( 'd' );
+       /**
+        * @param {jQuery} $queue
+        * @param {Function} func
+        * @param {boolean} [expectingEvent]
+        */
+       function addToQueue( $queue, func, expectingEvent ) {
+               if( expectingEvent === undefined ) {
+                       expectingEvent = true;
+               }
+               $queue.queue( 'tests', function( next ) {
+                       QUnit.stop();
+                       testEditModeChange( func, expectingEvent ).always( 
function() {
+                               QUnit.start();
+                               next();
+                       } );
+               } );
+       }
 
-       aliasesview.stopEditing();
+       addToQueue( $queue, function() {
+               aliasesview.startEditing();
+       } );
+
+       addToQueue( $queue, function() {
+               aliasesview.startEditing();
+       }, false );
+
+       addToQueue( $queue, function() {
+               aliasesview.stopEditing( true );
+       } );
+
+       addToQueue( $queue, function() {
+               aliasesview.stopEditing( true );
+       }, false );
+
+       addToQueue( $queue, function() {
+               aliasesview.stopEditing();
+       }, false );
+
+       addToQueue( $queue, function() {
+               aliasesview.startEditing();
+       } );
+
+       addToQueue( $queue, function() {
+               aliasesview.$list.data( 'tagadata' ).getTags().first().find( 
'input' ).val( 'b' );
+               aliasesview.stopEditing();
+       } );
+
+       addToQueue( $queue, function() {
+               aliasesview.startEditing();
+       } );
+
+       addToQueue( $queue, function() {
+               aliasesview.$list.data( 'tagadata' ).getTags().first()
+                       .removeClass( 'tagadata-choice-equal' ).find( 'input' 
).val( 'd' );
+               aliasesview.stopEditing();
+       } );
+
+       $queue.dequeue( 'tests' );
 } );
 
 QUnit.test( 'isInitialValue()', function( assert ) {
diff --git a/lib/tests/qunit/resources.php b/lib/tests/qunit/resources.php
index b3356e3..d030b5b 100644
--- a/lib/tests/qunit/resources.php
+++ b/lib/tests/qunit/resources.php
@@ -53,6 +53,16 @@
                        ),
                ),
 
+               'jquery.ui.EditableTemplatedWidget.tests' => $moduleBase + 
array(
+                       'scripts' => array(
+                               
'jquery.ui/jquery.ui.EditableTemplatedWidget.tests.js',
+                       ),
+                       'dependencies' => array(
+                               'jquery.ui.EditableTemplatedWidget',
+                               'wikibase.templates',
+                       ),
+               ),
+
                'jquery.ui.tagadata.tests' => $moduleBase + array(
                        'scripts' => array(
                                'jquery.ui/jquery.ui.tagadata.tests.js',

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib21c2d50d1acd0c32024ad226956cd0840fe3e13
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Henning Snater <[email protected]>

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

Reply via email to