Thiemo Mättig (WMDE) has submitted this change and it was merged.

Change subject: Implemented pagesuggester widget
......................................................................


Implemented pagesuggester widget

(bug 68905)
For now, $.wikibase.pagesuggester features the functionality extracted from 
SitePageInterface.

Change-Id: I44a22407c6c31c4b6b1b5f91700c1b7381d0fdec
---
M lib/WikibaseLib.hooks.php
M lib/resources/Resources.php
A lib/resources/jquery.wikibase/jquery.wikibase.pagesuggester.js
M lib/resources/wikibase.ui.PropertyEditTool.EditableValue.Interface.js
M lib/resources/wikibase.ui.PropertyEditTool.EditableValue.SitePageInterface.js
A lib/tests/qunit/jquery.wikibase/jquery.wikibase.pagesuggester.tests.js
M 
lib/tests/qunit/wikibase.ui.PropertyEditTool.EditableValue.SitePageInterface.tests.js
M lib/tests/qunit/wikibase.ui.SiteLinksEditTool.tests.js
8 files changed, 235 insertions(+), 85 deletions(-)

Approvals:
  WikidataJenkins: Verified
  Thiemo Mättig (WMDE): Looks good to me, approved
  jenkins-bot: Checked



diff --git a/lib/WikibaseLib.hooks.php b/lib/WikibaseLib.hooks.php
index 1b9868e..c1b4263 100644
--- a/lib/WikibaseLib.hooks.php
+++ b/lib/WikibaseLib.hooks.php
@@ -186,6 +186,16 @@
                        ),
                );
 
+               $testModules['qunit']['jquery.wikibase.pagesuggester.tests'] = 
$moduleBase + array(
+                       'scripts' => array(
+                               
'tests/qunit/jquery.wikibase/jquery.wikibase.pagesuggester.tests.js'
+                       ),
+                       'dependencies' => array(
+                               'jquery',
+                               'jquery.wikibase.pagesuggester',
+                       ),
+               );
+
                $testModules['qunit']['jquery.wikibase.referenceview.tests'] = 
$moduleBase + array(
                        'scripts' => array(
                                
'tests/qunit/jquery.wikibase/jquery.wikibase.referenceview.tests.js',
diff --git a/lib/resources/Resources.php b/lib/resources/Resources.php
index a87d710..f64c76b 100644
--- a/lib/resources/Resources.php
+++ b/lib/resources/Resources.php
@@ -320,6 +320,7 @@
                                'jquery.ui.suggester',
                                'util.inherit',
                                'jquery.wikibase.entityselector',
+                               'jquery.wikibase.pagesuggester',
                                'jquery.wikibase.toolbareditgroup',
                                'jquery.wikibase.siteselector',
                                'mediawiki.api',
@@ -497,6 +498,16 @@
                        )
                ),
 
