Tobias Gritschacher has uploaded a new change for review.

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


Change subject: Make use of new data model constructors all over the UI now
......................................................................

Make use of new data model constructors all over the UI now

* replaced wb.entities with wb.fetchedEntities, holding wb.FetchedContent now 
instead of wb.Entity
  instances. Includes some tests.
* wb.entity is a wb.Entity object representing the site's entity now.
* for unserializing JSON in entityViewInit we now use the 
wikibase.serialization module.
* wb.entityview is expecting a wb.Entity object instead of a loose data 
structure now.
* removed/changed some todos

Change-Id: I40bcc945610fe6f32e89fc12ea3b0def3126317a
---
M lib/resources/jquery.valueview.views/wikibaseItem.js
M lib/resources/jquery.wikibase/jquery.wikibase.claimlistview.js
M lib/resources/jquery.wikibase/jquery.wikibase.claimview.js
M lib/resources/jquery.wikibase/jquery.wikibase.entityview.js
M lib/resources/jquery.wikibase/jquery.wikibase.snakview/snakview.js
M 
lib/resources/jquery.wikibase/jquery.wikibase.snakview/snakview.variations.Value.js
M lib/resources/wikibase.js
M lib/resources/wikibase.utilities/wikibase.utilities.ui.js
M lib/tests/qunit/wikibase.datamodel/Wikibase.snak.tests.js
M repo/includes/EntityView.php
M repo/resources/Resources.php
M repo/resources/wikibase.ui.entityViewInit.js
12 files changed, 114 insertions(+), 86 deletions(-)


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

