Daniel Werner has uploaded a new change for review.

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


Change subject: (bug 45002) made EntityId data values work with the new 
jQuery.valueview.
......................................................................

(bug 45002) made EntityId data values work with the new jQuery.valueview.

IMPORTANT DEPENDENCY: ValueView extension's 
I09cd9f42ca1a22f11ff102a18e56321b451eed34

There is one bigger todo left, which would be to make get/setRawValue of the 
EntityIdInput
expert more consistent; both should take and give the same kind of values.
This will be done in a follow-up though, the situation has not really become 
worse since
before this change-set.

Change-Id: Ic619890cc997e81a2c1f7839c8eb0d4cdffcf556
---
M lib/resources/Resources.php
A 
lib/resources/jquery.valueview.experts.wikibase/experts.wikibase.EntityIdInput.js
A 
lib/resources/jquery.valueview.experts.wikibase/experts.wikibase.EntityIdValue.js
A lib/resources/jquery.valueview.experts.wikibase/experts.wikibase.js
D lib/resources/jquery.valueview.views/views.css
D lib/resources/jquery.valueview.views/wikibaseItem.js
6 files changed, 255 insertions(+), 187 deletions(-)


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

diff --git a/lib/resources/Resources.php b/lib/resources/Resources.php
index d49df6a..54e851b 100644
--- a/lib/resources/Resources.php
+++ b/lib/resources/Resources.php
@@ -523,6 +523,7 @@
                                'jquery.wikibase.entityselector',
                                'wikibase.datamodel',
                                'mw.ext.valueView',
+                               'jquery.valueview.experts.wikibase',
                                'wikibase.store', // required for getting 
datatype from entityselector selected property
                                'mediawiki.legacy.shared',
                                'jquery.ui.TemplatedWidget'
@@ -632,12 +633,11 @@
                ),
 
                // jQuery.valueview views for Wikibase specific 
