mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Popups
synced 2024-11-28 01:10:04 +00:00
Merge "Resize thumbnails images returned by REST endpoint"
This commit is contained in:
commit
ade818e89e
BIN
resources/dist/index.js
vendored
BIN
resources/dist/index.js
vendored
Binary file not shown.
BIN
resources/dist/index.js.map
vendored
BIN
resources/dist/index.js.map
vendored
Binary file not shown.
3
src/constants.js
Normal file
3
src/constants.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
THUMBNAIL_SIZE: 300 * $.bracketedDevicePixelRatio()
|
||||
};
|
|
@ -1,7 +1,6 @@
|
|||
( function ( mw, $ ) {
|
||||
( function ( mw ) {
|
||||
|
||||
var EXTRACT_LENGTH = 525,
|
||||
THUMBNAIL_SIZE = 300 * $.bracketedDevicePixelRatio(),
|
||||
// Public and private cache lifetime (5 minutes)
|
||||
CACHE_LIFETIME = 300;
|
||||
|
||||
|
@ -9,9 +8,10 @@
|
|||
* MediaWiki API gateway factory
|
||||
*
|
||||
* @param {mw.Api} api
|
||||
* @param {mw.ext.constants } config
|
||||
* @returns {ext.popups.Gateway}
|
||||
*/
|
||||
function createMediaWikiApiGateway( api ) {
|
||||
function createMediaWikiApiGateway( api, config ) {
|
||||
|
||||
/**
|
||||
* Fetch page data from the API
|
||||
|
@ -33,7 +33,7 @@
|
|||
explaintext: true,
|
||||
|
||||
piprop: 'thumbnail',
|
||||
pithumbsize: THUMBNAIL_SIZE,
|
||||
pithumbsize: config.THUMBNAIL_SIZE,
|
||||
rvprop: 'timestamp',
|
||||
inprop: 'url',
|
||||
titles: title,
|
||||
|
@ -106,4 +106,4 @@
|
|||
|
||||
module.exports = createMediaWikiApiGateway;
|
||||
|
||||
}( mediaWiki, jQuery ) );
|
||||
}( mediaWiki ) );
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
( function ( mw ) {
|
||||
( function ( mw, $ ) {
|
||||
|
||||
var RESTBASE_ENDPOINT = '/api/rest_v1/page/summary/',
|
||||
RESTBASE_PROFILE = 'https://www.mediawiki.org/wiki/Specs/Summary/1.0.0';
|
||||
|
@ -7,9 +7,10 @@
|
|||
* RESTBase gateway factory
|
||||
*
|
||||
* @param {Function} ajax function from jQuery for example
|
||||
* @param {ext.popups.constants} config set of configuration values
|
||||
* @returns {ext.popups.Gateway}
|
||||
*/
|
||||
function createRESTBaseGateway( ajax ) {
|
||||
function createRESTBaseGateway( ajax, config ) {
|
||||
|
||||
/**
|
||||
* Fetch page data from the API
|
||||
|
@ -35,7 +36,9 @@
|
|||
*/
|
||||
function getPageSummary( title ) {
|
||||
return fetch( title )
|
||||
.then( convertPageToModel );
|
||||
.then( function( page ) {
|
||||
return convertPageToModel( page, config.THUMBNAIL_SIZE );
|
||||
} );
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -45,23 +48,44 @@
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the original thumbnail and ensure it fits within limits of THUMBNAIL_SIZE
|
||||
*
|
||||
* @param {Object} original image
|
||||
* @param {int} thumbSize expected thumbnail size
|
||||
* @returns {Object}
|
||||
*/
|
||||
function generateThumbnailData( original, thumbSize ) {
|
||||
var parts = original.source.split( '/' ),
|
||||
filename = parts[ parts.length - 1 ];
|
||||
|
||||
if ( thumbSize > original.width && filename.indexOf( '.svg' ) === -1 ) {
|
||||
thumbSize = original.width;
|
||||
}
|
||||
|
||||
return $.extend( {}, original, {
|
||||
source: parts.join( '/' ) + '/' + thumbSize + 'px-' + filename
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the rest API response to a preview model
|
||||
*
|
||||
* @param {Object} page
|
||||
* @param {int} thumbSize
|
||||
* @returns {ext.popups.PreviewModel}
|
||||
*/
|
||||
function convertPageToModel( page ) {
|
||||
function convertPageToModel( page, thumbSize ) {
|
||||
return mw.popups.preview.createModel(
|
||||
page.title,
|
||||
new mw.Title( page.title ).getUrl(),
|
||||
page.lang,
|
||||
page.dir,
|
||||
page.extract,
|
||||
page.thumbnail
|
||||
page.originalimage ? generateThumbnailData( page.originalimage, thumbSize ) : undefined
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = createRESTBaseGateway;
|
||||
|
||||
}( mediaWiki ) );
|
||||
}( mediaWiki, jQuery ) );
|
||||
|
|
21
src/index.js
21
src/index.js
|
@ -1,13 +1,14 @@
|
|||
( function ( mw, popups, Redux, ReduxThunk, $ ) {
|
||||
var BLACKLISTED_LINKS = [
|
||||
'.extiw',
|
||||
'.image',
|
||||
'.new',
|
||||
'.internal',
|
||||
'.external',
|
||||
'.oo-ui-buttonedElement-button',
|
||||
'.cancelLink a'
|
||||
];
|
||||
'.extiw',
|
||||
'.image',
|
||||
'.new',
|
||||
'.internal',
|
||||
'.external',
|
||||
'.oo-ui-buttonedElement-button',
|
||||
'.cancelLink a'
|
||||
],
|
||||
constants = require( './constants' );
|
||||
|
||||
/**
|
||||
* Creates a gateway with sensible values for the dependencies.
|
||||
|
@ -17,9 +18,9 @@
|
|||
*/
|
||||
function createGateway( config ) {
|
||||
if ( config.get( 'wgPopupsAPIUseRESTBase' ) ) {
|
||||
return popups.gateway.createRESTBaseGateway( $.ajax );
|
||||
return popups.gateway.createRESTBaseGateway( $.ajax, constants );
|
||||
}
|
||||
return popups.gateway.createMediaWikiApiGateway( new mw.Api() );
|
||||
return popups.gateway.createMediaWikiApiGateway( new mw.Api(), constants );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
var createModel = mw.popups.preview.createModel,
|
||||
createMediaWikiApiGateway = mw.popups.gateway.createMediaWikiApiGateway,
|
||||
DEFAULT_CONSTANTS = {
|
||||
THUMBNAIL_SIZE: 300
|
||||
},
|
||||
MEDIAWIKI_API_RESPONSE = {
|
||||
query: {
|
||||
pages: [
|
||||
|
@ -52,7 +55,7 @@
|
|||
api = {
|
||||
get: spy
|
||||
},
|
||||
gateway = createMediaWikiApiGateway( api ),
|
||||
gateway = createMediaWikiApiGateway( api, DEFAULT_CONSTANTS),
|
||||
expectedOptions = {
|
||||
action: 'query',
|
||||
prop: 'info|extracts|pageimages|revisions|info',
|
||||
|
@ -62,7 +65,7 @@
|
|||
exchars: 525,
|
||||
explaintext: true,
|
||||
piprop: 'thumbnail',
|
||||
pithumbsize: 300 * $.bracketedDevicePixelRatio(),
|
||||
pithumbsize: DEFAULT_CONSTANTS.THUMBNAIL_SIZE,
|
||||
rvprop: 'timestamp',
|
||||
inprop: 'url',
|
||||
titles: 'Test Title',
|
||||
|
@ -86,7 +89,7 @@
|
|||
var api = {
|
||||
get: this.sandbox.stub()
|
||||
},
|
||||
gateway = createMediaWikiApiGateway( api ),
|
||||
gateway = createMediaWikiApiGateway( api, DEFAULT_CONSTANTS ),
|
||||
errorCases = [
|
||||
{},
|
||||
{
|
||||
|
@ -142,7 +145,7 @@
|
|||
api = {
|
||||
get: this.sandbox.stub().returns( deferred.promise() )
|
||||
},
|
||||
gateway = createMediaWikiApiGateway( api ),
|
||||
gateway = createMediaWikiApiGateway( api, DEFAULT_CONSTANTS ),
|
||||
done = assert.async( 1 );
|
||||
|
||||
gateway.getPageSummary( 'Test Title' ).fail( function () {
|
||||
|
@ -159,7 +162,7 @@
|
|||
$.Deferred().resolve( MEDIAWIKI_API_RESPONSE ).promise()
|
||||
)
|
||||
},
|
||||
gateway = createMediaWikiApiGateway( api ),
|
||||
gateway = createMediaWikiApiGateway( api, DEFAULT_CONSTANTS ),
|
||||
done = assert.async( 1 );
|
||||
|
||||
gateway.getPageSummary( 'Test Title' ).done( function ( result ) {
|
||||
|
@ -198,7 +201,7 @@
|
|||
$.Deferred().resolve( response ).promise()
|
||||
)
|
||||
},
|
||||
gateway = createMediaWikiApiGateway( api ),
|
||||
gateway = createMediaWikiApiGateway( api, DEFAULT_CONSTANTS),
|
||||
done = assert.async( 1 );
|
||||
|
||||
gateway.getPageSummary( 'Test Title' ).done( function ( result ) {
|
||||
|
|
|
@ -2,14 +2,35 @@
|
|||
|
||||
var createModel = mw.popups.preview.createModel,
|
||||
createRESTBaseGateway = mw.popups.gateway.createRESTBaseGateway,
|
||||
DEFAULT_CONSTANTS = {
|
||||
THUMBNAIL_SIZE: 512
|
||||
},
|
||||
SVG_ORIGINAL_IMAGE = {
|
||||
source: "https://upload.wikimedia.org/wikipedia/commons/8/8d/Ceiling_cat.svg",
|
||||
width: 800,
|
||||
height: 1000
|
||||
},
|
||||
RESTBASE_RESPONSE = {
|
||||
title: 'Barack Obama',
|
||||
extract: 'Barack Hussein Obama II born August 4, 1961) ...',
|
||||
thumbnail: {
|
||||
source: 'https://upload.wikimedia.org/someImage.jpg',
|
||||
width: 256,
|
||||
height: 320
|
||||
width: 200,
|
||||
height: 250
|
||||
},
|
||||
originalimage: {
|
||||
source: "https://upload.wikimedia.org/wikipedia/commons/8/8d/President_Barack_Obama.jpg",
|
||||
width: 800,
|
||||
height: 1000
|
||||
},
|
||||
lang: 'en',
|
||||
dir: 'ltr',
|
||||
timestamp: '2017-01-30T10:17:41Z',
|
||||
description: '44th President of the United States of America'
|
||||
},
|
||||
RESTBASE_RESPONSE_WITHOUT_IMAGE = {
|
||||
title: 'Barack Obama',
|
||||
extract: 'Barack Hussein Obama II born August 4, 1961) ...',
|
||||
lang: 'en',
|
||||
dir: 'ltr',
|
||||
timestamp: '2017-01-30T10:17:41Z',
|
||||
|
@ -22,14 +43,12 @@
|
|||
'ltr',
|
||||
'Barack Hussein Obama II born August 4, 1961) ...',
|
||||
{
|
||||
source: 'https://upload.wikimedia.org/someImage.jpg',
|
||||
width: 256,
|
||||
height: 320
|
||||
source: 'https://upload.wikimedia.org/wikipedia/commons/8/8d/President_Barack_Obama.jpg/512px-President_Barack_Obama.jpg',
|
||||
width: 800,
|
||||
height: 1000
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.module( 'ext.popups/gateway/rest' );
|
||||
|
||||
QUnit.test( 'RESTBase gateway is called with correct arguments', function ( assert ) {
|
||||
var getSpy = this.sandbox.spy(),
|
||||
gateway = createRESTBaseGateway( getSpy ),
|
||||
|
@ -50,11 +69,38 @@
|
|||
var gateway = createRESTBaseGateway();
|
||||
|
||||
assert.deepEqual(
|
||||
gateway.convertPageToModel( RESTBASE_RESPONSE ),
|
||||
gateway.convertPageToModel( RESTBASE_RESPONSE, 512 ),
|
||||
RESTBASE_RESPONSE_PREVIEW_MODEL
|
||||
);
|
||||
} );
|
||||
|
||||
QUnit.test( 'RESTBase gateway doesn\'t stretch thumbnails', function ( assert ) {
|
||||
var model,
|
||||
gateway = createRESTBaseGateway();
|
||||
|
||||
model = gateway.convertPageToModel( RESTBASE_RESPONSE, 2000);
|
||||
|
||||
assert.equal(
|
||||
model.thumbnail.source,
|
||||
'https://upload.wikimedia.org/wikipedia/commons/8/8d/President_Barack_Obama.jpg/800px-President_Barack_Obama.jpg',
|
||||
'If the requested thumbnail size is bigger than the originalimage width the originalimage width is used'
|
||||
);
|
||||
} );
|
||||
|
||||
QUnit.test( 'RESTBase gateway stretches SVGs', function ( assert ) {
|
||||
var model,
|
||||
gateway = createRESTBaseGateway();
|
||||
|
||||
model = gateway.convertPageToModel( $.extend( {}, RESTBASE_RESPONSE, { originalimage: SVG_ORIGINAL_IMAGE } ),
|
||||
2000 );
|
||||
|
||||
assert.equal(
|
||||
model.thumbnail.source,
|
||||
'https://upload.wikimedia.org/wikipedia/commons/8/8d/Ceiling_cat.svg/2000px-Ceiling_cat.svg',
|
||||
'If the requested thumbnail size is bigger than the originalimage and its an SVG all is good'
|
||||
);
|
||||
} );
|
||||
|
||||
QUnit.test( 'RESTBase gateway handles the API failure', function ( assert ) {
|
||||
var deferred = $.Deferred(),
|
||||
api = this.sandbox.stub().returns( deferred.promise() ),
|
||||
|
@ -73,7 +119,7 @@
|
|||
var api = this.sandbox.stub().returns(
|
||||
$.Deferred().resolve( RESTBASE_RESPONSE ).promise()
|
||||
),
|
||||
gateway = createRESTBaseGateway( api ),
|
||||
gateway = createRESTBaseGateway( api, DEFAULT_CONSTANTS),
|
||||
done = assert.async( 1 );
|
||||
|
||||
gateway.getPageSummary( 'Test Title' ).done( function ( result ) {
|
||||
|
@ -82,6 +128,18 @@
|
|||
} );
|
||||
} );
|
||||
|
||||
QUnit.test( 'RESTBase gateway handles missing images ', function ( assert ) {
|
||||
var model,
|
||||
gateway = createRESTBaseGateway();
|
||||
model = gateway.convertPageToModel( RESTBASE_RESPONSE_WITHOUT_IMAGE, 300 );
|
||||
|
||||
assert.equal(
|
||||
model.originalimage,
|
||||
undefined,
|
||||
'If restbase handles missing image information'
|
||||
);
|
||||
} );
|
||||
|
||||
QUnit.test( 'RESTBase gateway handles missing pages ', function ( assert ) {
|
||||
var response = {
|
||||
type: 'https://mediawiki.org/wiki/HyperSwitch/errors/not_found',
|
||||
|
@ -93,7 +151,7 @@
|
|||
api = this.sandbox.stub().returns(
|
||||
$.Deferred().rejectWith( response ).promise()
|
||||
),
|
||||
gateway = createRESTBaseGateway( api ),
|
||||
gateway = createRESTBaseGateway( api, DEFAULT_CONSTANTS ),
|
||||
done = assert.async( 1 );
|
||||
|
||||
gateway.getPageSummary( 'Missing Page' ).fail( function () {
|
||||
|
|
Loading…
Reference in a new issue