MediaWiki:Gadget-extsearch.js
Merk: Etter publisering vil det kanskje være nødvendig å slette mellomlageret i nettleseren din for å se endringene.
- Firefox / Safari: Hold Shift mens du klikker på Oppdater, eller trykk enten Ctrl+F5 eller Ctrl+R (⌘+R på Mac)
- Google Chrome: Trykk Ctrl+Shift+R (⌘+Shift+R på Mac)
- Internet Explorer / Edge: Hold Ctrl mens du trykker på Oppdater eller trykk Ctrl+F5
- Opera: Ttrykk Ctrl+F5.
/**
* External search gadget
*
* This gadget adds links to various external databases/websites in the sidebar
* for articles. By default, it searches for the page title, but if the user
* has selected some text in the article, it will search for that text instead.
*
* Idea from several older gadgets on no.wikipedia.org by User:Jeblad.
*
* @author Jon Harald Søby
* @version 1.2.1 (2024-03-21)
*/
( function() {
if ( !mw.config.get( 'wgIsArticle' ) ) {
return;
}
const conf = JSON.parse( mw.user.options.get( 'userjs-extsearch' ) ) || [];
//---- START gadget configuration ----//
// Search engine data. The key is the ID for the search engine (which will
// also be used when saving the options), and the value is an object with
// three keys:
// * 'name': The displayed name of the search engine
// * 'title': What will be shown when users hover the search engine
// * 'urlPattern': The URL to form a search in the search engine, with $1
// where the actual search term goes.
// TODO: Let users customize their own search engines?
const searchEngineData = {
'bokhylla': {
'name': 'Nettbiblioteket (tidl. Bokhylla)',
'title': 'Søk etter «$1» i Nettbiblioteket hos Nasjonalbiblioteket',
'urlPattern': 'https://www.nb.no/search?q=$1'
},
'twl': {
'name': 'The Wikipedia Library',
'title': 'Søk etter «$1» i The Wikipedia Library',
'urlPattern': 'https://wikipedialibrary.wmflabs.org/search/?q=$1'
},
'oria': {
'name': 'Oria (tidl. Bibsys)',
'title': 'Søk etter «$1» i Oria',
'urlPattern': 'https://bibsys-almaprimo.hosted.exlibrisgroup.com/primo-explore/search?vid=BIBSYS&query=any,contains,$1'
},
'snl': {
'name': 'Store norske leksikon',
'title': 'Søk etter «$1» i Store norske leksikon',
'urlPattern': 'https://snl.no/.search?query=$1'
},
'oslobilder': {
'name': 'Oslobilder',
'title': 'Søk etter «$1» i Oslobilder',
'urlPattern': 'http://oslobilder.no/search?searchstring=$1'
},
'digitaltmuseum': {
'name': 'DigitaltMuseum',
'title': 'Søk etter «$1» i DigitaltMuseum',
'urlPattern': 'https://digitaltmuseum.no/search/?q=$1'
},
'kulturminnesok': {
'name': 'Kulturminnesøk',
'title': 'Søk etter «$1» hos Kulturminnesøk',
'urlPattern': 'https://kulturminnesok.no/kart/?q=$1'
},
'ssr': {
'name': 'SSR faktaark',
'title': 'Søk etter «$1» i Sentralt stedsnavnregister',
'urlPattern': 'https://stadnamn.kartverket.no/fakta/?stedsnavn=$1'
},
'google': {
'name': 'Google',
'title': 'Søk etter «$1» med Google',
'urlPattern': 'https://www.google.com/search?q=$1'
},
'bing': {
'name': 'Bing',
'title': 'Søk etter «$1» med Bing',
'urlPattern': 'https://www.bing.com/search?q=$1'
},
'duckduckgo': {
'name': 'DuckDuckGo',
'title': 'Søk etter «$1» med DuckDuckGo',
'urlPattern': 'https://duckduckgo.com/?q=$1'
},
'nowiki': {
'name': 'Wikipedia på bokmål',
'title': 'Søk etter «$1» i Wikipedia på bokmål',
'urlPattern': 'https://no.wikipedia.org/w/index.php?fulltext=1&search=$1'
},
'nnwiki': {
'name': 'Wikipedia på nynorsk',
'title': 'Søk etter «$1» i Wikipedia på nynorsk',
'urlPattern': 'https://nn.wikipedia.org/w/index.php?fulltext=1&search=$1'
},
'enwiki': {
'name': 'Wikipedia på engelsk',
'title': 'Søk etter «$1» i Wikipedia på engelsk',
'urlPattern': 'https://en.wikipedia.org/w/index.php?fulltext=1&search=$1'
},
'commons': {
'name': 'Wikimedia Commons',
'title': 'Mediefilsøk etter «$1» på Wikimedia Commons',
'urlPattern': 'https://commons.wikimedia.org/w/index.php?title=Special:MediaSearch&search=$1'
},
'wikidata': {
'name': 'Wikidata',
'title': 'Søk etter «$1» på Wikidata',
'urlPattern': 'https://www.wikidata.org/w/index.php?search=$1'
}
};
const messages = {
'userjs-extsearch-portlet-title': 'Eksterne søk',
'userjs-extsearch-title': 'Rediger søkemotorer',
'userjs-extsearch-save': 'Lagre',
'userjs-extsearch-cancel': 'Avbryt',
'userjs-extsearch-error': 'Noe gikk galt. Last siden på nytt og prøv igjen.',
'userjs-extsearch-suggestions': 'Forslag til flere søkemotorer? [[MediaWiki-diskusjon:Gadget-extsearch.js|Legg dem inn her]].',
};
mw.messages.set( messages );
//---- END gadget configuration ----//
const portletId = 'p-query';
mw.util.addPortlet( portletId, mw.msg( 'userjs-extsearch-portlet-title' ), '#p-Wikipedia' ); // Temporary, as workaround for T351029
mw.util.showPortlet( portletId );
function addSearchLinks() {
for ( const engine of conf ) {
if ( !searchEngineData[ engine ] ) {
// Check if the search engine is in the current list of search
// engines (defined above). If we don't do this, an error
// could occur if a search engine the user had enabled
// was removed from the gadget.
continue;
}
mw.util.addPortletLink(
portletId,
searchEngineData[ engine ].urlPattern.replace(
'$1',
encodeURIComponent( mw.config.get( 'wgTitle' ) )
),
searchEngineData[ engine ].name,
'extsearch-' + engine,
searchEngineData[ engine ].title
);
}
// Functionality to search for the selected text
$( '#' + portletId + ' a' ).on( 'mouseenter focus', function( e ) {
const thisEngine = $( this ).closest( 'li' ).attr( 'id' ).split( '-' );
if ( thisEngine[ 0 ] !== 'extsearch' ) {
// Just in case an unrelated link snuck in there
return;
}
let selection = window.getSelection().toString() || mw.config.get( 'wgTitle' );
// Truncate the selection to max 128 characters (in case the user
// has selected an entire paragraph, for instance).
selection = selection.substring( 0, 128 );
const url = searchEngineData[ thisEngine[ 1 ] ].urlPattern.replace(
'$1',
encodeURIComponent( selection )
);
$( this )
.attr( 'href', url )
.attr( 'title', searchEngineData[ thisEngine[ 1 ] ].title.replace( '$1', selection ) );
} );
}
function addOptionsButton() {
mw.util.addCSS(
'body.skin-vector .extsearch-options-button,\n' +
'body.skin-vector-2022 .extsearch-options-button {\n\t' +
'margin-top: 8px;\n' +
'}\n' +
'.extsearch-options-button {\n\t' +
'background: transparent url(' +
'/w/extensions/UniversalLanguageSelector/resources/images/cog-sprite.svg' +
') no-repeat center top;\n\t' +
'border: 0;\n\t' +
'min-height: 16px;\n\t' +
'min-width: 16px;\n\t' +
'cursor: pointer;\n\t' +
'float: right\n\t' +
'}\n' +
'.extsearch-options-button:hover {\n\t' +
'background-position: center -16px;\n' +
'}'
);
const $optionsButton = $( '<button>' )
.addClass( 'extsearch-options-button' )
.attr( 'title', mw.msg( 'userjs-extsearch-title' ) )
.on( 'click', optionsDialog );
$( '#' + portletId ).prepend( $optionsButton );
}
function setOptions( options ) {
return new mw.Api().postWithEditToken( {
action: 'options',
format: 'json',
formatversion: 2,
optionname: 'userjs-extsearch',
optionvalue: JSON.stringify( options )
} );
}
function optionsDialog() {
function EditSearchDialog( config ) {
EditSearchDialog.super.call( this, config );
}
OO.inheritClass( EditSearchDialog, OO.ui.ProcessDialog );
EditSearchDialog.static.name = 'editSearchDialog';
EditSearchDialog.static.title = mw.msg( 'userjs-extsearch-title' );
EditSearchDialog.static.actions = [
{
action: 'save',
label: mw.msg( 'userjs-extsearch-save' ),
flags: [ 'primary', 'progressive' ],
framed: true
},
{
label: mw.msg( 'userjs-extsearch-cancel' ),
flags: 'safe',
icon: 'close',
invisibleLabel: true
}
];
EditSearchDialog.prototype.initialize = function() {
EditSearchDialog.super.prototype.initialize.apply( this, arguments );
this.fields = [];
const fieldset = new OO.ui.FieldsetLayout();
for ( const key in searchEngineData ) {
const checkbox = new OO.ui.CheckboxInputWidget( {
value: key,
selected: conf.includes( key )
} );
this.fields.push( checkbox );
fieldset.addItems( [
new OO.ui.FieldLayout( checkbox, {
label: searchEngineData[ key ].name,
align: 'inline'
} )
] );
}
this.content = new OO.ui.PanelLayout(
{
padded: true,
expanded: false,
$content: fieldset.$element.css( { 'column-count': 2 } )
}
);
this.content.$element.append( $( '<hr>' ) );
this.content.$element.append( $( '<p>' ).append(
mw.message( 'userjs-extsearch-suggestions' ).parseDom()
) );
this.$body.append( this.content.$element );
};
EditSearchDialog.prototype.getActionProcess = function( action ) {
const dialog = this;
if ( action === 'save' ) {
dialog.pushPending();
const newoptions = [];
for ( const field of dialog.fields ) {
if ( field.selected ) {
newoptions.push( field.value );
}
}
setOptions( newoptions ).then( function() {
dialog.close();
location.reload();
} ).fail( function() {
mw.notify( mw.msg( 'userjs-extsearch-error', { type: 'error' } ) );
} );
}
return EditSearchDialog.super.prototype.getActionProcess.call( this, action );
};
const windowManager = new OO.ui.WindowManager();
$( document.body ).append( windowManager.$element );
const dialog = new EditSearchDialog();
windowManager.addWindows( [ dialog ] );
windowManager.openWindow( dialog );
}
// Add the options cog to the sidebar portlet
addOptionsButton();
// Add the search links to the sidebar portlet
addSearchLinks();
} )();