273 lines
6.2 KiB
JavaScript
273 lines
6.2 KiB
JavaScript
/*!
|
|
* This file is part of the Semantic MediaWiki
|
|
*
|
|
* @section LICENSE
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
*
|
|
* @license GNU GPL v2+
|
|
* @since 3.0
|
|
*
|
|
* @author mwjames
|
|
*/
|
|
/* global jQuery, mediaWiki, semanticMediaWiki */
|
|
( function( $, mw, smw ) {
|
|
'use strict';
|
|
|
|
/**
|
|
* @since 3.0
|
|
* @class
|
|
*/
|
|
smw.suggester = smw.suggester || {};
|
|
|
|
/**
|
|
* Class constructor
|
|
*
|
|
* @since 3.0
|
|
*
|
|
* @class
|
|
* @constructor
|
|
*/
|
|
smw.suggester = function ( context ) {
|
|
|
|
var localizedName = mw.config.get( 'smw-config' ).namespaces.localizedName;
|
|
this.context = context;
|
|
|
|
this.category = localizedName[mw.config.get( 'wgNamespaceIds' ).category];
|
|
this.concept = localizedName[mw.config.get( 'wgNamespaceIds' ).concept];
|
|
|
|
this.currentRequest = null;
|
|
this.tempCache = [];
|
|
|
|
return this;
|
|
};
|
|
|
|
/* Public methods */
|
|
|
|
var fn = {
|
|
|
|
/**
|
|
* @since 3.0
|
|
* @method
|
|
*
|
|
* @return {Object}
|
|
*/
|
|
getDefaultTokenDefinitions: function() {
|
|
|
|
var that = this;
|
|
|
|
return {
|
|
property: {
|
|
token: '[[p:',
|
|
beforeInsert: function( token, value ) {
|
|
return value.replace( 'p:', '' ) + '::';
|
|
}
|
|
},
|
|
category: {
|
|
token: '[[c:',
|
|
beforeInsert: function( token, value ) {
|
|
return '[[' + that.category + ':' + value.replace( token, '' ) + ']]';
|
|
}
|
|
},
|
|
concept: {
|
|
token: '[[con:',
|
|
beforeInsert: function( token, value ) {
|
|
return '[[' + that.concept + ':' + value.replace( token, '' ) + ']]';
|
|
}
|
|
}
|
|
};
|
|
},
|
|
|
|
/**
|
|
* @since 3.0
|
|
* @method
|
|
*
|
|
* @param {Sting} key
|
|
* @param {Sting} cacheKey
|
|
* @param {Sting} term
|
|
* @param {Object} callback
|
|
*
|
|
* @return {Object}
|
|
*/
|
|
search: function( key, cacheKey, term, limit, callback ) {
|
|
|
|
var that = this;
|
|
|
|
var data = {
|
|
'action': 'smwbrowse',
|
|
'format': 'json',
|
|
'browse': key,
|
|
'params': JSON.stringify( {
|
|
"search": term,
|
|
"limit": limit
|
|
} )
|
|
};
|
|
|
|
// Abort any active request handle
|
|
if ( that.currentRequest !== null ) {
|
|
that.currentRequest.abort();
|
|
}
|
|
|
|
that.currentRequest = $.ajax( {
|
|
url: mw.util.wikiScript( 'api' ),
|
|
dataType: 'json',
|
|
data: data,
|
|
'success': function( response ) {
|
|
|
|
that.tempCache[cacheKey] = $.map( response.query, function( item, key ) {
|
|
return { id: item.label, name: item.label };
|
|
} );
|
|
|
|
that.currentRequest = null;
|
|
that.context.removeClass( 'is-disabled' );
|
|
|
|
return callback( that.tempCache[cacheKey] );
|
|
}
|
|
} );
|
|
|
|
return callback( [] );
|
|
},
|
|
|
|
/**
|
|
* @since 3.0
|
|
* @method
|
|
*
|
|
* @param {Array} list
|
|
*/
|
|
registerDefaultTokenList: function( list ) {
|
|
|
|
var that = this,
|
|
defaultTokenDefinitions = that.getDefaultTokenDefinitions();
|
|
|
|
list.forEach( function( key ) {
|
|
if ( defaultTokenDefinitions.hasOwnProperty( key ) ) {
|
|
that.registerTokenDefinition( key, defaultTokenDefinitions[key] );
|
|
}
|
|
} );
|
|
},
|
|
|
|
/**
|
|
* @since 3.0
|
|
* @method
|
|
*
|
|
* @param {String} key
|
|
* @param {Object} definition
|
|
*/
|
|
registerTokenDefinition: function( key, definition ) {
|
|
this.register( key, definition.token, definition.beforeInsert );
|
|
},
|
|
|
|
/**
|
|
* @since 3.0
|
|
* @method
|
|
*
|
|
* @param {Sting} key
|
|
* @param {Sting} token
|
|
* @param {Object} beforeInsert
|
|
*/
|
|
register: function( key, token, beforeInsert ) {
|
|
|
|
var that = this,
|
|
limit = 20;
|
|
|
|
// Default atwho options
|
|
var options = {
|
|
at: token,
|
|
spaceSelectsMatch: false,
|
|
startWithSpace: false,
|
|
lookUpOnClick: false,
|
|
acceptSpaceBar: true,
|
|
hideWithoutSuffix: false,
|
|
displayTimeout: 300,
|
|
suffix: '',
|
|
limit: limit,
|
|
callbacks: {}
|
|
};
|
|
|
|
options.callbacks.highlighter = function ( li, query ) {
|
|
var regexp;
|
|
|
|
if ( !query || query == '?' ) {
|
|
return li;
|
|
};
|
|
|
|
regexp = new RegExp(">\\s*([^\<]*?)(" + query.replace("+", "\\+") + ")([^\<]*)\\s*<", 'ig');
|
|
return li.replace(regexp, function(str, $1, $2, $3) {
|
|
return '> ' + $1 + '<strong>' + $2 + '</strong>' + $3 + ' <';
|
|
} );
|
|
};
|
|
|
|
// https://github.com/ichord/At.js/wiki/How-to-use-remoteFilter
|
|
options.callbacks.remoteFilter = function ( term, callback ) {
|
|
|
|
var cacheKey = token + term;
|
|
|
|
if ( term == null || term.length < 2 && term != '?' ) {
|
|
return callback( [] );
|
|
}
|
|
|
|
that.context.addClass( 'is-disabled' );
|
|
|
|
if( typeof that.tempCache[cacheKey] == "object" ) {
|
|
that.context.removeClass( 'is-disabled' );
|
|
return callback( that.tempCache[cacheKey] );
|
|
}
|
|
|
|
return that.search( key, cacheKey, term, limit, callback );
|
|
};
|
|
|
|
/**
|
|
* Sort data
|
|
*
|
|
* @param query [String] matched string
|
|
* @param items [Array] data that was refactored
|
|
* @param searchKey [String] at char to search
|
|
*
|
|
* @return [Array] sorted data
|
|
*/
|
|
options.callbacks.sorter = function ( query, items, searchKey ) {
|
|
// https://stackoverflow.com/questions/1129216/sort-array-of-objects-by-string-property-value-in-javascript
|
|
return items.sort( function( a, b ) {
|
|
return ( a.id > b.id ) ? 1 : ( ( b.id > a.id ) ? -1 : 0 );
|
|
} );
|
|
};
|
|
|
|
// https://github.com/ichord/At.js/wiki/Callbacks
|
|
options.callbacks.beforeInsert = function ( value, $li ) {
|
|
return beforeInsert( token, value );
|
|
};
|
|
|
|
// https://github.com/ichord/At.js
|
|
this.context.atwho( options );
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Factory
|
|
* @since 3.0
|
|
*/
|
|
var Factory = {
|
|
newEntitySuggester: function( $context ) {
|
|
return new smw.suggester( $context );
|
|
}
|
|
};
|
|
|
|
smw.suggester.prototype = fn;
|
|
|
|
smw.Factory = smw.Factory || {};
|
|
smw.Factory = $.extend( smw.Factory, Factory );
|
|
|
|
} )( jQuery, mediaWiki, semanticMediaWiki );
|