Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F23900449
WIP wikidata gadget
No One
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Authored By
Mvolz
Jul 19 2018, 1:07 PM
2018-07-19 13:07:59 (UTC+0)
Size
12 KB
Referenced Files
None
Subscribers
None
WIP wikidata gadget
View Options
var citoidQidTypeMap = {
"artwork": "Q838948",
"audioRecording": "Q5057302",
"bill": "Q686822",
"blogPost": "Q17928402",
"book": "Q571",
"bookSection": "Q1980247",
"case": "Q2334719",
"computerProgram": "Q5057302",
"conferencePaper": "Q23927052",
"dictionaryEntry": "Q4423781",
"document": "Q49848",
"email": "Q9158",
"encyclopediaArticle": "Q17329259",
"film": "Q11424",
"forumPost": "Q7216866",
"hearing": "Q545861",
"instantMessage": "Q30070565",
"interview": "Q178651",
"journalArticle": "Q191067",
"letter": "Q133492",
"magazineArticle": "Q191067",
"manuscript": "Q87167",
"map": "Q4006",
"newspaperArticle": "Q191067",
"patent": "Q253623",
"podcast": "Q5057302",
"presentation": "Q604733",
"radioBroadcast": "Q1555508",
"report": "Q10870555",
"statute": "Q820655",
"thesis": "Q1266946",
"tvBroadcast": "Q21191270",
"videoRecording": "Q30070675",
"webpage": "Q36774"
};
var typeProperty = "P31"; // Property to use for "instance of" or "type"; corresponds to field 'itemType' in citoid
( function ( $, mw ) {
'use strict';
function ReferenceItem( data ) {
this.data = data; // Raw data from citoid
this.display = {}; // Elements for displaying the item
}
function CitoidDialog( config ) {
CitoidDialog.super.call( this, config );
}
OO.inheritClass( CitoidDialog, OO.ui.Dialog );
CitoidDialog.static.name = 'citoidDialog';
CitoidDialog.static.title = 'Create new reference item';
CitoidDialog.static.citoidFormat = 'mediawiki-basefields';
CitoidDialog.prototype.initialize = function () {
CitoidDialog.super.prototype.initialize.call( this );
this.items = []; // List of ReferenceItem objects
this.content = new OO.ui.PanelLayout( { padded: true, expanded: false } );
this.content.$element.append( '<p>Press \'Esc\' to close. </p>' );
this.$body.append( this.content.$element );
this.lookupInput = new OO.ui.TextInputWidget( {
placeholder: 'URL, DOI, PMC or Title'
} );
this.lookupButton = new OO.ui.ButtonWidget( {
label: 'Search'
} );
this.lookupActionFieldLayout = new OO.ui.ActionFieldLayout( this.lookupInput, this.lookupButton, {
align: 'top',
label: 'Search'
} );
// Error label
this.$noticeLabel = $( '<div>' ).addClass( 'oo-ui-element-hidden' ).text( 'Unable to retrieve data from input; try changing your search?' );
this.content.$element.append( this.lookupActionFieldLayout.$element, this.$noticeLabel );
// Restbase URL
this.fullRestbaseUrl = 'https://en.wikipedia.org/api/';
// API config for citoid service if using citoid behind Restbase
this.serviceUrl = this.fullRestbaseUrl + 'rest_v1/data/citation/' + CitoidDialog.static.citoidFormat;
this.serviceConfig = {
ajax: {
// Request content in user language from citoid service. Possible we should do English as well to get both in case they are different.
headers: { 'accept-language': mw.config.get( 'wgUserLanguage' ) },
crossDomain: true,
timeout: 30 * 1000, // 30 seconds
type: 'GET'
}
};
this.lookupButton.connect( this, { click: 'onLookupButtonClick' } );
};
// Override the getBodyHeight() method to specify a custom height (or don't to use the automatically generated height)
CitoidDialog.prototype.getBodyHeight = function () {
return this.content.$element.outerHeight( true );
};
CitoidDialog.prototype.getSetupProcess = function ( data ) {
data = data || {};
return CitoidDialog.super.prototype.getSetupProcess.call( this, data )
.next( function () {
// Set up contents based on data
this.lookupInput.setValue( data.search );
}, this );
};
CitoidDialog.prototype.displayNewItem = function ( data ) {
this.item = new ReferenceItem( data[0] ); // Hardcode to only use first citation for the time being
this.items.push( this.item ); // Add to list of items in dialog
/* Display Elements */
// Item label
this.item.display.label = new OO.ui.TextInputWidget( {
value: this.item.data.title,
label: 'label'
} );
// Item description
this.item.display.description = new OO.ui.TextInputWidget( {
value: this.item.data.itemType,
label: 'description'
} );
// Button
this.item.display.createButton = new OO.ui.ButtonWidget( {
label: 'Create new item'
} );
// Item creation failure message
this.item.display.$failureLabel = $( '<div>' )
.addClass( 'oo-ui-element-hidden' )
.text( 'Unable to create new item; item with same label and description already exists. Try changing the description?' );
/* Actions */
this.item.display.createButton.connect( this, { click: 'onCreateButtonClick' } );
/* Layout */
this.item.display.itemLayout = new OO.ui.FieldsetLayout( {
label: 'New Item',
classes: ["container"]
} );
this.item.display.itemLayout.addItems( [
new OO.ui.FieldLayout( this.item.display.label, {
label: this.item.display.label.label,
align: 'left'
} ),
new OO.ui.FieldLayout( this.item.display.description, {
label: this.item.display.description.label,
align: 'left'
} )
]);
this.content.$element.append( this.item.display.itemLayout.$element,
this.item.display.createButton.$element,
this.item.display.$failureLabel
);
this.updateSize();
};
/**
* Handle click events from the lookup button, perform lookup
*/
CitoidDialog.prototype.onLookupButtonClick = function () {
this.executeAction( 'lookup' );
};
/**
* Handle click events from the lookup button, perform lookup
*/
CitoidDialog.prototype.onCreateButtonClick = function () {
this.executeAction( 'create' );
};
CitoidDialog.prototype.getActionProcess = function ( action ) {
var dialog = this;
if ( action === 'lookup' ) {
return new OO.ui.Process( function () {
return this.performLookup().then( function ( data ) {
dialog.displayNewItem( data );
},
// Failure
function () {
dialog.lookupFailed();
});
}, this );
}
if ( action === 'create' ) {
return new OO.ui.Process( function () {
dialog.createNewItem();
}, this );
}
// Fallback to parent handler
return CitoidDialog.super.prototype.getActionProcess.call( this, action );
};
CitoidDialog.prototype.createNewItem = function ( ) {
var dialog = this;
var data = {
labels:[ {
language:"en",
value: this.item.display.label.value
} ],
descriptions:[ {
language:"en",
value: this.item.display.description.value
} ]
};
var api = new mw.Api();
// Set as pending
this.item.display.createButton.setDisabled( true );
this.item.display.label.setDisabled( true ).pushPending();
this.item.display.description.setDisabled( true ).pushPending();
api.postWithEditToken( {
assert: 'user',
action: 'wbeditentity',
new: 'item',
data: JSON.stringify(data),
format: 'json'
} ).then( function ( results ) {
if ( results.success && results.success === 1 ) {
dialog.insertItem( results );
} else {
dialog.creationFailed();
}
// Failure
}, function ( ) {
dialog.creationFailed();
}
);
}
CitoidDialog.prototype.insertItem = function ( results ) {
this.close( results.entity.id );
// Remove pre-creation display
//this.item.display.itemLayout.$element.remove();
//this.item.display.createButton.$element.remove();
// Update display
//this.content.$element.append( '<p>Created new item ' + results.entity.id + '</p>' );
//this.updateSize();
// TODO insert item into field
};
/**
* Send a request to the citoid service
*
* @return {jQuery.Promise} Lookup promise
*/
CitoidDialog.prototype.performLookup = function () {
var xhr,
search,
dialog = this;
// Clear prior results
this.clearResults();
// TODO: Add caching for requested urls
if ( this.lookupPromise ) {
// Abort existing lookup
this.lookupPromise.abort();
this.lookupPromise = null;
this.lookupInput.popPending();
}
// Set as pending
this.lookupButton.setDisabled( true );
this.lookupInput.setDisabled( true ).pushPending();
search = this.lookupInput.getValue();
search = decodeURIComponent( search );
// We have to first set up a get response so we can have
// a proper xhr object with "abort" method, so we can
// hand off this abort method to the jquery promise
if ( this.fullRestbaseUrl ) {
// Use restbase endpoint
this.serviceConfig.ajax.url = this.serviceUrl + '/' + encodeURIComponent( search );
xhr = new mw.Api( this.serviceConfig ).get();
} else {
// Use standalone citoid service
xhr = this.service
.get( {
search: search,
format: ve.ui.CiteFromIdInspector.static.citoidFormat
} );
}
this.lookupPromise = xhr
.always( function () {
dialog
.lookupInput
.setDisabled( false )
// restore focus to the input field
.focus()
.popPending();
dialog.lookupButton.setDisabled( false );
} )
.promise( { abort: xhr.abort } );
return this.lookupPromise;
};
CitoidDialog.prototype.lookupFailed = function () {
// Enable the input and lookup button
this.$noticeLabel.removeClass( 'oo-ui-element-hidden' );
this.lookupInput.once( 'change', function () {
this.$noticeLabel.addClass( 'oo-ui-element-hidden' );
this.updateSize();
}.bind( this ) ).setValidityFlag( false );
this.updateSize();
};
CitoidDialog.prototype.creationFailed = function () {
// Enable the input and lookup button
this.item.display.$failureLabel.removeClass( 'oo-ui-element-hidden' );
this.item.display.label.setDisabled( false ).popPending();
this.item.display.description.setDisabled( false ).popPending();
this.item.display.createButton.setDisabled( false );
this.updateSize();
};
/**
* Clear the search results
*/
CitoidDialog.prototype.clearResults = function () {
var i;
for (i = 0; i < this.items.length; i++) {
this.item.display.itemLayout.$element.remove();
this.item.display.createButton.$element.remove();
this.item.display.$failureLabel.remove();
}
this.items = [];
this.updateSize();
};
// Make the window.
var citoidDialog = new CitoidDialog( {
size: 'medium'
} );
// Create and append a window manager, which will open and close the window.
var windowManager = new OO.ui.WindowManager();
$( 'body' ).append( windowManager.$element );
// Add the window to the window manager using the addWindows() method.
windowManager.addWindows( [ citoidDialog ] );
function init() {
var currentField = $( 'input' );
var willEntitySelectorListUpdate = false;
$( document ).on( 'input propertychange paste', '.wikibase-snakview-value-container:has(.ui-suggester-input)', function () {
currentField = $( this ).find( '.ui-suggester-input' ).first();
willEntitySelectorListUpdate = true;
} );
$( document ).on( 'DOMSubtreeModified', '.ui-entityselector-list', function () {
if ( willEntitySelectorListUpdate ) {
var firstLi = $( this ).find( 'li' ).first();
var isNotFound = firstLi.hasClass( 'ui-entityselector-notfound' );
if ( isNotFound ) {
willEntitySelectorListUpdate = false;
var $innerA = firstLi.find( 'a' ).first();
$innerA.on( 'click', function () {
firstLi.remove();
var citoidWindow = windowManager.openWindow( citoidDialog, { search: currentField.val() } );
citoidWindow.opened.then( function () {
citoidDialog.executeAction( 'lookup' );
} );
citoidWindow.closed.then( function( qid ) {
if ( qid ) {
currentField.val( qid );
}
} );
return false;
} );
$innerA.text( "No item with that title found; Create new reference item?" );
}
}
} );
}
$( function () {
mw.hook( 'wikibase.entityPage.entityLoaded' ).add( init );
} );
}( jQuery, mediaWiki ) );
File Metadata
Details
Attached
Mime Type
text/plain; charset=utf-8
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
6180865
Default Alt Text
WIP wikidata gadget (12 KB)
Attached To
Mode
P7368 WIP wikidata gadget
Attached
Detach File
Event Timeline
Log In to Comment