Henning Snater has uploaded a new change for review.

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

Change subject: Split off itemview and propertyview from entityview
......................................................................

Split off itemview and propertyview from entityview

- Made entityview abstract
- Moved statement handling to itemview and propertyview
- Moved site link handling to itemview
- itemview and propertyview can be created without any pre-rendered static HTML 
now

Change-Id: Ia417c45af10c881a5edd4d2ef82649492922be05
---
M lib/resources/jquery.wikibase/jquery.wikibase.entityview.js
A lib/resources/jquery.wikibase/jquery.wikibase.itemview.js
A lib/resources/jquery.wikibase/jquery.wikibase.propertyview.js
M lib/resources/jquery.wikibase/resources.php
M lib/tests/qunit/jquery.wikibase/jquery.wikibase.entityview.tests.js
A lib/tests/qunit/jquery.wikibase/jquery.wikibase.itemview.tests.js
A lib/tests/qunit/jquery.wikibase/jquery.wikibase.propertyview.tests.js
M lib/tests/qunit/jquery.wikibase/resources.php
M repo/resources/Resources.php
M repo/resources/templates.php
M repo/resources/wikibase.ui.entityViewInit.js
11 files changed, 679 insertions(+), 216 deletions(-)


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

diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.entityview.js 
b/lib/resources/jquery.wikibase/jquery.wikibase.entityview.js
index b89dc33..9b9e861 100644
--- a/lib/resources/jquery.wikibase/jquery.wikibase.entityview.js
+++ b/lib/resources/jquery.wikibase/jquery.wikibase.entityview.js
@@ -8,16 +8,22 @@
        var PARENT = $.ui.TemplatedWidget;
 
 /**
- * View for displaying an entire wikibase entity.
- * @since 0.3
+ * Abstract base view for displaying Wikibase `Entity`s.
+ * @class jQuery.wikibase.entityview
  * @extends jQuery.ui.TemplatedWidget
+ * @abstract
+ * @since 0.3
+ *
+ * @constructor
  *
  * @option {wikibase.entityChangers.EntityChangersFactory} 
entityChangersFactory
- * @option {wikibase.datamodel.Entity} [value]
+ * @option {wikibase.datamodel.Entity} value
  * @option {wikibase.store.EntityStore} entityStore
  * @option {wikibase.ValueViewBuilder} valueViewBuilder
  * @option {dataTypes.DataTypeStore} dataTypeStore
  * @option {string[]} languages
+ *
+ * @throws {Error} when called.
  *
  * @event afterstartediting
  *        Triggered after the widget has switched to edit mode.
@@ -76,23 +82,32 @@
        $fingerprints: null,
 
        /**
-        * @type {jQuery}
+        * @see jQuery.ui.TemplatedWidget._create
+        *
+        * @throws {Error} when called.
         */
