मीडियाविकि:Gadget-ImportPagelist.js
ध्यान दें: प्रकाशित करने के बाद बदलाव देखने के लिए आपको अपने ब्राउज़र के कैश को हटाना पड़ सकता है।
- Firefox/Safari: Reload क्लिक समय Shift दबाएँ, या फिर Ctrl-F5 या Ctrl-R दबाएँ (Mac पर ⌘-R)
- Google Chrome: Ctrl-Shift-R दबाएँ (Mac पर ⌘-Shift-R)
- Internet Explorer/Edge: Refresh पर क्लिक करते समय Ctrl दबाएँ, या Ctrl-F5 दबाएँ
- Opera: Ctrl-F5 दबाएँ।
/**
* Import pagelist gadget
*
* Adds a link to import a pagelist from a given IA identifier
*
* Uses the pagelister.toolforge.org tool
*
* Changelog:
* * 2020-10-24: Initial version
* * 2020-11-27: Update cover image from title page, if there is one
* * 2021-01-06: Handle Hathi links
*/
/* eslint-disable
camelcase
*/
'use strict';
// IIFE used when including as a user script (to allow debug or config)
// Default gadget use will get an IIFE wrapper as well
( function () {
var gadgetName = 'import_pagelist',
IPL = {
enabled: true,
configured: false,
host: 'https://pagelister.toolforge.org',
linkLabel: 'Import pagelist',
link_style: { 'font-size': '92%', float: 'right' },
error_message: 'An error occurred:',
bad_response_msg: 'Bad response from pagelist server',
cancel_btn: 'Cancel',
import_btn: 'Import',
dialog_title: 'Import pagelist'
};
/*
* Read config from user. function fired by hook
*/
function apply_config( cfg ) {
console.log( 'Configuring ' + gadgetName );
// Bail if the config looks like junkA
if ( !cfg || typeof cfg !== 'object' ) {
console.error( 'Invalid ' + gadgetName + ' config', cfg );
return;
}
if ( typeof cfg.enabled === 'boolean' ) {
IPL.enabled = cfg.enabled;
}
if ( typeof cfg.host === 'string' ) {
IPL.host = cfg.host;
}
IPL.configured = true;
}
function install_dialog() {
var ParamDialog = function ( config ) {
ParamDialog.super.call( this, config );
};
OO.inheritClass( ParamDialog, OO.ui.ProcessDialog );
// Specify a name for .addWindows()
ParamDialog.static.name = 'importPageListDialog';
ParamDialog.static.title = IPL.dialog_title;
// Specify the static configurations: title and action set
ParamDialog.static.actions = [ {
flags: 'primary',
label: IPL.import_btn,
action: 'open'
},
{
flags: 'safe',
label: IPL.cancel_btn
}
];
// Customize the initialize() function to add content and layouts:
ParamDialog.prototype.initialize = function () {
ParamDialog.super.prototype.initialize.call( this );
this.panel = new OO.ui.PanelLayout( {
padded: true,
expanded: false
} );
this.content = new OO.ui.FieldsetLayout();
this.inputs = {};
this.fields = {};
this.inputs.source = new OO.ui.DropdownInputWidget( {
options: [
{ data: 'ia', label: 'Internet Archive' },
{ data: 'ht', label: 'Hathi Trust' }
] } );
// this.inputs['source'].selectItem( option1 );
this.fields.source = new OO.ui.FieldLayout( this.inputs.source, {
label: 'Source',
align: 'right'
} );
this.content.addItems( [ this.fields.source ] );
this.inputs.id = new OO.ui.TextInputWidget();
this.fields.id = new OO.ui.FieldLayout( this.inputs.id, {
label: 'ID',
align: 'right'
} );
this.content.addItems( [ this.fields.id ] );
this.inputs.offset = new OO.ui.NumberInputWidget( {
value: 0,
step: 1
} );
this.fields.offset = new OO.ui.FieldLayout( this.inputs.offset, {
label: 'Offset',
help: 'Offset between the source and the file. If the file are identical, this is 0. If a cover page has been removed, it is 1',
align: 'right'
} );
this.content.addItems( [ this.fields.offset ] );
this.panel.$element.append( this.content.$element );
this.$body.append( this.panel.$element );
};
ParamDialog.prototype.prefill_id = function ( link ) {
this.inputs.id.setValue( link.id );
this.inputs.source.setValue( link.source );
};
// Use getSetupProcess() to set up the window with data passed to it at the time
// of opening (e.g., url: 'http://www.mediawiki.org', in this example).
ParamDialog.prototype.getSetupProcess = function ( data ) {
var self = this;
data = data || {};
return ParamDialog.super.prototype.getSetupProcess.call( this, data )
.next( function () {
// Fire off a request to see if we can find any useful IDs in the commons page
find_likely_ids( function ( data ) {
self.prefill_id( data );
} );
}, this );
};
function report_error( msg ) {
alert( IPL.error_message + '\n\n' + msg );
}
// Specify processes to handle the actions.
ParamDialog.prototype.getActionProcess = function ( action ) {
var dialog = this;
if ( action === 'open' ) {
// Create a new process to handle the action
return new OO.ui.Process( function () {
set_pl_enabled( false );
fetch( IPL.host + '/pagelist/v1/list?' + new URLSearchParams( {
source: dialog.inputs.source.getValue(),
id: dialog.inputs.id.getValue(),
offset: dialog.inputs.offset.getNumericValue(),
} ) )
.then( function ( response ) { return response.json(); } )
.then( function ( data ) {
if ( data ) {
if ( data.errors !== undefined ) {
var errors = data.errors.map( function ( e ) {
return e.msg;
} ).join( '\n' );
report_error( errors );
} else if ( data.pagelist !== undefined ) {
var plv = data.pagelist;
set_pl_value( plv );
set_cover_value( plv );
} else {
report_error( IPL.bad_response_msg );
}
}
} )
.finally( function () { set_pl_enabled( true ); } );
dialog.close( {
action: action
} );
}, this );
}
// Fallback to parent handler
return ParamDialog.super.prototype.getActionProcess.call( this, action );
};
ParamDialog.prototype.getTeardownProcess = function ( data ) {
return ParamDialog.super.prototype.getTeardownProcess.call( this, data )
.first( function () {
// Perform any cleanup as needed
}, this );
};
// Create and append a window manager.
var windowManager = new OO.ui.WindowManager();
$( 'body' ).append( windowManager.$element );
// Create a new process dialog window.
var paramDlg = new ParamDialog();
// Add the window to window manager using the addWindows() method.
windowManager.addWindows( [ paramDlg ] );
// Open the window!
windowManager.openWindow( paramDlg );
// focus the input in just a moment
setTimeout( function () {
paramDlg.$body.find( 'input' )[ 0 ].focus();
}, 300 );
}
function get_ia_id_from_url( url ) {
var rx = /(details|manage|download)\/([^/]*)/,
match = rx.exec( url.pathname );
if ( match ) {
return match[ 2 ];
}
return null;
}
function get_ht_id_from_url( url ) {
if ( url.hostname.match( /hathitrust.org$/ ) ) {
// null if not found
return url.searchParams.get( 'id' );
} else if ( url.hostname.match( /hdl.handle.net$/ ) ) {
return url.pathname.split( '/' )[ 2 ];
}
return null;
}
// Find IA links in a page's content
function find_useful_links( data ) {
for ( var page in data.query.pages ) {
var extlinks = data.query.pages[ page ].extlinks;
if ( extlinks ) {
for ( var i = 0; i < extlinks.length; i++ ) {
var l = extlinks[ i ].url;
if ( l.startsWith( '//' ) ) {
l = window.location.protocol + l;
}
var url = new URL( l );
if ( url.hostname.match( /archive.org$/ ) ) {
var id = get_ia_id_from_url( url );
if ( id !== null ) {
return { source: 'ia', id: id };
}
} else if ( url.hostname.match( /hathitrust.org$/ ) ||
( url.hostname.match( /hdl.handle.net$/ ) ) ) {
var id = get_ht_id_from_url( url );
if ( id !== null ) {
return { source: 'ht', id: id };
}
}
}
}
var iwlinks = data.query.pages[ page ].iwlinks;
if ( iwlinks ) {
for ( var i = 0; i < iwlinks.length; i++ ) {
var l = iwlinks[ i ];
if ( l.prefix === 'iarchive' ) {
return { source: 'ia', id: l.title };
}
}
}
}
return null;
}
function find_likely_ids( callback ) {
// Get all external links from the Commons file page
mw.loader.using( 'mediawiki.ForeignApi' ).done( function () {
var api = new mw.ForeignApi( 'https://commons.wikimedia.org/w/api.php' ),
com_pg = 'File:' + mw.config.get( 'wgTitle' );
api.get( {
action: 'query',
format: 'json',
formatversion: 2,
prop: 'extlinks|iwlinks',
titles: com_pg,
ellimit: 100,
iwlimit: 100
} ).done( function ( data ) {
var link = find_useful_links( data );
if ( link !== null ) {
callback( link );
}
} ).fail( function ( data ) {
console.log( 'Commons GET Failed:', data );
} );
} );
}
function set_pl_value( plv ) {
OO.ui.infuse( $( '#wpprpindex-Pages' ).parent() ).setValue( plv );
}
function set_cover_value( plv ) {
// Set the cover image if there is one
var match = /(\d+)=["']?[Tt]itle["']\s/.exec( plv );
if ( match ) {
$( '#wpprpindex-Image' ).val( match[ 1 ] );
}
}
function set_pl_enabled( enabled ) {
OO.ui.infuse( $( '#wpprpindex-Pages' ).parent() ).setDisabled( !enabled );
}
// User clicked - install the dialog
function activate() {
mw.loader.using( [ 'mediawiki.util', 'oojs-ui-core', 'oojs-ui-widgets' ],
install_dialog );
}
// Insert the button next to the right field
function insert_button() {
var $btn = $( '<a>' )
.attr( 'href', '#' )
.append( IPL.linkLabel )
.addClass( 'import_pagelist_link' )
.on( 'click', activate );
// eslint-disable-next-line no-jquery/no-global-selector
$( '#wpprpindex-Pages' )
.closest( '.oo-ui-fieldLayout-body' )
.children( '.oo-ui-fieldLayout-header' )
.find( 'label' )
.append( $btn );
}
function add_css_rule( rule, css ) {
css = JSON.stringify( css ).replace( /"/g, '' ).replace( /,/g, ';' );
$( '<style>' ).prop( 'type', 'text/css' ).html( rule + css ).appendTo( 'head' );
}
function setConfigs( cfg ) {
if ( cfg.host ) {
IPL.host = cfg.host;
}
}
function iplSetup() {
var blankCfg = {};
// Get user config, if any
mw.hook( gadgetName + '.config' ).fire( blankCfg );
setConfigs( blankCfg );
// only care for editing in the Index: namespace
if ( !( mw.config.get( 'wgAction' ) === 'edit' || mw.config.get( 'wgAction' ) ===
'submit' ) ||
mw.config.get( 'wgCanonicalNamespace' ) !== 'Index' ) {
return;
}
add_css_rule( '.import_pagelist_link', IPL.link_style );
insert_button();
}
$( iplSetup );
}() );