MediaWiki:Gadget-PageSnippets.js
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
const PageSnippets = {
init( $content ) {
$content.find( '.page-snippet-filterable' ).each( function () {
const container = this;
if ( container.dataset.filtersReady ) {
return;
}
container.dataset.filtersReady = 'true';
const snippets = Array.from( container.querySelectorAll( '.page-snippet-inline' ) );
if ( !snippets.length ) {
return;
}
const properties = new Map();
// Collect property names and distinct values
snippets.forEach( function ( snippet ) {
snippet.querySelectorAll( '.data-chip[data-property]' )
.forEach( function ( chip ) {
const name = chip.dataset.property.trim();
if ( !name ) {
return;
}
const values = PageSnippets.getValues( chip );
if ( !values.length ) {
return;
}
if ( !properties.has( name ) ) {
properties.set( name, new Set() );
}
values.forEach( function ( value ) {
properties.get( name ).add( value );
} );
} );
} );
if ( !properties.size ) {
return;
}
const controls = document.createElement( 'div' );
controls.className = 'page-snippet-filters';
controls.style.display = 'flex';
controls.style.flexWrap = 'wrap';
controls.style.gap = '1em';
controls.style.margin = '1em 0';
controls.style.alignItems = 'end';
const selections = new Map();
function update() {
let visible = 0;
snippets.forEach( function ( snippet ) {
const chips = Array.from( snippet.querySelectorAll( '.data-chip[data-property]' ) );
const matches = Array.from( selections ).every(
function ( [ property, value ] ) {
if ( !value ) {
return true;
}
return chips.some( function ( chip ) {
return chip.dataset.property.trim() === property &&
PageSnippets.getValues( chip ).includes( value );
} );
}
);
snippet.style.display = matches ? '' : 'none';
if ( matches ) {
visible++;
}
} );
counter.textContent = 'Showing ' + visible + ' of ' + snippets.length + ' projects';
}
properties.forEach( function ( values, name ) {
const select = document.createElement( 'select' );
select.className = 'cdx-select';
const all = document.createElement( 'option' );
all.value = '';
all.textContent = 'All ' + name;
select.appendChild( all );
Array.from( values )
.sort( ( a, b ) => a.localeCompare( b ) )
.forEach( function ( value ) {
const option = document.createElement( 'option' );
option.value = value;
option.textContent = value;
select.appendChild( option );
} );
select.addEventListener( 'change', function () {
selections.set( name, select.value );
update();
} );
controls.appendChild( select );
selections.set( name, '' );
} );
const counter = document.createElement( 'span' );
counter.style.opacity = '0.7';
controls.appendChild( counter );
container.parentNode.insertBefore( controls, container );
update();
} );
},
getValues( chip ) {
const property = chip.dataset.property.trim();
const text = chip.textContent.trim();
if ( !text ) {
return [];
}
// Properties whose values are comma-separated
const multiValueProperties = new Set( [
'Page keywords',
'SDG'
] );
if ( !multiValueProperties.has( property ) ) {
return [ text ];
}
return text.split( ',' ).map( value => value.trim() ).filter( Boolean );
}
}
mw.hook( 'wikipage.content' ).add( PageSnippets.init );