-       $claims: null,
+       _create: function() {
+               throw new Error( 'Abstract entityview cannot be created 
directly' );
+       },
 
        /**
+        * Main initialization actually calling parent's _create().
         * @see jQuery.ui.TemplatedWidget._create
+        * @protected
         *
         * @throws {Error} if a required options is missing.
         */
-       _create: function() {
+       _initEntityview: function() {
                if(
-                       !this.options.entityStore
+                       !this.options.value
+                       || !this.options.entityStore
                        || !this.options.valueViewBuilder
                        || !this.options.entityChangersFactory
                ) {
                        throw new Error( 'Required option(s) missing' );
                }
+
+               PARENT.prototype._create.call( this );
 
                this.$toc = $( '.toc', this.element );
 
@@ -101,21 +116,10 @@
                this._initAliases();
                this._initFingerprints();
 
-               // TODO: Have an itemview and propertyview instead of ugly hack 
here.
-               var entityType = this.options.value.getType();
-               if( this.element.find( '.wb-claimlistview' ).length > 0 ) {
-                       this._initClaims();
-               }
-
-               if( entityType === 'item' ) {
-                       this._initSiteLinks();
-               }
-
                this._attachEventHandlers();
        },
 
        _initLabel: function() {
-               // TODO: Allow initializing entitview on empty DOM
                this.$label = $( '.wb-firstHeading .wikibase-labelview', 
this.element ).first();
                if( !this.$label.length ) {
                        this.$label = $( '<div/>' );
@@ -186,7 +190,7 @@
                        return;
                }
 
-               this.$fingerprints = $( '.wikibase-fingerprintgroupview' );
+               this.$fingerprints = $( '.wikibase-fingerprintgroupview', 
this.element );
 
                if( !this.$fingerprints.length ) {
                        var $precedingNode = this.$toc;
@@ -241,78 +245,6 @@
                } );
        },
 
-       _initClaims: function() {
-               this.$claims = $( '.wb-claimgrouplistview', this.element 
).first();
-               if( this.$claims.length === 0 ) {
-                       this.$claims = $( '<div/>' ).appendTo( this.element );
-               }
-
-               this.$claims
-               .claimgrouplistview( {
-                       value: this.options.value.getStatements(),
-                       dataTypeStore: this.option( 'dataTypeStore' ),
-                       entityType: this.options.value.getType(),
-                       entityStore: this.options.entityStore,
-                       valueViewBuilder: this.options.valueViewBuilder,
-                       entityChangersFactory: 
this.options.entityChangersFactory
-               } )
-               .claimgrouplabelscroll();
-
-               // This is here to be sure there is never a duplicate id:
-               $( '.wb-claimgrouplistview' )
-               .prev( '.wb-section-heading' )
-               .first()
-               .attr( 'id', 'claims' );
-       },
-
-       _initSiteLinks: function() {
-               var self = this;
-
-               this.$siteLinks = $( '.wikibase-sitelinkgrouplistview', 
this.element );
-
-               if( this.$siteLinks.length === 0 ) {
-                       // Properties for example don't have sitelinks
-                       return;
-               }
-
-               // Scrape group and site link order from existing DOM:
-               var value = [];
-               this.$siteLinks.find( '.wikibase-sitelinkgroupview' ).each( 
function() {
-                       var $sitelinkgroupview = $( this ),
-                               $sitelinklistview = $sitelinkgroupview.find( 
'.wikibase-sitelinklistview' ),
-                               group = $sitelinkgroupview.data( 
'wb-sitelinks-group' ),
-                               siteIdsOfGroup = [],
-                               siteLinkSet = self.options.value.getSiteLinks(),
-                               siteLinkIds = siteLinkSet.getKeys(),
-                               siteLinksOfGroup = [];
-
-                       $sitelinklistview.find( '.wikibase-sitelinkview' 
).each( function() {
-                               siteIdsOfGroup.push( $( this ).data( 
'wb-siteid' ) );
-                       } );
-
-                       for( var i = 0; i < siteIdsOfGroup.length; i++ ) {
-                               for( var j = 0; j < siteLinkIds.length; j++ ) {
-                                       if( siteLinkIds[j] === 
siteIdsOfGroup[i] ) {
-                                               siteLinksOfGroup.push( 
siteLinkSet.getItemByKey( siteLinkIds[j] ) );
-                                               break;
-                                       }
-                               }
-                       }
-
-                       value.push( {
-                               group: group,
-                               siteLinks: siteLinksOfGroup
-                       } );
-               } );
-
-               this.$siteLinks.sitelinkgrouplistview( {
-                       value: value,
-                       entityId: self.options.value.getId(),
-                       siteLinksChanger: 
self.options.entityChangersFactory.getSiteLinksChanger(),
-                       entityStore: self.options.entityStore
-               } );
-       },
-
        _attachEventHandlers: function() {
                var self = this;
 
@@ -321,11 +253,7 @@
                        'labelviewafterstartediting.' + this.widgetName,
                        'descriptionviewafterstartediting.' + this.widgetName,
                        'aliasesviewafterstartediting.' + this.widgetName,
-                       'fingerprintgroupviewafterstartediting.' + 
this.widgetName,
-                       'claimviewafterstartediting.' + this.widgetName,
-                       'statementviewafterstartediting.' + this.widgetName,
-                       'referenceviewafterstartediting.' + this.widgetName,
-                       'sitelinkgroupviewafterstartediting.' + this.widgetName
+                       'fingerprintgroupviewafterstartediting.' + 
this.widgetName
                ].join( ' ' ),
                function( event ) {
                        self._trigger( 'afterstartediting' );
@@ -336,13 +264,7 @@
                        'labelviewafterstopediting.' + this.widgetName,
                        'descriptionviewafterstopediting.' + this.widgetName,
                        'aliasesviewafterstopediting.' + this.widgetName,
-                       'fingerprintgroupviewafterstopediting.' + 
this.widgetName,
-                       'claimlistviewafterremove.' + this.widgetName,
-                       'claimviewafterstopediting.' + this.widgetName,
-                       'statementviewafterstopediting.' + this.widgetName,
-                       'statementviewafterremove.' + this.widgetName,
-                       'referenceviewafterstopediting.' + this.widgetName,
-                       'sitelinkgroupviewafterstopediting.' + this.widgetName
+                       'fingerprintgroupviewafterstopediting.' + 
this.widgetName
                ].join( ' ' ),
                function( event, dropValue ) {
                        self._trigger( 'afterstopediting', null, [dropValue] );
@@ -371,22 +293,6 @@
                this.$aliases.data( 'aliasesview' )[state]();
                if( this.$fingerprints ) {
                        this.$fingerprints.data( 'fingerprintgroupview' 
)[state]();
-               }
-
-               // horrible, horrible hack until we have proper item and 
property views
-               if( this.$claims ) {
-                       this.$claims.data( 'claimgrouplistview' )[state]();
-                       // TODO: Resolve integration of referenceviews
-                       this.$claims.find( '.wb-statement-references' ).each( 
function() {
-                               var $listview = $( this ).children( 
':wikibase-listview' );
-                               if( $listview.length ) {
-                                       $listview.data( 'listview' )[state]();
-                               }
-                       } );
-               }
-
-               if( this.$siteLinks && this.$siteLinks.length > 0 ) {
-                       this.$siteLinks.data( 'sitelinkgrouplistview' 
)[state]();
                }
        },
 
@@ -427,4 +333,23 @@
        }
 } );
 
