MediaWiki:Gadget-cards.js

Wikipedia, Entziklopedia askea

Oharra: Gorde ondoren zure nabigatzailearen katxea ekidin beharko duzu aldaketak ikusteko. Mozilla / Firefox / Safari: Shift tekla sakatu birkargatzeko momentuan, edo Ctrl-Shift-R sakatu (Cmd-Shift-R Apple Mac baten); IE: Ctrl tekla sakatu birkargatzeko momentuan, edo Ctrl-F5 sakatu; Konqueror:: Birkargatzeko klik egin, edo F5 sakatu, besterik ez; Opera erabiltzaileek Tresnak-Hobespenak atalera jo eta katxea garbitzeko aukera hautatu.

const { CdxCard, CdxMessage } = require( '@wikimedia/codex' );
const Vue = require( 'vue' );

const CardWidget = {
    components: {
        CdxCard
    },
	props: {
		titles: {
			type: Array
		}
	},
    template: `<div>
    <cdx-card v-for="titleObj in titles" :thumbnail="titleObj.thumbnail" :url="titleObj.url"
        :force-thumbnail="true">
        <template #title>
            {{  titleObj.title  }}
        </template>
        <template #description>
            {{  titleObj.description  }}
        </template>
    </cdx-card>    
</div>`
 }
 const mwApi = new mw.Api();

 /**
 * @param {Object} obj
 * @return {Card}
 */
function toCard( originalTitleObj ) {
	return ( obj ) => Object.assign( {
		url: mw.util.getUrl( obj.title ),
		title: obj.title,
		id: obj.title,
		description: obj.description,
		thumbnail: obj.thumbnail ? Object.assign( {}, obj.thumbnail, {
            url: obj.thumbnail.source
        } ) : undefined
	}, originalTitleObj[obj.title] );
}

function getPages( titleObjs ) {
    const titleMap = {};
    titleObjs.forEach((obj) => titleMap[obj.title] = obj);
	return mwApi.ajax( {
		action: 'query',
		format: 'json',
		origin: '*',
        titles: titleObjs.map( ( titleObj ) => titleObj.title ),
		prop: 'coordinates|info|pageimages|description',
		inprop: 'url',
		formatversion: 2,
		pprop: 'displaytitle',
		piprop: 'thumbnail',
		pithumbsize: 150,
		pilimit: 50
	} ).then( function ( data ) {
		return data.query.pages.map( toCard( titleMap ) );
	} );
}

const titleExpand = ( titles ) => {
    return getPages( titles );
};

const ErrorWidget = {
    components: {
        CdxMessage
    },
	props: {
		message: String
	},
    template: `<cdx-message type="error">
	    <p><strong>Orain ezin da atal hau kargatu. Arazoaren azalpena hemen azpian duzu.</strong></p>	<p>{{ message }}</p></cdx-message>
</div>`
};

function renderError( target, message ) {
    Vue.createApp( ErrorWidget, {
        message
    } ).mount( target );

}
 function loadPageViews( target, url, exclude, limit ) {
    $.get( url )
        .then((data) => {
            titleExpand(
                data.items[0].articles.map((a) => ( {
                    title: a.article
                }) )
                .filter((a) => !a.title.includes(':') && !exclude.includes(a.title))
                .slice(0, limit)
            ).then( ( titles ) => {
                Vue.createApp( CardWidget, {
                    titles
                } ).mount( target )
            })
        }, ( error ) => {
            let message;
            try {
                const r = JSON.parse( error.responseText );
                message = r.detail;
            } catch ( e ) {
                message = 'Unknown';
            }
            renderError( target, message );
        }  );
}

Array.from(document.querySelectorAll( '[data-component="cards"]' )).forEach((node) => {
    const dataset = node.dataset;
    const targetId = dataset.target;
    const type = dataset.apiType;
    const target = targetId ? document.getElementById( targetId ) : node;
    const limit = dataset.limit ? parseInt( dataset.limit, 10 ) : 10;
    const excludeList = dataset.exclude ? dataset.exclude.split('|') : [];
    if ( !target ) {
        renderError( node, 'Widget is not setup correctly (missing render target)' );
        return;
    }
    switch ( type ) {
        case 'nearby':
            if ( targetId === 'mw-nearby-pages' ) {
                mw.loader.using( 'ext.nearby.scripts' );
            } else {
                console.warn( 'Please set targets to "mw-nearby-pages" to use this widget');
            }
            break;
        case 'pageviews':
            if ( dataset.url.indexOf( 'https://' ) === 0 ) {
                console.warn( 'URL should be relative e.g. begin with /api/rest_v1/metrics/pageviews/' );
            } else {
                loadPageViews( target, `https://wikimedia.org${dataset.url}`, excludeList, limit );
            }
            break;
        default:
            console.warn( 'Type not implemented' );
    }
});