DataValues/DataTypes
-               'wikibase.jquery.valueview.views' => $moduleTemplate + array(
+               'jquery.valueview.experts.wikibase' => $moduleTemplate + array(
                        'scripts' => array(
-                               'jquery.valueview.views/wikibaseItem.js',
-                       ),
-                       'styles' => array(
-                               'jquery.valueview.views/views.css',
+                               
'jquery.valueview.experts.wikibase/experts.wikibase.js',
+                               
'jquery.valueview.experts.wikibase/experts.wikibase.EntityIdInput.js',
+                               
'jquery.valueview.experts.wikibase/experts.wikibase.EntityIdValue.js',
                        ),
                        'dependencies' => array(
                                'jquery.valueview',
diff --git 
a/lib/resources/jquery.valueview.experts.wikibase/experts.wikibase.EntityIdInput.js
 
b/lib/resources/jquery.valueview.experts.wikibase/experts.wikibase.EntityIdInput.js
new file mode 100644
index 0000000..fd5aa46
--- /dev/null
+++ 
b/lib/resources/jquery.valueview.experts.wikibase/experts.wikibase.EntityIdInput.js
@@ -0,0 +1,146 @@
+/**
+ * @file
+ * @ingroup WikibaseLib
+ * @licence GNU GPL v2+
+ * @author Daniel Werner < [email protected] >
+ */
+( function( mw, wb, dv, vp, $, vv ) {
+       'use strict';
+
+       // temporarily define a hard coded prefix map until we get this from 
the server
+       var WB_ENTITIES_PREFIXMAP = {
+               'q': 'item',
+               'p': 'property'
+       };
+
+       var PARENT = vv.experts.StringValue;
+
+       /**
+        * Valueview expert for wikibase.EntityId. This is a simple expert, 
only handling the input,
+        * based on the StringValue input but with the 
jQuery.wikibase.entityselector for convenience.
+        *
+        * @since 0.4
+        *
+        * @constructor
+        * @extends jQuery.valueview.experts.StringValue
+        */
+       vv.experts.wikibase.EntityIdInput = vv.expert( 'wikibaseentityidinput', 
PARENT, {
+               /**
+                * @see Query.valueview.experts.StringValue._init
+                */
+               _init: function() {
+                       PARENT.prototype._init.call( this );
+
+                       var notifier = this._viewNotifier,
+                               $input = this.$input;
+
+                       $input
+                       .entityselector( {
+                               url: mw.util.wikiScript( 'api' ),
+                               selectOnAutocomplete: true
+                       } )
+                       .eachchange( function( event, oldValue ) {
+                               $( this ).data( 'entityselector' 
).repositionMenu();
+                       } )
+                       .on( 'entityselectorselect', function( e, ui ) {
+                               var itemData = {
+                                       id: ui.item.id,
+                                       label: {}
+                               };
+                               itemData.label[ mw.config.get( 'wgUserLanguage' 
) ] = ui.item.label;
+
+                               // update local store with newest information 
about selected item
+                               // TODO: create more sophisticated local store 
interface rather than accessing
+                               //       wb.fetchedEntities directly
+                               wb.fetchedEntities[ ui.item.id ] = new 
wb.store.FetchedContent( {
+                                       // TODO: *terrible* solution to use 
regex, entityselector should provide title
+                                       title: new mw.Title( ui.item.url.match( 
/[^\/]+$/ )[0] ),
+                                       content: new wb.Item( itemData )
+                               } );
+                       } )
+                       .on(
+                               // "aftersetentity": When setting the entity 
programmatically (editing an existing
+                               // Snak).
+                               // "response": Each time an API query returns 
(the input value gets auto-completed).
+                               // "close": After having selected an entity by 
clicking on a suggestion list item.
+                               'entityselectoraftersetentity 
entityselectorresponse entityselectorclose',
+                               function( e ) {
+                                       var expand = $( this ).data( 
'AutoExpandInput' );
+                                       expand && expand.expand();
+                                       $( this ).data( 'entityselector' 
).repositionMenu();
+                               }
+                       );
+
+                       $input.on( 'entityselectorselect', function( event, 
response ) {
+                               notifier.notify( 'change' ); // here in 
addition to 'eachchange' from StringValue expert
+                       } );
+               },
+
+               /**
+                * @see Query.valueview.Expert._getRawValue
+                *
+                * @return string
+                *
+                * TODO: get/setRawValue should be consistent. Right now one 
takes a DataValue object while
+                *       the other returns a string!
+                */
+               _getRawValue: function() {
+                       var entitySelector = this.$input.data( 'entityselector' 
),
+                               selectedEntity = 
entitySelector.selectedEntity();
+
+                       return selectedEntity ? selectedEntity.id : null;
+               },
+
+               /**
+                * @see Query.valueview.Expert._setRawValue
+                *
+                * @return wb.EntityId
+                */
+               _setRawValue: function( rawValue ) {
+                       var entityId = rawValue instanceof wb.EntityId
+                               ? rawValue.getPrefixedId( WB_ENTITIES_PREFIXMAP 
)
+                               // TODO: be consistent with get/set, don't 
check for string and EntityId!
+                               : ( ( typeof rawValue === 'string' && rawValue 
) ? rawValue : null );
+
+                       var fetchedEntity = entityId ? wb.fetchedEntities[ 
entityId ] : null,
+                               simpleEntity = null;
+
+                       if( fetchedEntity ) {
+                               // entity selector requires very basic data 
only, but ID has to be set which is
+                               // not the case in the wb.fetchedEntities 
entity store.
+                               simpleEntity = {
+                                       label: 
fetchedEntity.getContent().getLabel(),
+                                       id: entityId,
+                                       url: fetchedEntity.getTitle().getUrl()
+                               };
+                       }
+
+                       this.$input.data( 'entityselector' ).selectedEntity( 
simpleEntity );
+                       // TODO: entityselector should just be able to handle 
wb.Entity without making it a
+                       //  dependency there.
+               },
+
+               /**
+                * @see Query.valueview.Expert.parser
+                */
+               parser: function() {
+                       return new wb.EntityIdParser( {
+                               'prefixmap': WB_ENTITIES_PREFIXMAP
+                       } );
+               },
+
+               /**
+                * @see Query.valueview.experts.StringValue.draw
+                */
+               draw: function() {
+                       this._newValue = false; // we use the entityselector to 
manage the value immediately
+                       PARENT.prototype.draw.call( this );
+
+                       // Make sure entityselector is closed in non-edit mode:
+                       if( !this._viewState.isInEditMode() ) {
+                               this.$input.data( 'entityselector' ).close();
+                       }
+               }
+       } );
+
+}( mediaWiki, wikibase, dataValues, valueParsers, jQuery, jQuery.valueview ) );
diff --git 
a/lib/resources/jquery.valueview.experts.wikibase/experts.wikibase.EntityIdValue.js
 
b/lib/resources/jquery.valueview.experts.wikibase/experts.wikibase.EntityIdValue.js
new file mode 100644
index 0000000..9a776e8
--- /dev/null
+++ 
b/lib/resources/jquery.valueview.experts.wikibase/experts.wikibase.EntityIdValue.js
@@ -0,0 +1,88 @@
+/**
+ * @file
+ * @ingroup WikibaseLib
+ * @licence GNU GPL v2+
+ * @author Daniel Werner < [email protected] >
+ */
+( function( mw, wb, dv, vp, $, vv ) {
+       'use strict';
+
+       // temporarily define a hard coded prefix map until we get this from 
the server
+       var WB_ENTITIES_PREFIXMAP = {
+               'q': 'item',
+               'p': 'property'
+       };
+
+       var PARENT = vv.BifidExpert,
+               editableExpert = vv.experts.wikibase.EntityIdInput;
+
+       /**
+        * Helper for building a pretty link or info about an Entity.
+        *
+        * @param {string} entityId
+        * @returns jQuery
+        */
+       function buildEntityRefDom( entityId ) {
+               var fetchedEntity = wb.fetchedEntities[ entityId ];
+
+               if( !fetchedEntity ) {
+                       // Entity missing, deleted or not in local store, 
generate info:
+                       return wb.utilities.ui.buildMissingEntityInfo( 
entityId, wb.Item );
+               }
+
+               var $label = wb.utilities.ui.buildPrettyEntityLabel( 
fetchedEntity.getContent() );
+
+               return $( '<a/>', {
+                       href: fetchedEntity.getTitle().getUrl()
+               } ).append( $label );
+       }
+
+       /**
+        * Valueview expert for handling Wikibase Entity references.
+        *
+        * @since 0.4
+        *
+        * @constructor
+        * @extends jQuery.valueview.experts.StringValue
+        */
+       vv.experts.wikibase.EntityIdValue = vv.expert( 'commonsmediatype', 
PARENT, {
+               /**
+                * @see jQuery.valueview.BifidExpert._editableExpert
+                */
+               _editableExpert: editableExpert,
+
+               /**
+                * @see jQuery.valueview.BifidExpert._staticExpert
+                */
+               _staticExpert: vv.experts.StaticDom,
+
+               /**
+                * @see jQuery.valueview.BifidExpert._staticExpertOptions
+                */
+               _staticExpertOptions: {
+                       domBuilder: function( currentRawValue, viewState ) {
+                               if( !currentRawValue ) {
+                                       return '';
+                               }
+
+                               // We have to check for string or instance of 
wb.EntityId since the EntityIdInput
+                               // expert has this huge flaw that it takes a 
wb.EntityId but returns a string as
+                               // raw value. This is all related to the 
current entity ID mess.
+                               var entityId = currentRawValue instanceof 
wb.EntityId
+                                       ? currentRawValue.getPrefixedId( 
WB_ENTITIES_PREFIXMAP )
+                                       : currentRawValue;
+
+                               return buildEntityRefDom( entityId );
+                       },
+                       baseExpert: editableExpert
+               }
+       } );
+
+       // Make the above expert available for wb.EntityId data value handling.
+       // TODO: Move this in some kind of higher initialization file once we 
have more like this:
+       mw.ext.valueView.expertProvider.registerExpert(
+               wb.EntityId,
+               vv.experts.wikibase.EntityIdValue
+       );
+
+}( mediaWiki, wikibase, dataValues, valueParsers, jQuery, jQuery.valueview ) );
diff --git 
a/lib/resources/jquery.valueview.experts.wikibase/experts.wikibase.js 
b/lib/resources/jquery.valueview.experts.wikibase/experts.wikibase.js
new file mode 100644
index 0000000..73ffe7b
--- /dev/null
+++ b/lib/resources/jquery.valueview.experts.wikibase/experts.wikibase.js
@@ -0,0 +1,16 @@
+/**
+ * @file
+ * @ingroup WikibaseLib
+ * @licence GNU GPL v2+
+ * @author Daniel Werner < [email protected] >
+ */
+( function( wb, $, vv ) {
+       'use strict';
+
+       /**
+        * Space for Wikibase related jQuery.valueview experts.
+        * @type Object
+        */
+       vv.experts.wikibase = {};
+
+}( wikibase, jQuery, jQuery.valueview ) );
diff --git a/lib/resources/jquery.valueview.views/views.css 
b/lib/resources/jquery.valueview.views/views.css
deleted file mode 100644
index c562162..0000000
--- a/lib/resources/jquery.valueview.views/views.css
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * Styles for Wikibase valueview views.
- *
- * @since 0.1
- * @file
- * @ingroup WikibaseLib
- *
- * @license GNU GPL v2+
- * @author Daniel Werner < [email protected] >
- */
diff --git a/lib/resources/jquery.valueview.views/wikibaseItem.js 
b/lib/resources/jquery.valueview.views/wikibaseItem.js
deleted file mode 100644
index 6488764..0000000
--- a/lib/resources/jquery.valueview.views/wikibaseItem.js
+++ /dev/null
@@ -1,172 +0,0 @@
-/**
- * Widget for editing values of the Wikibase specific item DataType.
- *
- * @licence GNU GPL v2+
- * @author Daniel Werner < [email protected] >
- */
-( function( mw, wb, dv, vp, dt, $ ) {
-       'use strict';
-
-       var PARENT = $.valueview.LinkedSingleInputWidget,
-               // temporarily define a hard coded prefix map until we get this 
from the server
-               WB_ENTITIES_PREFIXMAP = {
-                       'q': 'item',
-                       'p': 'property'
-               };
-
-       $.valueview.widget( 'wikibaseitem', PARENT, {
-               /**
-                * @see jQuery.valueview.Widget.dataTypeId
-                */
-               dataValueType: 'wikibase-entityid',
-
-               /**
-                * Only trigger parsing/validation of value when entity has 
been selected, not after each
-                * change in the input field since at that time the entity 
selector's API call isn not done.
-                * @see jQuery.valueview.Widget.dataTypeId
-                */
-               updateValueEvents: 'eachchange entityselectorselect',
-
-               /**
-                * @see jQuery.Widget._create
-                */
-               _create: function() {
-                       // TODO: replace hardcoded options
-                       this.valueParser = new wb.EntityIdParser( {
-                               'prefixmap': WB_ENTITIES_PREFIXMAP
-                       } );
-
-                       // TODO: properly inject options
-                       this.valueParser = new wb.EntityIdParser( {
-                               'prefixmap': {
-                                       'q': 'item',
-                                       'p': 'property'
-                               }
-                       } );
-
-                       PARENT.prototype._create.call( this );
-               },
-
-               /**
-                * Builds the input element for editing, ready to be inserted 
into the DOM.
-                *
-                * @return {jQuery}
-                * @private
-                */
-               _buildInputDom: function() {
-                       return $( '<textarea/>', {
-                               'class': this.widgetBaseClass + '-input',
-                               'type': 'text',
-                               'placeholder': this.option( 'inputPlaceholder' )
-                       } )
-                       .inputAutoExpand( { expandWidth: false, 
expandHeight:true, suppressNewLine: true } )
-                       .entityselector( {
-                               url: mw.util.wikiScript( 'api' ),
-                               selectOnAutocomplete: true
-                       } )
-                       .eachchange( function( event, oldValue ) {
-                               $( this ).data( 'entityselector' 
).repositionMenu();
-                       } )
-                       .on( 'entityselectorselect', function( e, ui ) {
-                               var itemData = {
-                                       id: ui.item.id,
-                                       label: {}
-                               };
-                               itemData.label[ mw.config.get( 'wgUserLanguage' 
) ] = ui.item.label;
-
-                               // update local store with newest information 
about selected item
-                               // TODO: create more sophisticated local store 
interface rather than accessing
-                               //       wb.fetchedEntities directly
-                               wb.fetchedEntities[ ui.item.id ] = new 
wb.store.FetchedContent( {
-                                       // TODO: *terrible* solution to use 
regex, entityselector should provide title
-                                       title: new mw.Title( ui.item.url.match( 
/[^\/]+$/ )[0] ),
-                                       content: new wb.Item( itemData )
-                               } );
-                       } )
-                       .on(
-                               // "aftersetentity": When setting the entity 
programmatically (editing an existing
-                               // Snak).
-                               // "response": Each time an API query returns 
(the input value gets auto-completed).
-                               // "close": After having selected an entity by 
clicking on a suggestion list item.
-                               'entityselectoraftersetentity 
entityselectorresponse entityselectorclose',
-                               function( e ) {
-                                       $( this ).data( 'AutoExpandInput' 
).expand();
-                                       $( this ).data( 'entityselector' 
).repositionMenu();
-                               }
-                       );
-               },
-
-               /**
-                * @see jQuery.valueview.Widget._displayValue
-                * @param {wb.EntityId} value
-                */
-               _displayValue: function( value ) {
-                       if( this.$input ) {
-                               var entityId = value === null ? null : 
value.getPrefixedId( WB_ENTITIES_PREFIXMAP ),
-                                       fetchedEntity = entityId ? 
wb.fetchedEntities[ entityId ] : null,
-                                       simpleEntity = null;
-
-                               if( fetchedEntity ) {
-                                       // entity selector requires very basic 
data only, but ID has to be set which is
-                                       // not the case in the 
wb.fetchedEntities entity store.
-                                       simpleEntity = {
-                                               label: 
fetchedEntity.getContent().getLabel(),
-                                               id: entityId
-                                       };
-                               }
-
-                               // in edit mode:
-                               this.$input.data( 'entityselector' 
).selectedEntity( simpleEntity );
-                               // TODO: entityselector should just be able to 
handle wb.Entity without making it a
-                               //  dependency there.
-                       } else {
-                               // in static mode:
-                               PARENT.prototype._displayValue.call( this, 
value );
-                       }
-               },
-
-               /**
-                * @see 
$.valueview.LinkedSingleInputWidget._getLinkHrefFromValue
-                */
-               _getLinkHrefFromValue: function( value ) {
-                       if( !value ) {
-                               return '';
-                       }
-                       var itemId = value.getPrefixedId( WB_ENTITIES_PREFIXMAP 
),
-                               fetchedItem = wb.fetchedEntities[ itemId ],
-                               url = fetchedItem ? 
fetchedItem.getTitle().getUrl() : false;
-
-                       return url || '';
-               },
-
-               /**
-                * @see 
$.valueview.LinkedSingleInputWidget._getLinkTextFromValue
-                */
-               _getLinkContentFromValue: function( value ) {
-                       if( !value ) {
-                               return '';
-                       }
-                       var itemId = value.getPrefixedId( WB_ENTITIES_PREFIXMAP 
),
-                               fetchedItem = wb.fetchedEntities[ itemId ];
-
-                       if( !fetchedItem ) {
-                               return wb.utilities.ui.buildMissingEntityInfo( 
itemId, wb.Item );
-                       }
-                       return wb.utilities.ui.buildPrettyEntityLabel( 
fetchedItem.getContent() );
-               },
-
-               /**
-                * @see jQuery.valueview.Widget._getRawValue
-                */
-               _getRawValue: function() {
-                       if( this.$input ) {
-                               var entitySelector = this.$input.data( 
'entityselector' ),
-                                       selectedEntity = 
entitySelector.selectedEntity();
-
-                               return selectedEntity ? selectedEntity.id : 
null;
-                       }
-                       return this.$anchor.text();
-               }
-       } );
-
-}( mediaWiki, wikibase, dataValues, valueParsers, dataTypes, jQuery ) );

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic619890cc997e81a2c1f7839c8eb0d4cdffcf556
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Daniel Werner <[email protected]>

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

Reply via email to