+               'jquery.wikibase.pagesuggester' => $moduleTemplate + array(
+                       'scripts' => array(
+                               
'jquery.wikibase/jquery.wikibase.pagesuggester.js',
+                       ),
+                       'dependencies' => array(
+                               'jquery.ui.suggester',
+                               'wikibase.sites',
+                       ),
+               ),
+
                'jquery.wikibase.listview' => $moduleTemplate + array(
                        'scripts' => array(
                                'jquery.wikibase/jquery.wikibase.listview.js',
diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.pagesuggester.js 
b/lib/resources/jquery.wikibase/jquery.wikibase.pagesuggester.js
new file mode 100644
index 0000000..13e3e93
--- /dev/null
+++ b/lib/resources/jquery.wikibase/jquery.wikibase.pagesuggester.js
@@ -0,0 +1,115 @@
+/**
+ * @licence GNU GPL v2+
+ * @author H. Snater < mediaw...@snater.com >
+ */
+( function( $, mw, wb ) {
+       'use strict';
+
+/**
+ * Suggester enhanced input element for selecting a site link's page.
+ * @since 0.5
+ *
+ * @option {string} [siteId]
+ *
+ * @option {string} [pageName]
+ */
+$.widget( 'wikibase.pagesuggester', $.ui.suggester, {
+       /**
+        * @see jQuery.ui.suggester.options
+        */
+       options: {
+               siteId: null,
+               pageName: null
+       },
+
+       /**
+        * @see jQuery.ui.suggester._create
+        */
+       _create: function() {
+               var self = this;
+
+               if( this.option( 'pageName' ) ) {
+                       this.element.val( this.option( 'pageName' ) );
+               }
+
+               if( !this.option( 'source' ) ) {
+                       this.option( 'source', this._request() );
+               }
+
+               $.ui.suggester.prototype._create.call( this );
+
+               this.element
+               .on( this.widgetEventPrefix + 'change.' + this.widgetName, 
function( event ) {
+                       if( $.trim( self.element.val() ) !== self.option( 
'pageName' ) ) {
+                               self.option( 'pageName', $.trim( 
self.element.val() ) );
+                       }
+               } );
+       },
+
+       /**
+        * @see jQuery.ui.suggester._setOption
+        */
+       _setOption: function( key, value ) {
+               $.ui.suggester.prototype._setOption.apply( this, arguments );
+
+               if( key === 'siteId' ) {
+                       this._trigger( 'change' );
+               }
+
+               if( key === 'pageName' ) {
+                       this.element.val( this.option( 'pageName' ) );
+                       this._trigger( 'change' );
+               }
+       },
+
+       /**
+        * @see $.ui.suggester.search
+        */
+       search: function( event ) {
+               // Reject searching when there is no siteId specified:
+               if( !this.option( 'siteId' ) ) {
+                       var deferred = $.Deferred();
+                       return deferred.reject( 'siteId-undefined' ).promise();
+               }
+               return $.ui.suggester.prototype.search.apply( this, arguments );
+       },
+
+       /**
+        * @see jQuery.ui.suggester._getSuggestions
+        *
+        * @return {Object} jQuery.Promise
+        *         Resolved parameters:
+        *         - {string[]}
+        *         - {string}
+        *         Rejected parameters:
+        *         - {string}
+        */
+       _request: function() {
+               var self = this;
+
+               return function( term ) {
+                       var deferred = $.Deferred();
+
+                       $.ajax( {
+                               url: wb.sites.getSite( self.option( 'siteId' ) 
).getApi(),
+                               dataType: 'jsonp',
+                               data: {
+                                       search: term,
+                                       action: 'opensearch'
+                               },
+                               timeout: 8000
+                       } )
+                       .done( function( response ) {
+                               deferred.resolve( response[1], response[0] );
+                       } )
+                       .fail( function( jqXHR, textStatus ) {
+                               // Since this is a JSONP request, this will 
always fail with a timeout...
+                               deferred.reject( textStatus );
+                       } );
+
+                       return deferred.promise();
+               };
+       }
+
+} );
+}( jQuery, mediaWiki, wikibase ) );
diff --git 
a/lib/resources/wikibase.ui.PropertyEditTool.EditableValue.Interface.js 
b/lib/resources/wikibase.ui.PropertyEditTool.EditableValue.Interface.js
index 42e4f02..11b225a 100644
--- a/lib/resources/wikibase.ui.PropertyEditTool.EditableValue.Interface.js
+++ b/lib/resources/wikibase.ui.PropertyEditTool.EditableValue.Interface.js
@@ -199,15 +199,12 @@
         */
        updateLanguageAttributes: function() {
                // apply subject's language attributes or attributes according 
to user language.
-               if ( this._inputElem !== null ) {
-                       var lang = this.getSubject().attr( 'lang' );
-                       if ( lang === undefined ) {
-                               lang = mw.config.get( 'wgUserLanguage' );
-                       }
+               if( this._inputElem ) {
+                       var lang = this.getSubject().attr( 'lang' ) || 
mw.config.get( 'wgUserLanguage' );
 
-                       // Get the computed dir from CSS, to make sure that 
it's explicit and not 'auto', which
-                       // is less useful for <input>:
-                       var dir = this.getSubject().css( 'direction' );
+                       var dir = ( $.uls && $.uls.data.getDir( lang ) )
+                               || this.getSubject().css( 'direction' )
+                               || 'auto';
 
                        this._inputElem.attr( 'lang', lang ).attr( 'dir', dir );
                }
diff --git 
a/lib/resources/wikibase.ui.PropertyEditTool.EditableValue.SitePageInterface.js 
b/lib/resources/wikibase.ui.PropertyEditTool.EditableValue.SitePageInterface.js
index d8a96b2..bd352cf 100644
--- 
a/lib/resources/wikibase.ui.PropertyEditTool.EditableValue.SitePageInterface.js
+++ 
b/lib/resources/wikibase.ui.PropertyEditTool.EditableValue.SitePageInterface.js
@@ -20,18 +20,6 @@
  */
 wb.ui.PropertyEditTool.EditableValue.SitePageInterface = util.inherit( PARENT, 
{
        /**
-        * Url the AJAX request will point to (if ajax should be used to define 
a result set).
-        * @type {string}
-        */
-       url: null,
-
-       /**
-        * Additional params for the AJAX request (if ajax should be used to 
define a result set)
-        * @type {Object}
-        */
-       ajaxParams: null,
-
-       /**
         * Information for which site this autocomplete interface should serve 
input suggestions
         * @var wikibase.Site
         */
@@ -69,32 +57,36 @@
 
                var $input = PARENT.prototype._buildInputElement.call( this );
 
-               $input.suggester( {
-                       source: this._request()
+               $input.pagesuggester( {
+                       siteId: this._site ? this._site.getId() : null
                } );
 
                this._initBadgeEditing();
 
                $input
-               .on( 'keyup close', function( event ) {
+               .on( 'pagesuggesterchange pagesuggesterclose', function( event 
) {
+                       this._currentResults = [];
+
+                       var menu = $input.data( 'pagesuggester' ).option( 
'menu' );
+
+                       if( menu ) {
+                               $.each( menu.option( 'items' ), function() {
+                                       self._currentResults.push( 
this.getValue() );
+                               } );
+                       }
+
                        // The input element might have been removed already 
with the event still being in the
                        // loop:
                        if ( !self.isDisabled() && self._inputElem !== null ) {
                                self._onInputRegistered();
                        }
                } )
-               .on( 'suggesterresponse suggesterselect', function( event, 
results ) {
-                       self._currentResults = results;
-                       if ( !self.isDisabled() ) {
-                               self._onInputRegistered();
-                       }
-               } )
-               .on( 'suggestererror', function( event, textStatus, errorThrown 
) {
-                       if ( textStatus !== 'abort' ) {
+               .on( 'pagesuggestererror', function( event, message ) {
+                       if ( message !== 'abort' ) {
                                var error = {
-                                       code: textStatus,
+                                       code: message,
                                        message: mw.msg( 
'wikibase-error-autocomplete-connection' ),
-                                       detailedMessage: mw.msg( 
'wikibase-error-autocomplete-response', errorThrown )
+                                       detailedMessage: mw.msg( 
'wikibase-error-autocomplete-response', message )
                                };
                                self._inputElem.wbtooltip( {
                                        content: error,
@@ -166,36 +158,6 @@
        },
 
        /**
-        * Generates the suggester source function.
-        */
-       _request: function() {
-               var self = this;
-
-               return function( term ) {
-                       var deferred = $.Deferred();
-
-                       $.ajax( {
-                               url: self._site.getApi(),
-                               dataType: 'jsonp',
-                               data: {
-                                       search: term,
-                                       action: 'opensearch'
-                               },
-                               timeout: 8000
-                       } )
-                       .done( function( response ) {
-                               deferred.resolve( response[1], response[0] );
-                       } )
-                       .fail( function( jqXHR, textStatus ) {
-                               // Since this is a JSONP request, this will 
always fail with a timeout...
-                               deferred.reject( textStatus );
-                       } );
-
-                       return deferred.promise();
-               };
-       },
-
-       /**
         * Allows to set the site, the pages should be selected from.
         *
         * @param wb.Site site
@@ -207,6 +169,10 @@
 
                this._site = site;
 
+               if( this._inputElem ) {
+                       this._inputElem.data( 'pagesuggester' ).option( 
'siteId', site.getId() );
+               }
+
                this._currentResults = []; // empty current suggestions...
        },
 
@@ -215,23 +181,9 @@
         */
        updateLanguageAttributes: function() {
                PARENT.prototype.updateLanguageAttributes.call( this );
-               // apply input's language attributes or attributes according to 
user language
-               if ( this._inputElem !== null ) {
-                       var lang = this._inputElem.attr( 'lang' );
-                       if ( lang === undefined ) {
-                               lang = mw.config.get( 'wgUserLanguage' );
-                       }
-                       var dir = this._inputElem.attr( 'dir' );
-                       if ( dir === undefined ) {
-                               if ( wb.getLanguages()[lang] !== undefined ) {
-                                       dir = $.uls.data.getDir( lang );
-                               }
-                       }
-                       if ( dir === undefined ) {
-                               dir = 'auto'; // Shouldn't happen, but go figure
-                       }
-                       this._inputElem.data( 'suggester' ).options.menu.element
-                               .attr( 'lang', lang ).attr( 'dir', dir );
+
+               if( this._inputElem ) {
+                       this._inputElem.data( 'pagesuggester' 
).repositionMenu();
                }
        },
 
@@ -328,9 +280,9 @@
                var success = PARENT.prototype._setState.call( this, state );
                if( this._inputElem !== null ) {
                        if( state === this.STATE.DISABLED ) {
-                               this._inputElem.data( 'suggester').disable();
+                               this._inputElem.data( 
'pagesuggester').disable();
                        } else {
-                               this._inputElem.data( 'suggester').enable();
+                               this._inputElem.data( 'pagesuggester').enable();
                        }
                }
                return success;
diff --git 
a/lib/tests/qunit/jquery.wikibase/jquery.wikibase.pagesuggester.tests.js 
b/lib/tests/qunit/jquery.wikibase/jquery.wikibase.pagesuggester.tests.js
new file mode 100644
index 0000000..abd1970
--- /dev/null
+++ b/lib/tests/qunit/jquery.wikibase/jquery.wikibase.pagesuggester.tests.js
@@ -0,0 +1,65 @@
+/**
+ * @licence GNU GPL v2+
+ * @author H. Snater < mediaw...@snater.com >
+ */
+( function( $, QUnit ) {
+       'use strict';
+
+       /**
+        * Factory creating a jQuery.wikibase.pagesuggester widget suitable for 
testing.
+        *
+        * @param {Object} [options]
+        */
+       var newTestPageSuggester = function( options ) {
+               return $( '<input/>' )
+                       .addClass( 'test_pagesuggester')
+                       .appendTo( 'body' )
+                       .pagesuggester( options );
+       };
+
+       QUnit.module( 'jquery.wikibase.pagesuggester', {
+               teardown: function() {
+                       var $pageSuggester = $( '.test_pagesuggester' ),
+                               pageSuggester = $pageSuggester.data( 
'pagesuggester' );
+                       if( pageSuggester ) {
+                               pageSuggester.destroy();
+                       }
+                       $pageSuggester.remove();
+               }
+       } );
+
+       QUnit.test( 'Create', function( assert ) {
+               var $pageSuggester = newTestPageSuggester();
+
+               assert.ok(
+                       $pageSuggester.data( 'pagesuggester' ) instanceof 
$.wikibase.pagesuggester,
+                       'Instantiated page suggester.'
+               );
+       } );
+
+       QUnit.test( 'Try searching for suggestions without a site', 1, 
function( assert ) {
+               var $pageSuggester = newTestPageSuggester(),
+                       pageSuggester = $pageSuggester.data( 'pagesuggester' );
+
+               QUnit.stop();
+
+               pageSuggester.search()
+               .done( function() {
+                       assert.ok(
+                               false,
+                               'Searching successful although supposed to 
fail.'
+                       );
+               } )
+               .fail( function() {
+                       assert.ok(
+                               true,
+                               'Searching failed as expected.'
+                       );
+               } )
+               .always( function() {
+                       QUnit.start();
+               } );
+
+       } );
+
+}( jQuery, QUnit ) );
diff --git 
a/lib/tests/qunit/wikibase.ui.PropertyEditTool.EditableValue.SitePageInterface.tests.js
 
b/lib/tests/qunit/wikibase.ui.PropertyEditTool.EditableValue.SitePageInterface.tests.js
index 47d7d9e..4a7e821 100644
--- 
a/lib/tests/qunit/wikibase.ui.PropertyEditTool.EditableValue.SitePageInterface.tests.js
+++ 
b/lib/tests/qunit/wikibase.ui.PropertyEditTool.EditableValue.SitePageInterface.tests.js
@@ -113,13 +113,13 @@
                this.subject.setLanguageAttributes( this.language.rtl.code, 
this.language.rtl.dir );
 
                equal(
-                       this.subject._inputElem.data( 'suggester' 
).options.menu.element.attr( 'lang' ),
+                       this.subject._inputElem.data( 'pagesuggester' 
).options.menu.element.attr( 'lang' ),
                        this.language.rtl.code,
                        'assign rtl language code to auto-complete menu'
                );
 
                equal(
-                       this.subject._inputElem.data( 'suggester' 
).options.menu.element.attr( 'dir' ),
+                       this.subject._inputElem.data( 'pagesuggester' 
).options.menu.element.attr( 'dir' ),
                        this.language.rtl.dir,
                        'assign rtl language direction to auto-complete menu'
                );
diff --git a/lib/tests/qunit/wikibase.ui.SiteLinksEditTool.tests.js 
b/lib/tests/qunit/wikibase.ui.SiteLinksEditTool.tests.js
index 5309dc3..da87352 100644
--- a/lib/tests/qunit/wikibase.ui.SiteLinksEditTool.tests.js
+++ b/lib/tests/qunit/wikibase.ui.SiteLinksEditTool.tests.js
@@ -89,7 +89,7 @@
 
                // set result set for validation
                newValue.sitePageInterface._sites = siteLink[1];
-               newValue.sitePageInterface._inputElem.data( 'suggester' 
).option( 'source', siteLink[1] );
+               newValue.sitePageInterface._inputElem.data( 'pagesuggester' 
).option( 'source', siteLink[1] );
 
                // pretend API success
                var fakeApiResponse = { entity: { sitelinks: {} } };

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I44a22407c6c31c4b6b1b5f91700c1b7381d0fdec
Gerrit-PatchSet: 11
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Henning Snater <henning.sna...@wikimedia.de>
Gerrit-Reviewer: Adrian Lang <adrian.l...@wikimedia.de>
Gerrit-Reviewer: Aude <aude.w...@gmail.com>
Gerrit-Reviewer: Hoo man <h...@online.de>
Gerrit-Reviewer: Thiemo Mättig (WMDE) <thiemo.maet...@wikimedia.de>
Gerrit-Reviewer: Tobias Gritschacher <tobias.gritschac...@wikimedia.de>
Gerrit-Reviewer: WikidataJenkins <wikidata-servi...@wikimedia.de>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to