/** * Responsible for executing a deferred request to the MediaWiki back-end to * retrieve the representation for a #ask query. */ /*global jQuery, mediaWiki, smw */ /*jslint white: true */ ( function( $, mw, onoi ) { 'use strict'; /** * @since 3.0 * @constructor * * @param container {Object} * @param api {Object} */ var Query = function ( container, api ) { this.VERSION = "3.0"; this.container = container; this.mwApi = api; this.title = mw.config.get( 'wgPageName' ); this.data = container.data( 'query' ); this.query = this.data.query; this.cmd = this.data.cmd; this.control = container.find( '#deferred-control' ).data( 'control' ); this.limit = this.data.limit; this.offset = this.data.offset; this.rangeLimit = this.limit; this.rangeOffset = this.offset; this.init = true; this.max = this.data.max; this.step = 5; this.postfix = ''; // Ensure to have a limit, offset parameter for queries that use // the default setting if ( this.query.indexOf( "|limit=" ) == -1 ) { this.query = this.query + '|limit=' + this.limit; } if ( this.query.indexOf( "|offset=" ) == -1 ) { this.query = this.query + '|offset=' + this.offset; } if ( this.query.indexOf( "|default=" ) == -1 ) { this.query = this.query + '|default=' + mw.msg( 'smw_result_noresults' ); } }; /** * Request and parse a #ask/#show query using the MediaWiki API back-end * * @since 3.0 */ Query.prototype.doApiRequest = function() { var self = this, noTrace = ''; // Replace limit, offset with altered values var query = self.query.replace( 'limit=' + self.limit, 'limit=' + self.rangeLimit ).replace( 'offset=' + self.offset, 'offset=' + self.rangeOffset ); // In case the query was altered from its original request, signal // to the QueryDependencyLinksStore to disable any tracking if ( self.query !== query ) { noTrace = '|@notrace'; }; // API notes "modules: Gives the ResourceLoader modules used on the page. // Either jsconfigvars or encodedjsconfigvars must be requested jointly // with modules. 1.24+" self.mwApi.post( { action: "parse", title: self.title, contentmodel: 'wikitext', prop: 'text|modules|jsconfigvars', text: '{{#' + self.cmd + ':' + query + noTrace + '}}' } ).done( function( data ) { if ( self.init === true ) { self.initControls(); self.replaceOutput( '' ); }; // Remove any comments retrieved from the API parse var text = data.parse.text['*'].replace(//gm, '' ); // Remove any remaining placeholder loading classes if ( self.control !== '' ) { text = text.replace( 'smw-loading-image-dots', '' ); } // Remove any
element to avoid line breakages if ( self.cmd === 'show' ) { text = text.replace( /(?:^
]*>)|(?:<\/p>$)/img, '' ); } self.replaceOutput( text, '', data.parse.modules ); } ).fail ( function( code, failure ) { var error = code + ': ' + failure.textStatus; if ( failure.hasOwnProperty( 'exception' ) && failure.hasOwnProperty( 'xhr' ) ) { error = failure.xhr.responseText; } else if ( failure.hasOwnProperty( 'error' ) && failure.error.hasOwnProperty( 'info' ) ) { error = failure.error.info; } self.container.find( '#deferred-control' ).replaceWith( "
" ); self.container.find( '.irs' ).hide(); self.replaceOutput( error, "error" ); } ); }; /** * Replace output with generated content * * @since 3.0 * * @param text {String} * @param oClass {String} * @param modules {Array} * * @return {this} */ Query.prototype.replaceOutput = function( text, oClass, modules ) { var self = this, element = this.cmd === 'ask' ? 'div' : 'span'; oClass = oClass !== undefined ? "class='" + oClass + "'" : ''; self.container.find( '#deferred-output' ).replaceWith( "<" + element + " id='deferred-output'" + oClass + ">" + text + "" + element + ">" ); self.reload( modules ); }; /** * Reload module objects that rely on JavaScript to be executed after a * fresh parse. * * @since 3.0 * * @param modules {Array} */ Query.prototype.reload = function( modules ) { var self = this; // Trigger an event to re-apply JS instances initialization on new // content if ( modules !== undefined ) { mw.loader.using( modules ).done( function () { mw.hook( 'smw.deferred.query' ).fire( self.container ); } ); } else { mw.hook( 'smw.deferred.query' ).fire( self.container ); } var table = self.container.find( '#deferred-output table' ); // MW's table sorter isn't listed as page module therefore make an exception // and reload it manually if ( table.length > 0 && table.hasClass( 'sortable' ) ) { mw.loader.using( 'jquery.tablesorter' ).done( function () { table.tablesorter(); mw.hook( 'smw.deferred.query.tablesorter' ).fire( table ); } ); } }; /** * Executes and manages the initialization of control elements * * @since 3.0 */ Query.prototype.initControls = function() { var self = this; var loading = '