diff --git a/lib/resources/jquery.valueview.views/wikibaseItem.js 
b/lib/resources/jquery.valueview.views/wikibaseItem.js
index 5e4140b..3bd4f26 100644
--- a/lib/resources/jquery.valueview.views/wikibaseItem.js
+++ b/lib/resources/jquery.valueview.views/wikibaseItem.js
@@ -72,14 +72,20 @@
                                $( this ).data( 'entityselector' 
).repositionMenu();
                        } )
                        .on( 'entityselectorselect', function( e, ui ) {
+                               var itemData = {
+                                       id: ui.item.id,
+                                       label: {}
+                               };
+                               itemData.label[ language ] = ui.item.label;
+
                                // update local store with newest information 
about selected item
                                // TODO: create more sophisticated local store 
interface rather than accessing
-                               //       wb.entities directly
-                               wb.entities[ ui.item.id ] = {
-                                       id: ui.item.id,
-                                       label: ui.item.label,
-                                       url: ui.item.url
-                               };
+                               //       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
@@ -101,20 +107,22 @@
                _displayValue: function( value ) {
                        if( this.$input ) {
                                var entityId = value === null ? null : 
value.getPrefixedId( WB_ENTITIES_PREFIXMAP ),
-                                       entity = entityId ? wb.entities[ 
entityId ] : null,
+                                       fetchedEntity = entityId ? 
wb.fetchedEntities[ entityId ] : null,
                                        simpleEntity = null;
 
-                               if( entity ) {
+                               if( fetchedEntity ) {
                                        // entity selector requires very basic 
data only, but ID has to be set which is
-                                       // not the case in the wb.entities 
entity store.
+                                       // not the case in the 
wb.fetchedEntities entity store.
                                        simpleEntity = {
-                                               label: entity.label,
+                                               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 );
@@ -129,8 +137,8 @@
                                return '';
                        }
                        var itemId = value.getPrefixedId( WB_ENTITIES_PREFIXMAP 
),
-                               item = wb.entities[ itemId ],
-                               url = item ? item.url : false;
+                               fetchedItem = wb.fetchedEntities[ itemId ],
+                               url = fetchedItem ? 
fetchedItem.getTitle().getUrl() : false;
 
                        return url || '';
                },
@@ -143,19 +151,21 @@
                                return '';
                        }
                        var itemId = value.getPrefixedId( WB_ENTITIES_PREFIXMAP 
),
-                               item = wb.entities[ itemId ];
+                               fetchedItem = wb.fetchedEntities[ itemId ];
 
-                       if( !item ) {
+                       if( !fetchedItem ) {
                                return itemId;
                        }
 
-                       if( !item.label ) {
+                       var label = fetchedItem.getContent().getLabel();
+
+                       if( !label ) {
                                return $( document.createTextNode( itemId + ' ' 
) ).add(
                                        $( '<span/>' ).text( '(' + mw.msg( 
'wikibase-label-empty' ) + ')' )
                                );
                        }
 
-                       return item.label;
+                       return label;
                },
 
                /**
diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.claimlistview.js 
b/lib/resources/jquery.wikibase/jquery.wikibase.claimlistview.js
index 48d9901..b84a6d1 100644
--- a/lib/resources/jquery.wikibase/jquery.wikibase.claimlistview.js
+++ b/lib/resources/jquery.wikibase/jquery.wikibase.claimlistview.js
@@ -254,11 +254,11 @@
                var $section = this.$claims.children( '.wb-claim-section-' + 
mainSnakPropertyId ).first();
 
                if( $section.length === 0 ) {
-                       var property = wb.entities[ mainSnakPropertyId ],
+                       var fetchedProperty = wb.fetchedEntities[ 
mainSnakPropertyId ],
                                $addClaim,
                                self = this;
 
-                       if( !property ) {
+                       if( !fetchedProperty ) {
                                // Property info not in local store.
                                // This should not ever happen if used 
properly, but make sure!
                                throw new Error( 'Information for Property "' + 
mainSnakPropertyId + '" not found '
@@ -276,7 +276,9 @@
                        // create new section for first Claim in this section
                        $section = mw.template( 'wb-claim-section',
                                mainSnakPropertyId, // main Snak's property ID
-                               wb.utilities.ui.buildEntityLink( property ), // 
property name
+                               wb.utilities.ui.buildLinkToEntityPage( // 
property name
+                                       fetchedProperty.getContent(),
+                                       fetchedProperty.getTitle().getUrl() ),
                                $addClaim // claim
                        ).appendTo( this.$claims );
 
diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.claimview.js 
b/lib/resources/jquery.wikibase/jquery.wikibase.claimview.js
index 4e23194..6b18103 100644
--- a/lib/resources/jquery.wikibase/jquery.wikibase.claimview.js
+++ b/lib/resources/jquery.wikibase/jquery.wikibase.claimview.js
@@ -171,12 +171,11 @@
                } );
 
                if ( this._claim || this.options.predefined.mainSnak ) {
-                       var propertyName;
-                       if ( this._claim ) {
-                               propertyName = 
wb.entities[this.mainSnak().getPropertyId()].label;
-                       } else {
-                               propertyName = 
wb.entities[this.options.predefined.mainSnak.property].label;
-                       }
+                       var property = this._claim
+                               ? this.mainSnak().getPropertyId()
+                               : this.options.predefined.mainSnak.property;
+
+                       var propertyName = wb.fetchedEntities[ property 
].getContent().getLabel();
                        this.options.helpMessage = mw.msg( 
'wikibase-claimview-snak-tooltip', propertyName );
                }
        },
diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.entityview.js 
b/lib/resources/jquery.wikibase/jquery.wikibase.entityview.js
index a7818ae..de592af 100644
--- a/lib/resources/jquery.wikibase/jquery.wikibase.entityview.js
+++ b/lib/resources/jquery.wikibase/jquery.wikibase.entityview.js
@@ -40,12 +40,13 @@
        _create: function() {
                this.element.empty();
 
-               var $claimsHeading =
-                       $( mw.template( 'wb-section-heading', mw.msg( 
'wikibase-statements' ) ) );
+               var entity = this.option( 'value' ),
+                       $claimsHeading =
+                               $( mw.template( 'wb-section-heading', mw.msg( 
'wikibase-statements' ) ) );
 
                this.$claims = $( '<div/>' ).claimlistview( {
-                       value: this.option( 'value' ).claims,
-                       entityId: this.option( 'value' ).id,
+                       value: entity.getClaims(),
+                       entityId: entity.getId(),
                        listMembersWidget: $.wikibase.statementview
                } );
 
diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.snakview/snakview.js 
b/lib/resources/jquery.wikibase/jquery.wikibase.snakview/snakview.js
index 878c348..e504b6b 100644
--- a/lib/resources/jquery.wikibase/jquery.wikibase.snakview/snakview.js
+++ b/lib/resources/jquery.wikibase/jquery.wikibase.snakview/snakview.js
@@ -219,13 +219,12 @@
 
                                // update local store with newest information 
about selected property
                                // TODO: create more sophisticated local store 
interface rather than accessing
-                               //       wb.entities directly
-                               wb.entities[ entityId ] = {
-                                       id: entityId,
-                                       label: entity.getLabel(),
-                                       datatype: entity.getDataType().getId(),
-                                       url: ui.item.url
-                               };
+                               //       wb.fetchedEntities directly
+                               wb.fetchedEntities[ entityId ] = new 
wb.store.FetchedContent( {
+                                       // TODO: *terrible* solution to use 
regex, entityselector should provide title
+                                       title: new mw.Title( ui.item.url.match( 
/[^\/]+$/ )[0] ),
+                                       content: entity
+                               } );
 
                                self.propertyId( entityId );
 
@@ -706,19 +705,20 @@
        drawProperty: function() {
                var $propertyDom,
                        propertyId = this._propertyId,
-                       property = propertyId ? wb.entities[ propertyId ] : 
null;
+                       fetchedProperty = propertyId ? wb.fetchedEntities[ 
propertyId ] : null,
+                       property = fetchedProperty ? 
fetchedProperty.getContent() : null;
 
                if( this.options.locked.property || !this.isInEditMode() ) {
                        // property set and can't be changed afterwards, only 
display label
                        $propertyDom = property
-                               ? wb.utilities.ui.buildEntityLink( property )
+                               ? wb.utilities.ui.buildLinkToEntityPage(
+                                       property, 
fetchedProperty.getTitle().getUrl() )
                                // shouldn't usually happen, only in non-edit 
mode, while no Snak is set:
                                : $( document.createTextNode( '' ) );
-                       // TODO: display nice label with link here, just like 
claimlistview
                } else {
                        // no property set for this Snak, serve edit view to 
specify it:
                        var propertySelector = this._getPropertySelector(),
-                               propertyLabel = property && ( property.label || 
propertyId ) || '';
+                               propertyLabel = property && ( 
property.getLabel() || propertyId ) || '';
 
                        // TODO: use selectedEntity() or other command to set 
selected entity in both cases!
                        if( propertySelector ) {
diff --git 
a/lib/resources/jquery.wikibase/jquery.wikibase.snakview/snakview.variations.Value.js
 
b/lib/resources/jquery.wikibase/jquery.wikibase.snakview/snakview.variations.Value.js
index 73cb093..1c8716e 100644
--- 
a/lib/resources/jquery.wikibase/jquery.wikibase.snakview/snakview.variations.Value.js
+++ 
b/lib/resources/jquery.wikibase/jquery.wikibase.snakview/snakview.variations.Value.js
@@ -86,7 +86,7 @@
                        // directly (also by user interaction) are always 
rendered immediately
                        if( newValue !== false ) {
                                var propertyId = this._viewState.propertyId(),
-                                       dataType = dt.getDataType( wb.entities[ 
propertyId ].datatype );
+                                       dataType = wb.fetchedEntities[ 
propertyId ].getContent().getDataType();
 
                                // if the new value's type is not the data 
value type used by the Snak's property
                                // data type, something is very wrong. Display 
warning!
diff --git a/lib/resources/wikibase.js b/lib/resources/wikibase.js
index 26f91df..e0ed59f 100644
--- a/lib/resources/wikibase.js
+++ b/lib/resources/wikibase.js
@@ -61,11 +61,19 @@
 
        /**
         * Holds very basic information about all entities used in the pages 
entity view. Entity IDs
-        * are used as keys for many inner hashes where each has 'id', 'url' 
and 'label' fields. In case
-        * of property entities also a 'datatype' field.
+        * are used as keys for many inner hashes where each is an instance of 
wb.FetchedContent.
+        * Each of those wb.FetchedContent instances holds an instance of 
wb.Entity as its content. This
+        * entity data might be incomplete though, it is guaranteed that ID, 
and label are provided,
+        * for wb.Property instances it is also guaranteed that the datatype is 
provided.
+        *
+        * TODO: This should vanish from here (since its global) and will be 
replaced with a proper
+        *       store interface which will be injected into each 
jQuery.wikibase.entityview
+        *
+        * @since 0.4
+        *
         * @type {Object}
         */
-       this.entities = {};
+       this.fetchedEntities = {};
 
        /**
         * Will hold a list of all the sites after getSites() was called. This 
will cache the result.
diff --git a/lib/resources/wikibase.utilities/wikibase.utilities.ui.js 
b/lib/resources/wikibase.utilities/wikibase.utilities.ui.js
index 12148fa..f60846e 100644
--- a/lib/resources/wikibase.utilities/wikibase.utilities.ui.js
+++ b/lib/resources/wikibase.utilities/wikibase.utilities.ui.js
@@ -101,30 +101,31 @@
        };
 
        /**
-        * Creates a pretty link to a entity's page. Expects information about 
the Entity as a plain
-        * Object with 'id', 'url' and 'label' fields. If the label is not set 
or empty, then the link
-        * will show the entity's ID and some explanatory text describing that 
the label hast not been
-        * set yet.
+        * Creates a pretty link to an entity's page. If the label is not yet 
set, then the link will
+        * show the entity's ID and some explanatory text describing that the 
label hast not been set
+        * yet. Requires an URL to the wikipage or equivalent, on which the 
Entity is represented.
         *
         * @since 0.4
         *
-        * @param {Object} entityData Requires 'url', 'id' and optionally 
'label' fields
-        * @return jQuery 'a' element
+        * @param {wb.Entity} entity
+        * @param {string} url
+        * @return {jQuery} An 'a' element
         */
-       wb.utilities.ui.buildEntityLink = function( entityData ) {
-               var $propertyLink = $( '<a/>', {
-                       href: entityData.url,
-                       text: entityData.label || entityData.id
+       wb.utilities.ui.buildLinkToEntityPage = function( entity, url ) {
+               var label = entity.getLabel();
+               var $entityLink = $( '<a/>', {
+                       href: url,
+                       text: label || entity.getId()
                } );
 
-               if( !entityData.label ) {
-                       $propertyLink.append( $( '<span/>', {
+               if( !label ) {
+                       $entityLink.append( $( '<span/>', {
                                'class': 'wb-entity-undefinedinfo',
                                'text': ' (' + mw.msg( 'wikibase-label-empty' ) 
+ ')'
                        } ) );
                }
 
-               return $propertyLink;
+               return $entityLink;
        };
 
        /**
diff --git a/lib/tests/qunit/wikibase.datamodel/Wikibase.snak.tests.js 
b/lib/tests/qunit/wikibase.datamodel/Wikibase.snak.tests.js
index 137d9b7..cb06eac 100644
--- a/lib/tests/qunit/wikibase.datamodel/Wikibase.snak.tests.js
+++ b/lib/tests/qunit/wikibase.datamodel/Wikibase.snak.tests.js
@@ -57,7 +57,7 @@
                                deobjectifiedSnak.equals( snak ) && 
snak.equals( deobjectifiedSnak ),
                                'Newly constructed Snak from json is equal to 
original Snak'
                        );
-               }
+               };
 
                $.each( snakInfo, function( i, info ) {
                        var snakConstructor = info[0],
diff --git a/repo/includes/EntityView.php b/repo/includes/EntityView.php
index 3cf483e..1efb24e 100644
--- a/repo/includes/EntityView.php
+++ b/repo/includes/EntityView.php
@@ -760,23 +760,29 @@
        protected static function getBasicEntityInfo( EntityLookup 
$entityLoader, array $entityIds, $langCode ) {
                wfProfileIn( __METHOD__ );
 
+               $entityContentFactory = EntityContentFactory::singleton();
                $entities = $entityLoader->getEntities( $entityIds );
                $entityInfo = array();
+
+               $serializerFactory = new SerializerFactory();
+               $serializationOptions = new 
\Wikibase\Lib\Serializers\EntitySerializationOptions();
+               $serializationOptions->setProps( array( 'labels', 
'descriptions', 'datatype' ) );
+
+               $serializationOptions->setLanguages( array( $langCode ) );
 
                foreach( $entities as $prefixedId => $entity ) {
                        if( $entity === null ) {
                                continue;
                        }
-                       $entities[ $prefixedId ] = $entity->getLabel( $langCode 
);
+                       $serializer = 
$serializerFactory->newSerializerForObject( $entity, $serializationOptions );
+                       $entityInfo[ $prefixedId ] = 
$serializer->getSerialized( $entity );
 
-                       $entityInfo[ $prefixedId ] = array(
-                               'label' => $entity->getLabel( $langCode ),
-                               'url' => 
EntityContentFactory::singleton()->getTitleForId( $entity->getId() 
)->getFullUrl()
-                       );
+                       $entityContent = $entityContentFactory->getFromId( 
$entity->getId() );
 
-                       if( $entity instanceof Property ) {
-                               $entityInfo[ $prefixedId ]['datatype'] = 
$entity->getDataType()->getId();
-                       }
+                       // TODO: should perhaps implement and use a 
EntityContentSerializer since this is mixed,
+                       //  serialized Entity and EntityContent data because of 
adding the URL:
+                       $entityInfo[ $prefixedId ]['title'] = 
$entityContent->getTitle()->getPrefixedText();
+                       $entityInfo[ $prefixedId ]['lastrevid'] = 
$entityContent->getWikiPage()->getRevision()->getId();
                }
 
                wfProfileOut( __METHOD__ );
diff --git a/repo/resources/Resources.php b/repo/resources/Resources.php
index dac0f07..ed41942 100644
--- a/repo/resources/Resources.php
+++ b/repo/resources/Resources.php
@@ -48,6 +48,8 @@
                                'wikibase.datamodel',
                                'jquery.json',
                                'jquery.cookie',
+                               'wikibase.serialization.entities',
+                               'wikibase.serialization.fetchedcontent'
                        ),
                        'messages' => array(
                                'wikibase-sitelinks',
diff --git a/repo/resources/wikibase.ui.entityViewInit.js 
b/repo/resources/wikibase.ui.entityViewInit.js
index 4bd2836..f8044aa 100644
--- a/repo/resources/wikibase.ui.entityViewInit.js
+++ b/repo/resources/wikibase.ui.entityViewInit.js
@@ -74,13 +74,29 @@
 
                if( mw.config.get( 'wbEntity' ) !== null ) {
                        var entityJSON = $.evalJSON( mw.config.get( 'wbEntity' 
) ),
-                               usedEntitiesJSON = $.evalJSON( mw.config.get( 
'wbUsedEntities' ) );
+                               usedEntitiesJSON = $.evalJSON( mw.config.get( 
'wbUsedEntities' ) ),
+                               unserializerFactory = new 
wb.serialization.SerializerFactory(),
+                               entityUnserializer = 
unserializerFactory.newUnserializerFor( wb.Entity );
+
+                       // unserializer for fetched content whose content is a 
wb.Entity:
+                       var fetchedEntityUnserializer = 
unserializerFactory.newUnserializerFor(
+                               wb.store.FetchedContent, {
+                                       contentUnserializer: entityUnserializer
+                               }
+                       );
+
+                       wb.entity = entityUnserializer.unserialize( entityJSON 
);
+                       entityJSON = null;
+
+                       $.each( usedEntitiesJSON, function( id, 
fetchedEntityJSON ) {
+                               wb.fetchedEntities[ id ] = 
fetchedEntityUnserializer.unserialize( fetchedEntityJSON );
+                       } );
 
                        // if there are no aliases yet, the DOM structure for 
creating new ones is created manually since it is not
                        // needed for running the page without JS
                        $( '.wb-aliases-empty' )
                        .each( function() {
-                               $( this ).replaceWith( 
wikibase.ui.AliasesEditTool.getEmptyStructure() );
+                               $( this ).replaceWith( 
wb.ui.AliasesEditTool.getEmptyStructure() );
                        } );
 
                        // edit tool for aliases:
@@ -88,29 +104,12 @@
                                new wb.ui.AliasesEditTool( this );
                        } );
 
-                       // Information about used properties:
-                       $.each( usedEntitiesJSON, function( id, entity ) {
-                               entity.id = id; // we don't get that in the 
JSON but it is essential for wb.entities
-                               wb.entities[ id ] = entity;
-                       } );
-
-                       // Definition of the views entity:
-                       if ( entityJSON.claims !== undefined ) {
-                               $.each( entityJSON.claims, function( 
propertyId, claims ) {
-                                       $.each( claims, function( i, claim ) {
-                                               wb.entity.claims.push( 
wb.Claim.newFromJSON( claim ) );
-                                       } );
-                               } );
-                       }
-                       wb.entity.id = entityJSON.id;
-                       wb.entity.type = entityJSON.type;
-
                        $( '.wb-section-heading' ).remove();
 
                        // BUILD CLAIMS VIEW:
                        // Note: $.entityview() only works for claims right 
now, the goal is to use it for more
                        var $claims = $( '.wb-claims' ).entityview( {
-                               value: wb.entity // only holds the claims of an 
entity page right now
+                               value: wb.entity
                        } );
 
                        // removing site links heading to rebuild it with value 
counter

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I40bcc945610fe6f32e89fc12ea3b0def3126317a
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: mw1.21-wmf11
Gerrit-Owner: Tobias Gritschacher <tobias.gritschac...@wikimedia.de>
Gerrit-Reviewer: Daniel Werner <daniel.wer...@wikimedia.de>

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

Reply via email to