mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/MultimediaViewer
synced 2024-11-28 10:00:18 +00:00
Refactor image load code, add unit tests.
The code to load and set the image was semi-duplicated and scattered in various places. This was the source of defects as this code is called asynchronously and was hard to debug. This change attemps ot consolidate all the image load logic in one place. It also adds sorely needed unit tests. Change-Id: I92eb1c48e2ff0808134e56b4b150e22254eb2d6e
This commit is contained in:
parent
98e03d31c8
commit
f7925a1a4f
|
@ -339,29 +339,9 @@
|
|||
* @param {number} requestedWidth
|
||||
*/
|
||||
MMVP.loadResizedImage = function ( ui, imageData, targetWidth, requestedWidth ) {
|
||||
var rpid, viewer, image, maybeThumb;
|
||||
|
||||
// Replace image only if data was returned.
|
||||
if ( imageData ) {
|
||||
viewer = this;
|
||||
image = new Image();
|
||||
|
||||
image.onload = function () {
|
||||
viewer.profileEnd( rpid );
|
||||
};
|
||||
|
||||
rpid = this.profileStart( 'image-resize', {
|
||||
width: imageData.width,
|
||||
height: imageData.height,
|
||||
fileSize: imageData.size
|
||||
}, imageData.mimeType );
|
||||
|
||||
maybeThumb = imageData.getThumbUrl( requestedWidth );
|
||||
image.src = maybeThumb || imageData.url;
|
||||
if ( maybeThumb && requestedWidth > targetWidth || !maybeThumb && imageData.width > targetWidth ) {
|
||||
image.width = targetWidth;
|
||||
}
|
||||
ui.replaceImageWith( image );
|
||||
this.loadAndSetImage( ui, imageData, targetWidth, requestedWidth, 'image-resize' );
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -597,6 +577,47 @@
|
|||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @method
|
||||
* Loads and sets the image specified in the imageData. It also updates the controls
|
||||
* and collects profiling information.
|
||||
*
|
||||
* @param {mw.LightboxInterface} ui image container
|
||||
* @param {mw.mmv.model.Image} imageData image information
|
||||
* @param {number} targetWidth
|
||||
* @param {number} requestedWidth
|
||||
* @param {string} profileEvent profile event key
|
||||
*/
|
||||
MMVP.loadAndSetImage = function ( ui, imageData, targetWidth, requestedWidth, profileEvent ) {
|
||||
var rpid,
|
||||
maybeThumb,
|
||||
viewer = this,
|
||||
image = new Image();
|
||||
|
||||
image.onload = function () {
|
||||
viewer.profileEnd( rpid );
|
||||
};
|
||||
|
||||
rpid = this.profileStart( profileEvent, {
|
||||
width: imageData.width,
|
||||
height: imageData.height,
|
||||
fileSize: imageData.size
|
||||
}, imageData.mimeType );
|
||||
|
||||
// Use cached image if we have it.
|
||||
maybeThumb = imageData.getThumbUrl( requestedWidth );
|
||||
image.src = maybeThumb || imageData.url;
|
||||
|
||||
if ( maybeThumb && requestedWidth > targetWidth ||
|
||||
!maybeThumb && imageData.width > targetWidth ) {
|
||||
// Image bigger than the current area, resize before loading
|
||||
image.width = targetWidth;
|
||||
}
|
||||
|
||||
ui.replaceImageWith( image );
|
||||
this.updateControls();
|
||||
};
|
||||
|
||||
/**
|
||||
* @method
|
||||
* Loads a specified image.
|
||||
|
@ -630,38 +651,19 @@
|
|||
|
||||
mdpid = this.profileStart( 'metadata-fetch' );
|
||||
|
||||
this.fetchImageInfo( image.filePageTitle ).done( function ( imageData, repoInfo, size, requestedWidth ) {
|
||||
var pid,
|
||||
repoData = mw.mmv.model.Repo.newFromRepoInfo( repoInfo[imageData.repo] ),
|
||||
imageEle = new Image(),
|
||||
targetWidth = size;
|
||||
this.fetchImageInfo( image.filePageTitle ).done( function ( imageData, repoInfo, targetWidth, requestedWidth ) {
|
||||
var repoData = mw.mmv.model.Repo.newFromRepoInfo( repoInfo[imageData.repo] );
|
||||
|
||||
viewer.profileEnd( mdpid );
|
||||
|
||||
viewer.stopListeningToScroll();
|
||||
viewer.animateMetadataDivOnce()
|
||||
// We need to wait until the animation is finished before we listen to scroll
|
||||
.then( function() { viewer.startListeningToScroll(); } );
|
||||
|
||||
imageEle.onload = function () {
|
||||
if ( imageEle.width > targetWidth ) {
|
||||
imageEle.width = targetWidth;
|
||||
}
|
||||
|
||||
viewer.profileEnd( pid );
|
||||
viewer.updateControls();
|
||||
};
|
||||
|
||||
viewer.profileEnd( mdpid );
|
||||
|
||||
pid = viewer.profileStart( 'image-load', {
|
||||
width: imageData.width,
|
||||
height: imageData.height,
|
||||
fileSize: imageData.size
|
||||
}, imageData.mimeType );
|
||||
|
||||
imageEle.src = imageData.getThumbUrl( requestedWidth ) || imageData.url;
|
||||
viewer.loadAndSetImage( viewer.lightbox.iface, imageData, targetWidth, requestedWidth, 'image-load' );
|
||||
|
||||
viewer.lightbox.iface.$imageDiv.removeClass( 'empty' );
|
||||
viewer.lightbox.iface.replaceImageWith( imageEle );
|
||||
viewer.setImageInfo( image, imageData, repoData );
|
||||
} );
|
||||
|
||||
|
|
|
@ -461,25 +461,72 @@
|
|||
ui.attach( '#qunit-fixture' );
|
||||
|
||||
// Fake viewport dimensions, width/height == 2.0, we are limited by height
|
||||
ui.$imageWrapper.height(200);
|
||||
ui.$imageWrapper.width(400);
|
||||
ui.$imageWrapper.height( 200 );
|
||||
ui.$imageWrapper.width( 400 );
|
||||
|
||||
widths = viewer.getImageSizeApiArgs(ui);
|
||||
widths = viewer.getImageSizeApiArgs( ui );
|
||||
|
||||
assert.strictEqual(widths.target, 150/100*200, 'Correct target width was computed.');
|
||||
assert.strictEqual(widths.requested, 320 * $.devicePixelRatio(), 'Correct requested width was computed.');
|
||||
assert.strictEqual( widths.target, 150/100*200, 'Correct target width was computed.' );
|
||||
assert.strictEqual( widths.requested, 320 * $.devicePixelRatio(), 'Correct requested width was computed.' );
|
||||
|
||||
// Fake viewport dimensions, width/height == 1.0, we are limited by width
|
||||
ui.$imageWrapper.height(600);
|
||||
ui.$imageWrapper.width(600);
|
||||
ui.$imageWrapper.height( 600 );
|
||||
ui.$imageWrapper.width( 600 );
|
||||
|
||||
widths = viewer.getImageSizeApiArgs(ui);
|
||||
widths = viewer.getImageSizeApiArgs( ui );
|
||||
|
||||
assert.strictEqual(widths.target, 600, 'Correct target width was computed.');
|
||||
assert.strictEqual(widths.requested, 640 * $.devicePixelRatio(), 'Correct requested width was computed.');
|
||||
assert.strictEqual( widths.target, 600, 'Correct target width was computed.' );
|
||||
assert.strictEqual( widths.requested, 640 * $.devicePixelRatio(), 'Correct requested width was computed.' );
|
||||
|
||||
ui.unattach();
|
||||
} );
|
||||
|
||||
QUnit.asyncTest( 'loadAndSetImage(): Basic load', 9, function ( assert ) {
|
||||
var targetWidth,
|
||||
requestedWidth,
|
||||
profileEvent,
|
||||
pid = 4321,
|
||||
viewer = new mw.MultimediaViewer(),
|
||||
ui = new mw.LightboxInterface(),
|
||||
size = 120,
|
||||
width = 10,
|
||||
height = 11,
|
||||
imageUrl = 'http://en.wikipedia.org/w/skins/vector/images/search-ltr.png',
|
||||
imageData = new mw.mmv.model.Image(
|
||||
mw.Title.newFromText( 'File:Foobar.pdf.jpg' ),
|
||||
size, width, height, 'image/jpeg',
|
||||
imageUrl,
|
||||
'http://example.com',
|
||||
'example', 'tester', '2013-11-10', '2013-11-09', 'Blah blah blah',
|
||||
'A person', 'Another person', 'CC-BY-SA-3.0', 0, 0
|
||||
);
|
||||
|
||||
// Assert funtions are called with correct data
|
||||
viewer.profileStart = function ( type, imgSize, fileType ) {
|
||||
assert.strictEqual( type, profileEvent, 'Correct event type for profile start.' );
|
||||
assert.strictEqual( imgSize.width, width, 'Correct width for profile start.' );
|
||||
assert.strictEqual( imgSize.height, height, 'Correct height for profile start.' );
|
||||
assert.strictEqual( imgSize.fileSize, size, 'Correct fileSize for profile start.' );
|
||||
assert.strictEqual( fileType, 'image/jpeg', 'Correct fileType for profile start.' );
|
||||
|
||||
return pid;
|
||||
};
|
||||
viewer.profileEnd = function ( id ) {
|
||||
assert.strictEqual( id, pid, 'Correct pid to end profiling. Image loaded correctly.' );
|
||||
QUnit.start();
|
||||
};
|
||||
ui.replaceImageWith = function ( image ) {
|
||||
assert.strictEqual( image.src, imageUrl, 'Image to replace has correct "src" attribute.' );
|
||||
assert.strictEqual( image.width, targetWidth, 'Image to replace has correct "width" attribute.' );
|
||||
};
|
||||
viewer.updateControls = function () {
|
||||
assert.ok( true, 'Controls updated.' );
|
||||
};
|
||||
|
||||
// Test case when image loaded is bigger than current area
|
||||
targetWidth = 8; // Current area < imageData.width
|
||||
requestedWidth = 640;
|
||||
profileEvent = 'image-load';
|
||||
viewer.loadAndSetImage( ui, imageData, targetWidth, requestedWidth, profileEvent );
|
||||
} );
|
||||
}( mediaWiki, jQuery ) );
|
||||
|
|
Loading…
Reference in a new issue