Adrian Lang has uploaded a new change for review.

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

Change subject: [WIP] Use API for formatting in JS
......................................................................

[WIP] Use API for formatting in JS

Doesn't work, since the API does not provide language fallback. Also, I think
it would make more sense to implement EntityIdFormatters based on the
formatterStore and parserStore instances passed into ViewFactory. That would
mean language fallback (once implemented) has to be used in the formatters
provided by WikibaseRepo. Thus, the ValueView can also make use of the
language fallbacks :)

We also want to have a caching decorator for the EntityIdFormatters, or for
the formatters and parsers. The latter might increase memory usage too much,
though.

Bug: T88426
Change-Id: I641d8c46009f59e2b11284cb949322ae4d186b60
---
A view/resources/wikibase/entityIdFormatter/ApiEntityIdPlainFormatter.js
M view/resources/wikibase/entityIdFormatter/resources.php
M view/resources/wikibase/view/ViewFactory.js
M view/resources/wikibase/view/resources.php
A view/tests/qunit/wikibase/entityIdFormatter/ApiEntityIdPlainFormatter.tests.js
M view/tests/qunit/wikibase/entityIdFormatter/resources.php
6 files changed, 247 insertions(+), 118 deletions(-)


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

diff --git 
a/view/resources/wikibase/entityIdFormatter/ApiEntityIdPlainFormatter.js 
b/view/resources/wikibase/entityIdFormatter/ApiEntityIdPlainFormatter.js
new file mode 100644
index 0000000..1ba9308
--- /dev/null
+++ b/view/resources/wikibase/entityIdFormatter/ApiEntityIdPlainFormatter.js
@@ -0,0 +1,37 @@
+( function( $, wb, util ) {
+       'use strict';
+
+       /**
+        * @param {wikibase.api.RepoApi} repoApi
+        */
+       wb.entityIdFormatter.ApiEntityIdPlainFormatter = util.inherit(
+               'ApiEntityIdPlainFormatter',
+               wb.entityIdFormatter.EntityIdPlainFormatter,
+               function( repoApi ) {
+                       if( !repoApi || !( repoApi instanceof wb.api.RepoApi ) 
) {
+                               throw new Error( 'Required RepoApi instance not 
passed' );
+                       }
+                       this._repoApi = repoApi;
+               },
+               {
+                       _repoApi: null,
+
+                       format: function( entityId ) {
+                               var deferred = $.Deferred(),
+                                       self = this;
+                               this._repoApi.parseValue( 'wikibase-entityid', 
[ entityId ] ).done( function( apiResponse ) {
+                                       return self._repoApi.formatValue( 
apiResponse.results[0], null, null, 'text/plain' ).done( function( response ) {
+                                               deferred.resolve( 
response.result );
+                                       } ).fail( function() {
+                                               deferred.resolve( entityId );
+                                       } );
+                               } ).fail( function() {
+                                       deferred.resolve( entityId );
+                               } );
+
+                               return deferred.promise();
+                       }
+
+               }
+       );
+}( jQuery, wikibase, util ) );
diff --git a/view/resources/wikibase/entityIdFormatter/resources.php 
b/view/resources/wikibase/entityIdFormatter/resources.php
index 95e1b7e..a2932ef 100644
--- a/view/resources/wikibase/entityIdFormatter/resources.php
+++ b/view/resources/wikibase/entityIdFormatter/resources.php
@@ -22,6 +22,17 @@
                                'wikibase.view.__namespace',
                        )
                ),
+               'wikibase.entityIdFormatter.ApiEntityIdPlainFormatter' => 
$moduleTemplate + array(
+                       'scripts' => array(
+                               'ApiEntityIdPlainFormatter.js'
+                       ),
+                       'dependencies' => array(
+                               'util.inherit',
+                               'wikibase.api.RepoApi',
+                               'wikibase.entityIdFormatter.__namespace',
+                               
'wikibase.entityIdFormatter.EntityIdPlainFormatter',
+                       )
+               ),
                'wikibase.entityIdFormatter.EntityIdHtmlFormatter' => 
$moduleTemplate + array(
                        'scripts' => array(
                                'EntityIdHtmlFormatter.js'
diff --git a/view/resources/wikibase/view/ViewFactory.js 
b/view/resources/wikibase/view/ViewFactory.js
index 8f4a055..4d42040 100644
--- a/view/resources/wikibase/view/ViewFactory.js
+++ b/view/resources/wikibase/view/ViewFactory.js
@@ -1,133 +1,133 @@
 ( function( $, wb ) {
-       'use strict';
+'use strict';
 
-       var MODULE = wb.view;
+var MODULE = wb.view;
 
-       /**
-        * A factory for creating view widgets
-        *
-        * @class wikibase.view.ViewFactory
-        * @licence GNU GPL v2+
-        * @since 0.5
-        * @author Adrian Heine < adrian.he...@wikimedia.de >
-        * @constructor
-        *
-        * @param {util.ContentLanguages} contentLanguages
-        *        Required by the `ValueView` for limiting the list of 
available languages for
-        *        particular `jQuery.valueview.Expert` instances like the 
`Expert` responsible
-        *        for `MonoLingualTextValue`s.
-        * @param {dataTypes.DataTypeStore} dataTypeStore
-        *        Required by the `snakview` for retrieving and evaluating a 
proper `dataTypes.DataType`
-        *        object when interacting on a "value" `Variation`.
-        * @param {wikibase.entityChangers.EntityChangersFactory} 
entityChangersFactory
-        *        Required to store changed data.
-        * @param {wikibase.store.EntityStore} entityStore
-        *        Required for dynamically gathering `Entity`/`Property` 
information.
-        * @param {jQuery.valueview.ExpertStore} expertStore
-        *        Required by the `ValueView` for constructing `expert`s for 
different value types.
-        * @param {valueFormatters.ValueFormatterStore} formatterStore
-        *        Required by the `ValueView` for formatting entered values.
-        * @param {util.MessageProvider} messageProvider
-        *        Required by the `ValueView` for showing the user interface in 
the correct language.
-        * @param {valueParsers.ValueParserStore} parserStore
-        *        Required by the `ValueView` for parsing entered values.
-        * @param {string[]} userLanguages An array of language codes, the 
first being the UI language
-        *        Required for showing the user interface in the correct 
language and for showing terms
-        *        in all languages requested by the user.
-        */
-       var SELF = MODULE.ViewFactory = function ViewFactory(
-               contentLanguages,
-               dataTypeStore,
-               entityChangersFactory,
-               entityStore,
-               expertStore,
-               formatterStore,
-               messageProvider,
-               parserStore,
-               userLanguages
-       ) {
-               this._contentLanguages = contentLanguages;
-               this._dataTypeStore = dataTypeStore;
-               this._entityChangersFactory = entityChangersFactory;
-               this._entityStore = entityStore;
-               this._expertStore = expertStore;
-               this._formatterStore = formatterStore;
-               this._messageProvider = messageProvider;
-               this._parserStore = parserStore;
-               // Maybe make userLanguages an argument to getEntityView 
instead of to the constructor
-               this._userLanguages = userLanguages;
-       };
+/**
+ * A factory for creating view widgets
+ *
+ * @class wikibase.view.ViewFactory
+ * @licence GNU GPL v2+
+ * @since 0.5
+ * @author Adrian Heine < adrian.he...@wikimedia.de >
+ * @constructor
+ *
+ * @param {util.ContentLanguages} contentLanguages
+ *        Required by the `ValueView` for limiting the list of available 
languages for
+ *        particular `jQuery.valueview.Expert` instances like the `Expert` 
responsible
+ *        for `MonoLingualTextValue`s.
+ * @param {dataTypes.DataTypeStore} dataTypeStore
+ *        Required by the `snakview` for retrieving and evaluating a proper 
`dataTypes.DataType`
+ *        object when interacting on a "value" `Variation`.
+ * @param {wikibase.entityChangers.EntityChangersFactory} entityChangersFactory
+ *        Required to store changed data.
+ * @param {wikibase.store.EntityStore} entityStore
+ *        Required for dynamically gathering `Entity`/`Property` information.
+ * @param {jQuery.valueview.ExpertStore} expertStore
+ *        Required by the `ValueView` for constructing `expert`s for different 
value types.
+ * @param {valueFormatters.ValueFormatterStore} formatterStore
+ *        Required by the `ValueView` for formatting entered values.
+ * @param {util.MessageProvider} messageProvider
+ *        Required by the `ValueView` for showing the user interface in the 
correct language.
+ * @param {valueParsers.ValueParserStore} parserStore
+ *        Required by the `ValueView` for parsing entered values.
+ * @param {string[]} userLanguages An array of language codes, the first being 
the UI language
+ *        Required for showing the user interface in the correct language and 
for showing terms
+ *        in all languages requested by the user.
+ */
+var SELF = MODULE.ViewFactory = function ViewFactory(
+       contentLanguages,
+       dataTypeStore,
+       entityChangersFactory,
+       entityStore,
+       expertStore,
+       formatterStore,
+       messageProvider,
+       parserStore,
+       userLanguages
+) {
+       this._contentLanguages = contentLanguages;
+       this._dataTypeStore = dataTypeStore;
+       this._entityChangersFactory = entityChangersFactory;
+       this._entityStore = entityStore;
+       this._expertStore = expertStore;
+       this._formatterStore = formatterStore;
+       this._messageProvider = messageProvider;
+       this._parserStore = parserStore;
+       // Maybe make userLanguages an argument to getEntityView instead of to 
the constructor
+       this._userLanguages = userLanguages;
+};
 
-       /**
-        * @property {util.ContentLanguages}
-        * @private
-        **/
-       SELF.prototype._contentLanguages = null;
+/**
+ * @property {util.ContentLanguages}
+ * @private
+ **/
+SELF.prototype._contentLanguages = null;
 
-       /**
-        * @property {dataTypes.DataTypeStore}
-        * @private
-        **/
-       SELF.prototype._dataTypeStore = null;
+/**
+ * @property {dataTypes.DataTypeStore}
+ * @private
+ **/
+SELF.prototype._dataTypeStore = null;
 
-       /**
-        * @property {wikibase.entityChangers.EntityChangersFactory}
-        * @private
-        **/
-       SELF.prototype._entityChangersFactory = null;
+/**
+ * @property {wikibase.entityChangers.EntityChangersFactory}
+ * @private
+ **/
+SELF.prototype._entityChangersFactory = null;
 
-       /**
-        * @property {wikibase.store.EntityStore}
-        * @private
-        **/
-       SELF.prototype._entityStore = null;
+/**
+ * @property {wikibase.store.EntityStore}
+ * @private
+ **/
+SELF.prototype._entityStore = null;
 
-       /**
-        * @property {jQuery.valueview.ExpertStore}
-        * @private
-        **/
-       SELF.prototype._expertStore = null;
+/**
+ * @property {jQuery.valueview.ExpertStore}
+ * @private
+ **/
+SELF.prototype._expertStore = null;
 
-       /**
-        * @property {valueFormatters.ValueFormatterStore}
-        * @private
-        **/
-       SELF.prototype._formatterStore = null;
+/**
+ * @property {valueFormatters.ValueFormatterStore}
+ * @private
+ **/
+SELF.prototype._formatterStore = null;
 
-       /**
-        * @property {util.MessageProvider}
-        * @private
-        **/
-       SELF.prototype._messageProvider = null;
+/**
+ * @property {util.MessageProvider}
+ * @private
+ **/
+SELF.prototype._messageProvider = null;
 
-       /**
-        * @property {valueParsers.ValueParserStore}
-        * @private
-        **/
-       SELF.prototype._parserStore = null;
+/**
+ * @property {valueParsers.ValueParserStore}
+ * @private
+ **/
+SELF.prototype._parserStore = null;
 
-       /**
-        * @property {string[]}
-        * @private
-        **/
-       SELF.prototype._userLanguages = null;
+/**
+ * @property {string[]}
+ * @private
+ **/
+SELF.prototype._userLanguages = null;
 
-       /**
-        * Construct a suitable view for the given entity on the given DOM 
element
-        *
-        * @param {wikibase.datamodel.Entity} entity
-        * @param {jQuery} $dom
-        * @return {jQuery.wikibase.entityview} The constructed entity view
-        * @throws {Error} If there is no view for the given entity type
-        **/
-       SELF.prototype.getEntityView = function( entity, $dom ) {
-               return this._getView(
-                       entity.getType() + 'view',
-                       $dom,
-                       {
-                               dataTypeStore: this._dataTypeStore,
-                               entityChangersFactory: 
this._entityChangersFactory,
-                               entityIdPlainFormatter: new 
wb.entityIdFormatter.SimpleEntityIdPlainFormatter( this._entityStore ),
+/**
+ * Construct a suitable view for the given entity on the given DOM element
+ *
+ * @param {wikibase.datamodel.Entity} entity
+ * @param {jQuery} $dom
+ * @return {jQuery.wikibase.entityview} The constructed entity view
+ * @throws {Error} If there is no view for the given entity type
+ **/
+SELF.prototype.getEntityView = function( entity, $dom ) {
+       return this._getView(
+               entity.getType() + 'view',
+               $dom,
+               {
+                       dataTypeStore: this._dataTypeStore,
+                       entityChangersFactory: this._entityChangersFactory,
+                               entityIdPlainFormatter: new 
wb.entityIdFormatter.ApiEntityIdPlainFormatter( new wb.api.RepoApi( new 
mw.Api() ) ),
                                entityStore: this._entityStore,
                                languages: this._userLanguages,
                                value: entity,
diff --git a/view/resources/wikibase/view/resources.php 
b/view/resources/wikibase/view/resources.php
index 899cfd9..2833887 100644
--- a/view/resources/wikibase/view/resources.php
+++ b/view/resources/wikibase/view/resources.php
@@ -26,7 +26,7 @@
                        'dependencies' => array(
                                'jquery.wikibase.itemview',
                                'jquery.wikibase.propertyview',
-                               
'wikibase.entityIdFormatter.SimpleEntityIdPlainFormatter',
+                               
'wikibase.entityIdFormatter.ApiEntityIdPlainFormatter',
                                'wikibase.view.__namespace',
                                'wikibase.ValueViewBuilder'
                        )
diff --git 
a/view/tests/qunit/wikibase/entityIdFormatter/ApiEntityIdPlainFormatter.tests.js
 
b/view/tests/qunit/wikibase/entityIdFormatter/ApiEntityIdPlainFormatter.tests.js
new file mode 100644
index 0000000..bc751df
--- /dev/null
+++ 
b/view/tests/qunit/wikibase/entityIdFormatter/ApiEntityIdPlainFormatter.tests.js
@@ -0,0 +1,71 @@
+( function( $, sinon, QUnit, wb, mw ) {
+       'use strict';
+
+       QUnit.module( 'wikibase.entityIdFormatter.ApiEntityIdPlainFormatter' );
+
+       var api = new wb.api.RepoApi( {} );
+       api.parseValue = function( dataType, values ) {
+               var deferred = $.Deferred();
+               if( values[0] === 'Q2' ) {
+                       deferred.reject();
+               } else {
+                       deferred.resolve(
+                               { results: [ { value: { 'entity-type': 'item', 
'numeric-id': Number( values[0].substr( 1 ) ) } } ] }
+                       );
+               }
+               return deferred.promise();
+       };
+       api.formatValue = function( value ) {
+               var deferred = $.Deferred();
+               if( value.value[ 'numeric-id' ] === 3 ) {
+                       deferred.reject();
+               } else {
+                       deferred.resolve( { result: 'Label' } );
+               }
+               return deferred.promise();
+       };
+
+       function newFormatter() {
+               return new wb.entityIdFormatter.ApiEntityIdPlainFormatter( api 
);
+       }
+
+       QUnit.test( 'constructor throws error if no RepoApi is passed', 
function( assert ) {
+               assert.throws( function() {
+                       return new 
wb.entityIdFormatter.ApiEntityIdPlainFormatter();
+               } );
+       } );
+
+       QUnit.test( 'constructor throws error if RepoApi is not instance of 
RepoApi', function( assert ) {
+               assert.throws( function() {
+                       return new 
wb.entityIdFormatter.ApiEntityIdPlainFormatter( {} );
+               } );
+       } );
+
+       QUnit.test( 'format uses parser and formatter', function( assert ) {
+               var formatter = newFormatter();
+               var done = assert.async();
+               formatter.format( 'Q1' ).done( function( res ) {
+                       assert.equal( res, 'Label' );
+                       done();
+               } );
+       } );
+
+       QUnit.test( 'format falls back to the entity id when parsing fails', 
function( assert ) {
+               var formatter = newFormatter();
+               var done = assert.async();
+               formatter.format( 'Q2' ).done( function( res ) {
+                       assert.equal( res, 'Q2' );
+                       done();
+               } );
+       } );
+
+       QUnit.test( 'format falls back to the entity id when formatting fails', 
function( assert ) {
+               var formatter = newFormatter();
+               var done = assert.async();
+               formatter.format( 'Q3' ).done( function( res ) {
+                       assert.equal( res, 'Q3' );
+                       done();
+               } );
+       } );
+
+}( jQuery, sinon, QUnit, wikibase, mediaWiki ) );
diff --git a/view/tests/qunit/wikibase/entityIdFormatter/resources.php 
b/view/tests/qunit/wikibase/entityIdFormatter/resources.php
index 6065a08..5dba3ce 100644
--- a/view/tests/qunit/wikibase/entityIdFormatter/resources.php
+++ b/view/tests/qunit/wikibase/entityIdFormatter/resources.php
@@ -50,6 +50,16 @@
                        ),
                ),
 
+               'wikibase.entityIdFormatter.ApiEntityIdPlainFormatter.tests' => 
$moduleTemplate + array(
+                       'scripts' => array(
+                               'ApiEntityIdPlainFormatter.tests.js',
+                       ),
+                       'dependencies' => array(
+                               'wikibase.api.RepoApi',
+                               
'wikibase.entityIdFormatter.ApiEntityIdPlainFormatter',
+                       ),
+               ),
+
        );
 
        return $modules;

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I641d8c46009f59e2b11284cb949322ae4d186b60
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Adrian Lang <adrian.he...@wikimedia.de>

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

Reply via email to