+/**
+ * List of entityview types. Every entityview type should add itself to the 
list in order to be
+ * matched by $( ':wikibase-entityview' ) pseudo selector.
+ * @property {string[]}
+ * @static
+ */
+$.wikibase.entityview.TYPES = [];
+
+$.expr[':']['wikibase-entityview'] = $.expr.createPseudo( function( fullName ) 
{
+       return function( elem ) {
+               for( var i = 0; i < $.wikibase.entityview.TYPES.length; i++ ) {
+                       if( !!$.data( elem, $.wikibase.entityview.TYPES[i] ) ) {
+                               return true;
+                       }
+               }
+               return false;
+       };
+} );
+
 }( wikibase, jQuery, mediaWiki ) );
diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.itemview.js 
b/lib/resources/jquery.wikibase/jquery.wikibase.itemview.js
new file mode 100644
index 0000000..6eb8b13
--- /dev/null
+++ b/lib/resources/jquery.wikibase/jquery.wikibase.itemview.js
@@ -0,0 +1,228 @@
+( function( $, wb ) {
+       'use strict';
+
+var PARENT = $.wikibase.entityview;
+
+/**
+ * View for displaying a Wikibase `Item`.
+ * @see wikibase.datamodel.Item
+ * @class jQuery.wikibase.itemview
+ * @extends jQuery.wikibase.entityview
+ * @uses jQuery.wikibase.claimgrouplistview
+ * @users jQuery.wikibase.claimgrouplabelscroll
+ * @uses jQuery.wikibase.sitelinkgroupview
+ * @since 0.5
+ * @licence GNU GPL v2+
+ * @author H. Snater < mediaw...@snater.com >
+ *
+ * @constructor
+ */
+$.widget( 'wikibase.itemview', PARENT, {
+       /**
+        * @see jQuery.Widget.widgetEventPrefix
+        */
+       widgetEventPrefix: $.wikibase.entityview.widgetName,
+
+       /**
+        * @property {jQuery}
+        * @protected
+        * @readonly
+        */
+       $statements: null,
+
+       /**
+        * @inheritdoc
+        * @protected
+        */
+       _create: function() {
+               this._initEntityview();
+               this._initStatements();
+               this._initSiteLinks();
+       },
+
+       /**
+        * @protected
+        */
+       _initStatements: function() {
+               this.$statements = $( '.wb-claimgrouplistview', this.element 
).first();
+               if( this.$statements.length === 0 ) {
+                       this.$statements = $( '<div/>' ).appendTo( this.element 
);
+               }
+
+               this.$statements
+               .claimgrouplistview( {
+                       value: this.options.value.getStatements(),
+                       dataTypeStore: this.option( 'dataTypeStore' ),
+                       entityType: this.options.value.getType(),
+                       entityStore: this.options.entityStore,
+                       valueViewBuilder: this.options.valueViewBuilder,
+                       entityChangersFactory: 
this.options.entityChangersFactory
+               } )
+               .claimgrouplabelscroll();
+
+               // This is here to be sure there is never a duplicate id:
+               $( '.wb-claimgrouplistview' )
+               .prev( '.wb-section-heading' )
+               .first()
+               .attr( 'id', 'claims' );
+       },
+
+       /**
+        * @protected
+        */
+       _initSiteLinks: function() {
+               var self = this,
+                       value = [];
+
+               this.$siteLinks = $( '.wikibase-sitelinkgrouplistview', 
this.element );
+
+               if( this.$siteLinks.length ) {
+                       value = scrapeSiteLinks( this.$siteLinks, 
this.options.value.getSiteLinks() );
+               } else {
+                       this.$siteLinks = $( '<div/>' ).appendTo( this.element 
);
+                       value = orderSiteLinksByGroup( 
this.options.value.getSiteLinks() );
+               }
+
+               this.$siteLinks.sitelinkgrouplistview( {
+                       value: value,
+                       entityId: self.options.value.getId(),
+                       siteLinksChanger: 
self.options.entityChangersFactory.getSiteLinksChanger(),
+                       entityStore: self.options.entityStore
+               } );
+       },
+
+       /**
+        * @inheritdoc
+        * @protected
+        */
+       _attachEventHandlers: function() {
+               PARENT.prototype._attachEventHandlers.call( this );
+
+               var self = this;
+
+               this.element
+               .on( [
+                       'statementviewafterstartediting.' + this.widgetName,
+                       'referenceviewafterstartediting.' + this.widgetName,
+                       'sitelinkgroupviewafterstartediting.' + this.widgetName
+               ].join( ' ' ),
+               function( event ) {
+                       self._trigger( 'afterstartediting' );
+               } );
+
+               this.element
+               .on( [
+                       'claimlistviewafterremove.' + this.widgetName,
+                       'statementviewafterstopediting.' + this.widgetName,
+                       'statementviewafterremove.' + this.widgetName,
+                       'referenceviewafterstopediting.' + this.widgetName,
+                       'sitelinkgroupviewafterstopediting.' + this.widgetName
+               ].join( ' ' ),
+               function( event, dropValue ) {
+                       self._trigger( 'afterstopediting', null, [dropValue] );
+               } );
+       },
+
+       /**
+        * @inheritdoc
+        * @protected
+        */
+       _setState: function( state ) {
+               PARENT.prototype._setState.call( this, state );
+
+               this.$statements.data( 'claimgrouplistview' )[state]();
+               // TODO: Resolve integration of referenceviews
+               this.$statements.find( '.wb-statement-references' ).each( 
function() {
+                       var $listview = $( this ).children( 
':wikibase-listview' );
+                       if( $listview.length ) {
+                               $listview.data( 'listview' )[state]();
+                       }
+               } );
+
+               this.$siteLinks.data( 'sitelinkgrouplistview' )[state]();
+       }
+} );
+
+/**
+ * Scrapes site links from static HTML in order to be sure the order in the 
static HTML matches the
+ * order set on the widget initialized on the HTML structure since that widget 
is not supposed to
+ * re-render the HTML for performance reasons.
+ * @ignore
+ *
+ * @param {jQuery} $siteLinks
+ * @param {wikibase.datamodel.SiteLinkSet} siteLinkSet
+ * @return {Object}
+ */
+function scrapeSiteLinks( $siteLinks, siteLinkSet ) {
+       var value = [];
+
+       $siteLinks.find( '.wikibase-sitelinkgroupview' ).each( function() {
+               var $sitelinkgroupview = $( this ),
+                       $sitelinklistview = $sitelinkgroupview.find( 
'.wikibase-sitelinklistview' ),
+                       group = $sitelinkgroupview.data( 'wb-sitelinks-group' ),
+                       siteIdsOfGroup = [],
+                       siteLinkIds = siteLinkSet.getKeys(),
+                       siteLinksOfGroup = [];
+
+               $sitelinklistview.find( '.wikibase-sitelinkview' ).each( 
function() {
+                       siteIdsOfGroup.push( $( this ).data( 'wb-siteid' ) );
+               } );
+
+               for( var i = 0; i < siteIdsOfGroup.length; i++ ) {
+                       for( var j = 0; j < siteLinkIds.length; j++ ) {
+                               if( siteLinkIds[j] === siteIdsOfGroup[i] ) {
+                                       siteLinksOfGroup.push( 
siteLinkSet.getItemByKey( siteLinkIds[j] ) );
+                                       break;
+                               }
+                       }
+               }
+
+               value.push( {
+                       group: group,
+                       siteLinks: siteLinksOfGroup
+               } );
+       } );
+
+       return value;
+}
+
+/**
+ * Maps site links of a `wikibase.datamodel.SiteLinkSet` to their Wikibase 
site groups.
+ * @ignore
+ *
+ * @param {wikibase.datamodel.SiteLinkSet} siteLinkSet
+ * @return {Object}
+ */
+function orderSiteLinksByGroup( siteLinkSet ) {
+       var value = [];
+
+       siteLinkSet.each( function( siteId, siteLink ) {
+               var site = wb.sites.getSite( siteId ),
+                       found = false;
+
+               if( !site ) {
+                       throw new Error( 'Site with id ' + siteId + ' is not 
registered' );
+               }
+
+               for( var i = 0; i < value.length; i++ ) {
+                       if( value[i].group === site.getGroup() ) {
+                               value[i].siteLinks.push( siteLink );
+                               found = true;
+                               break;
+                       }
+               }
+
+               if( !found ) {
+                       value.push( {
+                               group: site.getGroup(),
+                               siteLinks: [siteLink]
+                       } );
+               }
+       } );
+
+       return value;
+}
+
+$.wikibase.entityview.TYPES.push( $.wikibase.itemview.prototype.widgetName );
+
+}( jQuery, wikibase ) );
diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.propertyview.js 
b/lib/resources/jquery.wikibase/jquery.wikibase.propertyview.js
new file mode 100644
index 0000000..830d344
--- /dev/null
+++ b/lib/resources/jquery.wikibase/jquery.wikibase.propertyview.js
@@ -0,0 +1,146 @@
+( function( $, mw ) {
+       'use strict';
+
+var PARENT = $.wikibase.entityview;
+
+/**
+ * View for displaying a Wikibase `Property`.
+ * @see wikibase.datamodel.Property
+ * @class jQuery.wikibase.propertyview
+ * @extends jQuery.wikibase.entityview
+ * @uses jQuery.wikibase.claimgrouplistview
+ * @users jQuery.wikibase.claimgrouplabelscroll
+ * @since 0.5
+ * @licence GNU GPL v2+
+ * @author H. Snater < mediaw...@snater.com >
+ *
+ * @constructor
+ */
+$.widget( 'wikibase.propertyview', PARENT, {
+       /**
+        * @see jQuery.Widget.widgetEventPrefix
+        */
+       widgetEventPrefix: $.wikibase.entityview.widgetName,
+
+       /**
+        * @property {jQuery}
+        * @protected
+        * @readonly
+        */
+       $dataType: null,
+
+       /**
+        * @property {jQuery}
+        * @protected
+        * @readonly
+        */
+       $statements: null,
+
+       /**
+        * @inheritdoc
+        * @protected
+        */
+       _create: function() {
+               this._initEntityview();
+               this._initDataType();
+               this._initStatements();
+       },
+
+       /**
+        * @protected
+        */
+       _initDataType: function() {
+               // TODO: Implement propertyview template to have static HTML 
rendered by the back-end match
+               // the HTML rendered here without having to invoke templating 
mechanism here.
+
+               if( this.$dataType ) {
+                       return;
+               }
+
+               this.$dataType = $( '.wikibase-propertyview-datatype', 
this.element );
+
+               if( !this.$dataType.length ) {
+                       this.$dataType = mw.wbTemplate( 
'wikibase-propertyview-datatype',
+                               this.options.value.getDataTypeId()
+                       ).appendTo( this.element );
+               }
+       },
+
+       /**
+        * @protected
+        */
+       _initStatements: function() {
+               this.$statements = $( '.wb-claimgrouplistview', this.element 
).first();
+               if( this.$statements.length === 0 ) {
+                       this.$statements = $( '<div/>' ).appendTo( this.element 
);
+               }
+
+               this.$statements
+               .claimgrouplistview( {
+                       value: this.options.value.getStatements(),
+                       dataTypeStore: this.option( 'dataTypeStore' ),
+                       entityType: this.options.value.getType(),
+                       entityStore: this.options.entityStore,
+                       valueViewBuilder: this.options.valueViewBuilder,
+                       entityChangersFactory: 
this.options.entityChangersFactory
+               } )
+               .claimgrouplabelscroll();
+
+               // This is here to be sure there is never a duplicate id:
+               $( '.wb-claimgrouplistview' )
+               .prev( '.wb-section-heading' )
+               .first()
+               .attr( 'id', 'claims' );
+       },
+
+       /**
+        * @inheritdoc
+        * @protected
+        */
+       _attachEventHandlers: function() {
+               PARENT.prototype._attachEventHandlers.call( this );
+
+               var self = this;
+
+               this.element
+               .on( [
+                       'statementviewafterstartediting.' + this.widgetName,
+                       'referenceviewafterstartediting.' + this.widgetName
+               ].join( ' ' ),
+               function( event ) {
+                       self._trigger( 'afterstartediting' );
+               } );
+
+               this.element
+               .on( [
+                       'claimlistviewafterremove.' + this.widgetName,
+                       'statementviewafterstopediting.' + this.widgetName,
+                       'statementviewafterremove.' + this.widgetName,
+                       'referenceviewafterstopediting.' + this.widgetName
+               ].join( ' ' ),
+               function( event, dropValue ) {
+                       self._trigger( 'afterstopediting', null, [dropValue] );
+               } );
+       },
+
+       /**
+        * @inheritdoc
+        * @protected
+        */
+       _setState: function( state ) {
+               PARENT.prototype._setState.call( this, state );
+
+               this.$statements.data( 'claimgrouplistview' )[state]();
+               // TODO: Resolve integration of referenceviews
+               this.$statements.find( '.wb-statement-references' ).each( 
function() {
+                       var $listview = $( this ).children( 
':wikibase-listview' );
+                       if( $listview.length ) {
+                               $listview.data( 'listview' )[state]();
+                       }
+               } );
+       }
+} );
+
+$.wikibase.entityview.TYPES.push( $.wikibase.propertyview.prototype.widgetName 
);
+
+}( jQuery, mediaWiki ) );
diff --git a/lib/resources/jquery.wikibase/resources.php 
b/lib/resources/jquery.wikibase/resources.php
index 6b9fa48..be5fd06 100644
--- a/lib/resources/jquery.wikibase/resources.php
+++ b/lib/resources/jquery.wikibase/resources.php
@@ -170,14 +170,9 @@
                        'dependencies' => array(
                                'jquery.ui.TemplatedWidget',
                                'jquery.wikibase.aliasesview',
-                               'jquery.wikibase.claimgrouplistview',
-                               'jquery.wikibase.claimlistview',
                                'jquery.wikibase.descriptionview',
                                'jquery.wikibase.fingerprintgroupview',
                                'jquery.wikibase.labelview',
-                               'jquery.wikibase.toolbarcontroller',
-                               'jquery.wikibase.sitelinkgrouplistview',
-                               'jquery.wikibase.statementview',
                                'wikibase.datamodel.MultiTerm',
                                'wikibase.datamodel.Term',
                                'wikibase.getLanguageNameByCode',
@@ -243,6 +238,18 @@
                        ),
                ),
 
