Henning Snater has submitted this change and it was merged.
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.
- patch set 3: Entity ID input now auto resizes.
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, 260 insertions(+), 187 deletions(-)
Approvals:
Henning Snater: Verified; Looks good to me, approved
jenkins-bot: Checked
diff --git a/lib/resources/Resources.php b/lib/resources/Resources.php
index d49df6a..679563d 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,17 +633,17 @@
),
// 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',
'wikibase.parsers',
'jquery.eachchange',
+ 'jquery.inputAutoExpand',
'wikibase.utilities',
),
'messages' => array(
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..f946bc2
--- /dev/null
+++
b/lib/resources/jquery.valueview.experts.wikibase/experts.wikibase.EntityIdInput.js
@@ -0,0 +1,150 @@
+/**
+ * @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,
+ self = this;
+
+ $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 )
+ } );
+
+ self._resizeInput();
+ } )
+ .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 );
+ this._resizeInput();
+ // 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..afc515e
--- /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( 'entityidvalue', 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: merged
Gerrit-Change-Id: Ic619890cc997e81a2c1f7839c8eb0d4cdffcf556
Gerrit-PatchSet: 3
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Daniel Werner <[email protected]>
Gerrit-Reviewer: Henning Snater <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits