Lucas Werkmeister (WMDE) has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/358937 )

Change subject: Add QueryTemplate.parse and .getHtml functions
......................................................................

Add QueryTemplate.parse and .getHtml functions

parse() takes a query and attempts to extract the template. getHtml()
renders the template.

Tests are added to check that getHtml() returns a correctly rendered
template, including a test for using the same variable multiple times in
a template (which was not previously supported).

This was originally part of Ic362ea1087.

Bug: T167868
Change-Id: I91f31272870a574721667e301f103eb5e78de01f
---
M wikibase/queryService/ui/visualEditor/QueryTemplate.js
M wikibase/tests/queryService/ui/visualEditor/QueryTemplate.test.js
2 files changed, 128 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/wikidata/query/gui 
refs/changes/37/358937/1

diff --git a/wikibase/queryService/ui/visualEditor/QueryTemplate.js 
b/wikibase/queryService/ui/visualEditor/QueryTemplate.js
index 4469e55..1ef19dd 100644
--- a/wikibase/queryService/ui/visualEditor/QueryTemplate.js
+++ b/wikibase/queryService/ui/visualEditor/QueryTemplate.js
@@ -19,6 +19,49 @@
        }
 
        /**
+        * @property {Object} The parsed template definition.
+        * @private
+        */
+       SELF.prototype._definition = {};
+
+       /**
+        * @property {jQuery} A span with the rendered template.
+        * @private
+        */
+       SELF.prototype._template = null;
+
+       /**
+        * @property {Object.<string, Array.<jQuery>>} A map from variable 
names to lists of spans corresponding to that variable.
+        * @private
+        */
+       SELF.prototype._variables = [];
+
+       /**
+        * @param {SparqlQuery} query
+        * @return {?QueryTemplate}
+        */
+       SELF.parse = function( query ) {
+               var templateComment = query.getCommentContent( 'TEMPLATE=' ),
+                       templateJson,
+                       template;
+
+               if ( !templateComment ) {
+                       return null;
+               }
+               try {
+                       templateJson = JSON.parse( templateComment );
+               } catch ( e ) {
+                       return null;
+               }
+
+               template = new SELF;
+               template._definition = templateJson;
+               template._fragments = SELF._getQueryTemplateFragments( 
templateJson );
+
+               return template;
+       };
+
+       /**
         * Splits the template 'a ?b c ?d e' into
         * [ 'a ', '?b', ' c ', '?d', ' e' ].
         * Text and variable fragments always alternate,
@@ -86,5 +129,51 @@
                return template;
        };
 
+       /**
+        * @param {Function} getLabel Called with {string} variable name, 
should return {Promise} for label, id, description, type.
+        * @param {wikibase.queryService.ui.visualEditor.SelectorBox} 
selectorBox
+        * @param {Function} changeListener Called with {string} variable name, 
{string} old value, {string} new value.
+        * @return {jQuery}
+        */
+       SELF.prototype.getHtml = function( getLabel, selectorBox, 
changeListener ) {
+               if ( this._template !== null ) {
+                       return this._template;
+               }
+
+               this._template = SELF._buildTemplate( this._fragments, 
this._variables );
+
+               var self = this;
+
+               $.each( this._definition.variables, function( variable, 
variableDefinition ) {
+                       getLabel( variable ).done( function( label, id, 
description, type ) {
+                               $.each( self._variables[ variable ], function( 
index, $variable ) {
+                                       $variable.text( '' );
+                                       var $link = $( '<a>' ).text( label 
).attr( {
+                                               'data-id': id,
+                                               'data-type': type,
+                                               href: '#'
+                                       } ).appendTo( $variable );
+
+                                       if ( variableDefinition.query ) {
+                                               $link.attr( 'data-sparql', 
variableDefinition.query );
+                                       }
+
+                                       selectorBox.add( $link, null, function( 
selectedId, name ) {
+                                               for ( var j in self._variables[ 
variable ] ) {
+                                                       var $variable = 
self._variables[ variable ][ j ];
+                                                       $variable.find( 
'a[data-id="' + id + '"]' )
+                                                               .attr( 
'data-id', selectedId )
+                                                               .text( name );
+                                                       changeListener( 
variable, id, selectedId );
+                                                       id = selectedId;
+                                               }
+                                       } );
+                               } );
+                       } );
+               } );
+
+               return this._template;
+       };
+
        return SELF;
 }( jQuery, wikibase ) );
diff --git a/wikibase/tests/queryService/ui/visualEditor/QueryTemplate.test.js 
b/wikibase/tests/queryService/ui/visualEditor/QueryTemplate.test.js
index d300bef..b4a353d 100644
--- a/wikibase/tests/queryService/ui/visualEditor/QueryTemplate.test.js
+++ b/wikibase/tests/queryService/ui/visualEditor/QueryTemplate.test.js
@@ -60,4 +60,43 @@
                assert.ok( '?d' in variables, 'variables should contain the 
variables from the template' );
                assert.equal( Object.getOwnPropertyNames( variables ).length, 
2, 'variables should not contain any other properties' );
        } );
+
+       var testCases = [
+               {
+                       description: 'query template with single variable',
+                       sparql: '#TEMPLATE={ "template": "Find ?thing\u200Bs", 
"variables": { "?thing": {} } }\nSELECT ?human WHERE { BIND(wd:Q5 AS ?thing) 
?human wdt:P31 ?thing }',
+                       text: 'Find human\u200Bs'
+               },
+               {
+                       description: 'query template with two variables',
+                       sparql: '#TEMPLATE={ "template": "Find ?thing\u200Bs 
with ?prop", "variables": { "?thing": {}, "?prop": {} } }\nSELECT ?human ?other 
WHERE { BIND(wd:Q5 AS ?thing) BIND(wdt:P21 AS ?prop) ?human wdt:P31 ?thing; 
?prop ?other }',
+                       text: 'Find human\u200Bs with sex or gender'
+               },
+               {
+                       description: 'query template with the same variable 
twice',
+                       sparql: '#TEMPLATE={ "template": "Find ?thing\u200Bs 
that are ?thing\u200Bs", "variables": { "?thing": {} } }\nSELECT ?human WHERE { 
BIND(wd:Q5 AS ?thing) ?human wdt:P31 ?thing }',
+                       text: 'Find human\u200Bs that are human\u200Bs'
+               }
+       ];
+       var labels = {
+               '?thing': 'human',
+               '?prop': 'sex or gender'
+       };
+
+       $.each( testCases, function( index, testCase ) {
+               QUnit.test( testCase.description, function( assert ) {
+                       assert.expect( 1 );
+
+                       var query = new 
wb.queryService.ui.visualEditor.SparqlQuery();
+                       query.parse( testCase.sparql, 
wb.queryService.RdfNamespaces.ALL_PREFIXES );
+                       var qt = QueryTemplate.parse( query );
+                       var $html = qt.getHtml(
+                               function( variable ) { return 
$.Deferred().resolve( labels[variable] ).promise(); },
+                               { add: function() {} },
+                               function() {}
+                       );
+
+                       assert.equal( $html.text(), testCase.text );
+               } );
+       } );
 }( jQuery, QUnit, sinon, wikibase ) );

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I91f31272870a574721667e301f103eb5e78de01f
Gerrit-PatchSet: 1
Gerrit-Project: wikidata/query/gui
Gerrit-Branch: master
Gerrit-Owner: Lucas Werkmeister (WMDE) <[email protected]>

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

Reply via email to