+               'jquery.wikibase.itemview' => $moduleTemplate + array(
+                       'scripts' => array(
+                               'jquery.wikibase.itemview.js',
+                       ),
+                       'dependencies' => array(
+                               'jquery.wikibase.claimgrouplistview',
+                               'jquery.wikibase.entityview',
+                               'jquery.wikibase.sitelinkgrouplistview',
+                               'wikibase.sites',
+                       ),
+               ),
+
                'jquery.wikibase.labelview' => $moduleTemplate + array(
                        'scripts' => array(
                                'jquery.wikibase.labelview.js'
@@ -290,6 +297,16 @@
                        ),
                ),
 
+               'jquery.wikibase.propertyview' => $moduleTemplate + array(
+                       'scripts' => array(
+                               'jquery.wikibase.propertyview.js',
+                       ),
+                       'dependencies' => array(
+                               'jquery.wikibase.claimgrouplistview',
+                               'jquery.wikibase.entityview',
+                       ),
+               ),
+
                'jquery.wikibase.referenceview' => $moduleTemplate + array(
                        'scripts' => array(
                                'jquery.wikibase.referenceview.js',
diff --git 
a/lib/tests/qunit/jquery.wikibase/jquery.wikibase.entityview.tests.js 
b/lib/tests/qunit/jquery.wikibase/jquery.wikibase.entityview.tests.js
index b6c7d2b..021c512 100644
--- a/lib/tests/qunit/jquery.wikibase/jquery.wikibase.entityview.tests.js
+++ b/lib/tests/qunit/jquery.wikibase/jquery.wikibase.entityview.tests.js
@@ -2,89 +2,27 @@
  * @licence GNU GPL v2+
  * @author Adrian Lang <adrian.l...@wikimedia.de>
  */
-
 ( function( $, wb, QUnit ) {
 'use strict';
 
-/**
- * @param {Object} [options]
- * @param {jQuery} [$node]
- * @return {jQuery}
- */
-var createEntityview = function( options, $node ) {
-       options = $.extend( {
-               entityStore: 'i am an EntityStore',
-               entityChangersFactory: {
-                       getAliasesChanger: function() { return 'i am an 
AliasesChanger'; },
-                       getDescriptionsChanger: function() { return 'i am a 
DescriptionsChanger'; },
-                       getLabelsChanger: function() { return 'i am a 
LabelsChanger'; }
-               },
-               api: 'i am an Api',
-               valueViewBuilder: 'i am a valueview builder',
-               value: new wb.datamodel.Item( 'Q1' ) // FIXME: value is 
optional according to doc
-       }, options || {} );
+QUnit.module( 'jquery.wikibase.entityview' );
 
-       $node = $node || $( '<div/>' ).appendTo( 'body' );
-
-       var $entityview = $node
-               .addClass( 'test_entityview' )
-               .entityview( options );
-
-       $entityview.data( 'entityview' )._save = function() {
-               return $.Deferred().resolve( {
-                       entity: {
-                               lastrevid: 'i am a revision id'
-                       }
-               } ).promise();
-       };
-
-       return $entityview;
-};
-
-QUnit.module( 'jquery.wikibase.entityview', QUnit.newMwEnvironment( {
-       teardown: function() {
-               $( '.test_entityview' ).each( function() {
-                       var $entityview = $( this ),
-                               entityview = $entityview.data( 'entityview' );
-
-                       if( entityview ) {
-                               entityview.destroy();
-                       }
-
-                       $entityview.remove();
-               } );
-       }
-} ) );
-
-QUnit.test( 'Create & destroy', function( assert ) {
+QUnit.test( 'Direct initialization fails', function( assert ) {
        assert.throws(
                function() {
-                       createEntityview( { value: null } );
+                       $( '<div/>' ).entityview( $.extend( {
+                               entityStore: 'I am an EntityStore',
+                               entityChangersFactory: {
+                                       getAliasesChanger: function() { return 
'I am an AliasesChanger'; },
+                                       getDescriptionsChanger: function() { 
return 'I am a DescriptionsChanger'; },
+                                       getLabelsChanger: function() { return 
'I am a LabelsChanger'; }
+                               },
+                               api: 'I am an Api',
+                               valueViewBuilder: 'I am a valueview builder',
+                               value: new wb.datamodel.Property( 'P1', 
'someDataType' )
+                       } ) );
                },
-               'Throwing error when trying to initialize widget without a 
value.'
-       );
-
-       var $entityview = createEntityview(),
-               entityview = $entityview.data( 'entityview' );
-
-       assert.ok(
-               entityview instanceof $.wikibase.entityview,
-               'Created widget.'
-       );
-
-       entityview.destroy();
-
-       assert.ok(
-               $entityview.data( 'entityview' ) === undefined,
-               'Destroyed widget.'
-       );
-
-       $entityview = createEntityview( { languages: [ 'ku' ] } );
-       entityview = $entityview.data( 'entityview' );
-
-       assert.ok(
-               entityview instanceof $.wikibase.entityview,
-               'Created widget with a language.'
+               'Throwing error when trying to initialize widget directly.'
        );
 } );
 
diff --git a/lib/tests/qunit/jquery.wikibase/jquery.wikibase.itemview.tests.js 
b/lib/tests/qunit/jquery.wikibase/jquery.wikibase.itemview.tests.js
new file mode 100644
index 0000000..97f53f7
--- /dev/null
+++ b/lib/tests/qunit/jquery.wikibase/jquery.wikibase.itemview.tests.js
@@ -0,0 +1,91 @@
+/**
+ * @licence GNU GPL v2+
+ * @author H. Snater < mediaw...@snater.com >
+ */
+( function( $, wb, QUnit ) {
+'use strict';
+
+/**
+ * @param {Object} [options]
+ * @param {jQuery} [$node]
+ * @return {jQuery}
+ */
+var createItemview = function( options, $node ) {
+       options = $.extend( {
+               entityStore: 'I am an EntityStore',
+               entityChangersFactory: {
+                       getAliasesChanger: function() { return 'I am an 
AliasesChanger'; },
+                       getDescriptionsChanger: function() { return 'I am a 
DescriptionsChanger'; },
+                       getLabelsChanger: function() { return 'I am a 
LabelsChanger'; },
+                       getSiteLinksChanger: function() { return 'I am a 
SiteLinksChanger'; }
+               },
+               api: 'I am an Api',
+               valueViewBuilder: 'I am a valueview builder',
+               value: new wb.datamodel.Item( 'Q1' )
+       }, options || {} );
+
+       $node = $node || $( '<div/>' ).appendTo( 'body' );
+
+       var $itemview = $node
+               .addClass( 'test_itemview' )
+               .itemview( options );
+
+       $itemview.data( 'itemview' )._save = function() {
+               return $.Deferred().resolve( {
+                       entity: {
+                               lastrevid: 'i am a revision id'
+                       }
+               } ).promise();
+       };
+
+       return $itemview;
+};
+
+QUnit.module( 'jquery.wikibase.itemview', QUnit.newMwEnvironment( {
+       teardown: function() {
+               $( '.test_itemview' ).each( function() {
+                       var $itemview = $( this ),
+                               itemview = $itemview.data( 'itemview' );
+
+                       if( itemview ) {
+                               itemview.destroy();
+                       }
+
+                       $itemview.remove();
+               } );
+       }
+} ) );
+
+QUnit.test( 'Create & destroy', function( assert ) {
+       assert.throws(
+               function() {
+                       createItemview( { value: null } );
+               },
+               'Throwing error when trying to initialize widget without a 
value.'
+       );
+
+       var $itemview = createItemview(),
+               itemview = $itemview.data( 'itemview' );
+
+       assert.ok(
+               itemview instanceof $.wikibase.itemview,
+               'Created widget.'
+       );
+
+       itemview.destroy();
+
+       assert.ok(
+               $itemview.data( 'itemview' ) === undefined,
+               'Destroyed widget.'
+       );
+
+       $itemview = createItemview( { languages: ['ku'] } );
+       itemview = $itemview.data( 'itemview' );
+
+       assert.ok(
+               itemview instanceof $.wikibase.itemview,
+               'Created widget with a language.'
+       );
+} );
+
+}( jQuery, wikibase, QUnit ) );
diff --git 
a/lib/tests/qunit/jquery.wikibase/jquery.wikibase.propertyview.tests.js 
b/lib/tests/qunit/jquery.wikibase/jquery.wikibase.propertyview.tests.js
new file mode 100644
index 0000000..82db234
--- /dev/null
+++ b/lib/tests/qunit/jquery.wikibase/jquery.wikibase.propertyview.tests.js
@@ -0,0 +1,90 @@
+/**
+ * @licence GNU GPL v2+
+ * @author H. Snater < mediaw...@snater.com >
+ */
+( function( $, wb, QUnit ) {
+'use strict';
+
+/**
+ * @param {Object} [options]
+ * @param {jQuery} [$node]
+ * @return {jQuery}
+ */
+var createPropertyview = function( options, $node ) {
+       options = $.extend( {
+               entityStore: 'I am an EntityStore',
+               entityChangersFactory: {
+                       getAliasesChanger: function() { return 'I am an 
AliasesChanger'; },
+                       getDescriptionsChanger: function() { return 'I am a 
DescriptionsChanger'; },
+                       getLabelsChanger: function() { return 'I am a 
LabelsChanger'; }
+               },
+               api: 'I am an Api',
+               valueViewBuilder: 'I am a valueview builder',
+               value: new wb.datamodel.Property( 'P1', 'someDataType' )
+       }, options || {} );
+
+       $node = $node || $( '<div/>' ).appendTo( 'body' );
+
+       var $propertyview = $node
+               .addClass( 'test_propertyview' )
+               .propertyview( options );
+
+       $propertyview.data( 'propertyview' )._save = function() {
+               return $.Deferred().resolve( {
+                       entity: {
+                               lastrevid: 'i am a revision id'
+                       }
+               } ).promise();
+       };
+
+       return $propertyview;
+};
+
+QUnit.module( 'jquery.wikibase.propertyview', QUnit.newMwEnvironment( {
+       teardown: function() {
+               $( '.test_propertyview' ).each( function() {
+                       var $propertyview = $( this ),
+                               propertyview = $propertyview.data( 
'propertyview' );
+
+                       if( propertyview ) {
+                               propertyview.destroy();
+                       }
+
+                       $propertyview.remove();
+               } );
+       }
+} ) );
+
+QUnit.test( 'Create & destroy', function( assert ) {
+       assert.throws(
+               function() {
+                       createPropertyview( { value: null } );
+               },
+               'Throwing error when trying to initialize widget without a 
value.'
+       );
+
+       var $propertyview = createPropertyview(),
+               propertyview = $propertyview.data( 'propertyview' );
+
+       assert.ok(
+               propertyview instanceof $.wikibase.propertyview,
+               'Created widget.'
+       );
+
+       propertyview.destroy();
+
+       assert.ok(
+               $propertyview.data( 'propertyview' ) === undefined,
+               'Destroyed widget.'
+       );
+
+       $propertyview = createPropertyview( { languages: ['ku'] } );
+       propertyview = $propertyview.data( 'propertyview' );
+
+       assert.ok(
+               propertyview instanceof $.wikibase.propertyview,
+               'Created widget with a language.'
+       );
+} );
+
+}( jQuery, wikibase, QUnit ) );
diff --git a/lib/tests/qunit/jquery.wikibase/resources.php 
b/lib/tests/qunit/jquery.wikibase/resources.php
index 010a63e..38e9bc9 100644
--- a/lib/tests/qunit/jquery.wikibase/resources.php
+++ b/lib/tests/qunit/jquery.wikibase/resources.php
@@ -85,22 +85,22 @@
                        ),
                ),
 
-               'jquery.wikibase.entityview.tests' => $moduleBase + array(
-                       'scripts' => array(
-                               'jquery.wikibase.entityview.tests.js',
-                       ),
-                       'dependencies' => array(
-                               'jquery.wikibase.entityview',
-                               'wikibase.datamodel'
-                       ),
-               ),
-
                'jquery.wikibase.entityselector.tests' => $moduleBase + array(
                        'scripts' => array(
                                'jquery.wikibase.entityselector.tests.js',
                        ),
                        'dependencies' => array(
                                'jquery.wikibase.entityselector',
+                       ),
+               ),
+
+               'jquery.wikibase.entityview.tests' => $moduleBase + array(
+                       'scripts' => array(
+                               'jquery.wikibase.entityview.tests.js',
+                       ),
+                       'dependencies' => array(
+                               'jquery.wikibase.entityview',
+                               'wikibase.datamodel.Property',
                        ),
                ),
 
@@ -135,6 +135,16 @@
                        ),
                ),
 
+               'jquery.wikibase.itemview.tests' => $moduleBase + array(
+                       'scripts' => array(
+                               'jquery.wikibase.itemview.tests.js',
+                       ),
+                       'dependencies' => array(
+                               'jquery.wikibase.itemview',
+                               'wikibase.datamodel.Item',
+                       ),
+               ),
+
                'jquery.wikibase.labelview.tests' => $moduleBase + array(
                        'scripts' => array(
                                'jquery.wikibase.labelview.tests.js',
@@ -163,6 +173,16 @@
                        ),
                ),
 
+               'jquery.wikibase.propertyview.tests' => $moduleBase + array(
+                       'scripts' => array(
+                               'jquery.wikibase.propertyview.tests.js',
+                       ),
+                       'dependencies' => array(
+                               'jquery.wikibase.propertyview',
+                               'wikibase.datamodel.Property',
+                       ),
+               ),
+
                'jquery.wikibase.referenceview.tests' => $moduleBase + array(
                        'scripts' => array(
                                'jquery.wikibase.referenceview.tests.js',
diff --git a/repo/resources/Resources.php b/repo/resources/Resources.php
index 9c071f6..19d3ade 100644
--- a/repo/resources/Resources.php
+++ b/repo/resources/Resources.php
@@ -160,7 +160,8 @@
                        'dependencies' => array(
                                'mediawiki.user',
                                'mw.config.values.wbRepo',
-                               'jquery.wikibase.entityview',
+                               'jquery.wikibase.itemview',
+                               'jquery.wikibase.propertyview',
                                'jquery.wikibase.toolbarcontroller',
                                'jquery.wikibase.wbtooltip',
                                'jquery.cookie',
diff --git a/repo/resources/templates.php b/repo/resources/templates.php
index 0b159d3..7ef1fba 100644
--- a/repo/resources/templates.php
+++ b/repo/resources/templates.php
@@ -294,10 +294,10 @@
 <span class="wikibase-badgeselector wikibase-sitelinkview-badges"><!-- [0,*] 
wb-badge -->$1</span>
 HTML;
 
-       $templates['wb-property-datatype'] =
+       $templates['wikibase-propertyview-datatype'] =
 <<<HTML
-<div class="wb-datatype">
-       <div class="wb-datatype-value">$1</div>
+<div class="wikibase-propertyview-datatype">
+       <div class="wikibase-propertyview-datatype-value">$1</div>
 </div>
 HTML;
 
diff --git a/repo/resources/wikibase.ui.entityViewInit.js 
b/repo/resources/wikibase.ui.entityViewInit.js
index ce73efa..fbf55f0 100644
--- a/repo/resources/wikibase.ui.entityViewInit.js
+++ b/repo/resources/wikibase.ui.entityViewInit.js
@@ -108,6 +108,8 @@
        /**
         * @param {wikibase.datamodel.Entity} entity
         * @param {jQuery} $entityview
+        *
+        * @throws {Error} if no widget to render the entity exists.
         */
        function createEntityDom( entity, $entityview ) {
                var repoConfig = mw.config.get( 'wbRepo' );
@@ -121,8 +123,13 @@
                                entity
                        );
 
-               $entityview
-               .entityview( {
+               var view = entity.getType() + 'view';
+
+               if( !$.wikibase[view] ) {
+                       throw new Error( 'View for entity type ' + 
entity.getType() + ' does not exist' );
+               }
+
+               $entityview[entity.getType() + 'view']( {
                        value: entity,
                        entityChangersFactory: entityChangersFactory,
                        entityStore: entityStore,

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia417c45af10c881a5edd4d2ef82649492922be05
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Henning Snater <henning.sna...@wikimedia.de>

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

Reply via email to