mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/MultimediaViewer
synced 2024-12-19 03:11:57 +00:00
2156f3f485
This is an old library that is broken in Chrome 61. Rather than updating it we can just use $(window).scrollTop/Left which works in all the browsers we currently support. Fix MPSP.toggle to return a promise, instead of a deferred (although this return value is not used yet). Bug: T173618 Change-Id: Iaec56debbb808bd95cf65c1ebfe22bdf0116da68
564 lines
20 KiB
JavaScript
564 lines
20 KiB
JavaScript
( function ( mw, $ ) {
|
|
QUnit.module( 'mmv.bootstrap', QUnit.newMwEnvironment( {
|
|
setup: function () {
|
|
mw.config.set( 'wgMediaViewer', true );
|
|
mw.config.set( 'wgMediaViewerOnClick', true );
|
|
this.sandbox.stub( mw.user, 'isAnon' ).returns( false );
|
|
}
|
|
} ) );
|
|
|
|
function createGallery( imageSrc, caption ) {
|
|
var $div = $( '<div>' ).addClass( 'gallery' ).appendTo( '#qunit-fixture' ),
|
|
$galleryBox = $( '<div>' ).addClass( 'gallerybox' ).appendTo( $div ),
|
|
$thumbwrap = $( '<div>' ).addClass( 'thumb' ).appendTo( $galleryBox ),
|
|
$link = $( '<a>' ).addClass( 'image' ).appendTo( $thumbwrap );
|
|
|
|
$( '<img>' ).attr( 'src', ( imageSrc || 'thumb.jpg' ) ).appendTo( $link );
|
|
$( '<div>' ).addClass( 'gallerytext' ).text( caption || 'Foobar' ).appendTo( $galleryBox );
|
|
|
|
return $div;
|
|
}
|
|
|
|
function createThumb( imageSrc, caption, alt ) {
|
|
var $div = $( '<div>' ).addClass( 'thumb' ).appendTo( '#qunit-fixture' ),
|
|
$link = $( '<a>' ).addClass( 'image' ).appendTo( $div );
|
|
|
|
$( '<div>' ).addClass( 'thumbcaption' ).appendTo( $div ).text( caption );
|
|
$( '<img>' ).attr( 'src', ( imageSrc || 'thumb.jpg' ) ).attr( 'alt', alt ).appendTo( $link );
|
|
|
|
return $div;
|
|
}
|
|
|
|
function createNormal( imageSrc, caption ) {
|
|
var $link = $( '<a>' ).prop( 'title', caption ).addClass( 'image' ).appendTo( '#qunit-fixture' );
|
|
$( '<img>' ).prop( 'src', ( imageSrc || 'thumb.jpg' ) ).appendTo( $link );
|
|
return $link;
|
|
}
|
|
|
|
function createMultipleImage( images ) {
|
|
var i, $div, $thumbimage, $link,
|
|
$contain = $( '<div>' ).addClass( 'thumb' ),
|
|
$thumbinner = $( '<div>' ).addClass( 'thumbinner' ).appendTo( $contain );
|
|
for ( i = 0; i < images.length; ++i ) {
|
|
$div = $( '<div>' ).appendTo( $thumbinner );
|
|
$thumbimage = $( '<div>' ).addClass( 'thumbimage' ).appendTo( $div );
|
|
$link = $( '<a>' ).addClass( 'image' ).appendTo( $thumbimage );
|
|
$( '<img>' ).prop( 'src', images[ i ][ 0 ] ).appendTo( $link );
|
|
$( '<div>' ).addClass( 'thumbcaption' ).text( images[ i ][ 1 ] ).appendTo( $div );
|
|
}
|
|
return $contain;
|
|
}
|
|
|
|
function createBootstrap( viewer ) {
|
|
var bootstrap = new mw.mmv.MultimediaViewerBootstrap();
|
|
|
|
bootstrap.processThumbs( $( '#qunit-fixture' ) );
|
|
|
|
// MultimediaViewerBootstrap.ensureEventHandlersAreSetUp() is a weird workaround for gadget bugs.
|
|
// MediaViewer should work without it, and so should the tests.
|
|
bootstrap.ensureEventHandlersAreSetUp = $.noop;
|
|
|
|
bootstrap.getViewer = function () {
|
|
return viewer || { initWithThumbs: $.noop, hash: $.noop };
|
|
};
|
|
|
|
return bootstrap;
|
|
}
|
|
|
|
function hashTest( prefix, bootstrap, assert ) {
|
|
var hash = prefix + '/foo',
|
|
callCount = 0;
|
|
|
|
bootstrap.loadViewer = function () {
|
|
callCount++;
|
|
return $.Deferred().reject();
|
|
};
|
|
|
|
// Hijack loadViewer, which will return a promise that we'll have to
|
|
// wait for if we want to see these tests through
|
|
mw.mmv.testHelpers.asyncMethod( bootstrap, 'loadViewer' );
|
|
|
|
bootstrap.setupEventHandlers();
|
|
|
|
// invalid hash, should not trigger MMV load
|
|
window.location.hash = 'Foo';
|
|
|
|
// actual hash we want to test for, should trigger MMV load
|
|
// use setTimeout to add new hash change to end of the call stack,
|
|
// ensuring that event handlers for our previous change can execute
|
|
// without us interfering with another immediate change
|
|
setTimeout( function () {
|
|
window.location.hash = hash;
|
|
} );
|
|
|
|
return mw.mmv.testHelpers.waitForAsync().then( function () {
|
|
assert.ok( callCount === 1, 'Viewer should be loaded once' );
|
|
bootstrap.cleanupEventHandlers();
|
|
window.location.hash = '';
|
|
} );
|
|
}
|
|
|
|
QUnit.test( 'Promise does not hang on ResourceLoader errors', function ( assert ) {
|
|
var bootstrap,
|
|
errorMessage = 'loading failed',
|
|
done = assert.async();
|
|
|
|
this.sandbox.stub( mw.loader, 'using' )
|
|
.callsArgWith( 2, new Error( errorMessage, [ 'mmv' ] ) )
|
|
.withArgs( 'mediawiki.notification' ).returns( $.Deferred().reject() ); // needed for mw.notify
|
|
|
|
bootstrap = createBootstrap();
|
|
this.sandbox.stub( bootstrap, 'setupOverlay' );
|
|
this.sandbox.stub( bootstrap, 'cleanupOverlay' );
|
|
|
|
bootstrap.loadViewer( true ).fail( function ( message ) {
|
|
assert.ok( bootstrap.setupOverlay.called, 'Overlay was set up' );
|
|
assert.ok( bootstrap.cleanupOverlay.called, 'Overlay was cleaned up' );
|
|
assert.strictEqual( message, errorMessage, 'promise is rejected with the error message when loading fails' );
|
|
done();
|
|
} );
|
|
} );
|
|
|
|
QUnit.test( 'Clicks are not captured once the loading fails', function ( assert ) {
|
|
var event, returnValue,
|
|
bootstrap = new mw.mmv.MultimediaViewerBootstrap(),
|
|
clock = this.sandbox.useFakeTimers();
|
|
|
|
this.sandbox.stub( mw.loader, 'using' )
|
|
.callsArgWith( 2, new Error( 'loading failed', [ 'mmv' ] ) )
|
|
.withArgs( 'mediawiki.notification' ).returns( $.Deferred().reject() ); // needed for mw.notify
|
|
bootstrap.ensureEventHandlersAreSetUp = $.noop;
|
|
|
|
// trigger first click, which will cause MMV to be loaded (which we've
|
|
// set up to fail)
|
|
event = new $.Event( 'click', { button: 0, which: 1 } );
|
|
returnValue = bootstrap.click( {}, event, 'foo' );
|
|
clock.tick( 10 );
|
|
assert.ok( event.isDefaultPrevented(), 'First click is caught' );
|
|
assert.strictEqual( returnValue, false, 'First click is caught' );
|
|
|
|
// wait until MMW is loaded (or failed to load, in this case) before we
|
|
// trigger another click - which should then not be caught
|
|
event = new $.Event( 'click', { button: 0, which: 1 } );
|
|
returnValue = bootstrap.click( {}, event, 'foo' );
|
|
clock.tick( 10 );
|
|
assert.ok( !event.isDefaultPrevented(), 'Click after loading failure is not caught' );
|
|
assert.notStrictEqual( returnValue, false, 'Click after loading failure is not caught' );
|
|
|
|
clock.restore();
|
|
} );
|
|
|
|
QUnit.test( 'Check viewer invoked when clicking on valid image links', function ( assert ) {
|
|
// TODO: Is <div class="gallery"><span class="image"><img/></span></div> valid ???
|
|
var div, link, link2, link3, link4, link5, bootstrap,
|
|
viewer = { initWithThumbs: $.noop, loadImageByTitle: this.sandbox.stub() },
|
|
clock = this.sandbox.useFakeTimers();
|
|
|
|
// Create gallery with valid link image
|
|
div = createGallery();
|
|
link = div.find( 'a.image' );
|
|
|
|
// Valid isolated thumbnail
|
|
link2 = $( '<a>' ).addClass( 'image' ).appendTo( '#qunit-fixture' );
|
|
$( '<img>' ).attr( 'src', 'thumb2.jpg' ).appendTo( link2 );
|
|
|
|
// Non-valid fragment
|
|
link3 = $( '<a>' ).addClass( 'noImage' ).appendTo( div );
|
|
$( '<img>' ).attr( 'src', 'thumb3.jpg' ).appendTo( link3 );
|
|
|
|
$( '<div>' ).addClass( 'fullMedia' ).appendTo( div );
|
|
$( '<img>' ).attr( 'src', 'thumb4.jpg' ).appendTo(
|
|
$( '<a>' )
|
|
.appendTo(
|
|
$( '<div>' )
|
|
.attr( 'id', 'file' )
|
|
.appendTo( '#qunit-fixture' )
|
|
)
|
|
);
|
|
|
|
// Create a new bootstrap object to trigger the DOM scan, etc.
|
|
bootstrap = createBootstrap( viewer );
|
|
this.sandbox.stub( bootstrap, 'setupOverlay' );
|
|
|
|
link4 = $( '.fullMedia .mw-mmv-view-expanded' );
|
|
assert.ok( link4.length, 'Link for viewing expanded file was set up.' );
|
|
|
|
link5 = $( '.fullMedia .mw-mmv-view-config' );
|
|
assert.ok( link5.length, 'Link for opening enable/disable configuration was set up.' );
|
|
|
|
// Click on valid link
|
|
link.trigger( { type: 'click', which: 1 } );
|
|
clock.tick( 10 );
|
|
assert.ok( bootstrap.setupOverlay.callCount === 1, 'setupOverlay was called' );
|
|
assert.ok( viewer.loadImageByTitle.callCount === 1, 'loadImageByTitle was called' );
|
|
|
|
// Click on valid link
|
|
link2.trigger( { type: 'click', which: 1 } );
|
|
clock.tick( 10 );
|
|
assert.ok( bootstrap.setupOverlay.callCount === 2, 'setupOverlay was called' );
|
|
assert.ok( viewer.loadImageByTitle.callCount === 2, 'loadImageByTitle was called' );
|
|
|
|
// Click on valid link
|
|
link4.trigger( { type: 'click', which: 1 } );
|
|
clock.tick( 10 );
|
|
assert.ok( bootstrap.setupOverlay.callCount === 3, 'setupOverlay was called' );
|
|
assert.ok( viewer.loadImageByTitle.callCount === 3, 'loadImageByTitle was called' );
|
|
|
|
// Click on valid link even when preference says not to
|
|
mw.config.set( 'wgMediaViewerOnClick', false );
|
|
link4.trigger( { type: 'click', which: 1 } );
|
|
clock.tick( 10 );
|
|
mw.config.set( 'wgMediaViewerOnClick', true );
|
|
assert.ok( bootstrap.setupOverlay.callCount === 4, 'setupOverlay was called' );
|
|
assert.ok( viewer.loadImageByTitle.callCount === 4, 'loadImageByTitle was called' );
|
|
|
|
// @todo comment that above clicks should result in call, below clicks should not
|
|
|
|
// Click on non-valid link
|
|
link3.trigger( { type: 'click', which: 1 } );
|
|
clock.tick( 10 );
|
|
assert.ok( bootstrap.setupOverlay.callCount === 4, 'setupOverlay was not called' );
|
|
assert.ok( viewer.loadImageByTitle.callCount === 4, 'loadImageByTitle was not called' );
|
|
|
|
// Click on valid links with preference off
|
|
mw.config.set( 'wgMediaViewerOnClick', false );
|
|
link.trigger( { type: 'click', which: 1 } );
|
|
link2.trigger( { type: 'click', which: 1 } );
|
|
clock.tick( 10 );
|
|
assert.ok( bootstrap.setupOverlay.callCount === 4, 'setupOverlay was not called' );
|
|
assert.ok( viewer.loadImageByTitle.callCount === 4, 'loadImageByTitle was not called' );
|
|
|
|
clock.restore();
|
|
} );
|
|
|
|
QUnit.test( 'Skip images with invalid extensions', function ( assert ) {
|
|
var div, link,
|
|
viewer = { initWithThumbs: $.noop, loadImageByTitle: this.sandbox.stub() },
|
|
clock = this.sandbox.useFakeTimers();
|
|
|
|
// Create gallery with image that has invalid name extension
|
|
div = createGallery( 'thumb.badext' );
|
|
link = div.find( 'a.image' );
|
|
|
|
// Create a new bootstrap object to trigger the DOM scan, etc.
|
|
createBootstrap( viewer );
|
|
|
|
// Click on valid link with wrong image extension
|
|
link.trigger( { type: 'click', which: 1 } );
|
|
clock.tick( 10 );
|
|
|
|
assert.ok( !viewer.loadImageByTitle.called, 'Image should not be loaded' );
|
|
|
|
clock.restore();
|
|
} );
|
|
|
|
QUnit.test( 'Accept only left clicks without modifier keys, skip the rest', function ( assert ) {
|
|
var $div, $link, bootstrap,
|
|
viewer = { initWithThumbs: $.noop, loadImageByTitle: this.sandbox.stub() },
|
|
clock = this.sandbox.useFakeTimers();
|
|
|
|
// Create gallery with image that has valid name extension
|
|
$div = createGallery();
|
|
|
|
// Create a new bootstrap object to trigger the DOM scan, etc.
|
|
bootstrap = createBootstrap( viewer );
|
|
this.sandbox.stub( bootstrap, 'setupOverlay' );
|
|
|
|
$link = $div.find( 'a.image' );
|
|
|
|
// Handle valid left click, it should try to load the image
|
|
$link.trigger( { type: 'click', which: 1 } );
|
|
clock.tick( 10 );
|
|
assert.ok( bootstrap.setupOverlay.callCount === 1, 'Overlay was set up' );
|
|
assert.ok( viewer.loadImageByTitle.callCount === 1, 'Image was loaded' );
|
|
|
|
// Skip Ctrl-left-click, no image is loaded
|
|
$link.trigger( { type: 'click', which: 1, ctrlKey: true } );
|
|
clock.tick( 10 );
|
|
assert.ok( bootstrap.setupOverlay.callCount === 1, 'Overlay was not set up' );
|
|
assert.ok( viewer.loadImageByTitle.callCount === 1, 'Image was not loaded' );
|
|
|
|
// Skip invalid right click, no image is loaded
|
|
$link.trigger( { type: 'click', which: 2 } );
|
|
clock.tick( 10 );
|
|
assert.ok( bootstrap.setupOverlay.callCount === 1, 'Overlay was not set up' );
|
|
assert.ok( viewer.loadImageByTitle.callCount === 1, 'Image was not loaded' );
|
|
|
|
clock.restore();
|
|
} );
|
|
|
|
QUnit.test( 'Ensure that the correct title is loaded when clicking', function ( assert ) {
|
|
var bootstrap,
|
|
viewer = { initWithThumbs: $.noop, loadImageByTitle: this.sandbox.stub() },
|
|
$div = createGallery( 'foo.jpg' ),
|
|
$link = $div.find( 'a.image' ),
|
|
clock = this.sandbox.useFakeTimers();
|
|
|
|
// Create a new bootstrap object to trigger the DOM scan, etc.
|
|
bootstrap = createBootstrap( viewer );
|
|
this.sandbox.stub( bootstrap, 'setupOverlay' );
|
|
|
|
$link.trigger( { type: 'click', which: 1 } );
|
|
clock.tick( 10 );
|
|
assert.ok( bootstrap.setupOverlay.called, 'Overlay was set up' );
|
|
assert.strictEqual( viewer.loadImageByTitle.firstCall.args[ 0 ].getPrefixedDb(), 'File:Foo.jpg', 'Titles are identical' );
|
|
|
|
clock.restore();
|
|
} );
|
|
|
|
QUnit.test( 'Validate new LightboxImage object has sane constructor parameters', function ( assert ) {
|
|
var bootstrap,
|
|
$div,
|
|
$link,
|
|
viewer = mw.mmv.testHelpers.getMultimediaViewer(),
|
|
fname = 'valid',
|
|
imgSrc = '/' + fname + '.jpg/300px-' + fname + '.jpg',
|
|
imgRegex = new RegExp( imgSrc + '$' ),
|
|
clock = this.sandbox.useFakeTimers();
|
|
|
|
$div = createThumb( imgSrc, 'Blah blah', 'meow' );
|
|
$link = $div.find( 'a.image' );
|
|
|
|
// Create a new bootstrap object to trigger the DOM scan, etc.
|
|
bootstrap = createBootstrap( viewer );
|
|
this.sandbox.stub( bootstrap, 'setupOverlay' );
|
|
this.sandbox.stub( viewer, 'createNewImage' );
|
|
viewer.loadImage = $.noop;
|
|
viewer.createNewImage = function ( fileLink, filePageLink, fileTitle, index, thumb, caption, alt ) {
|
|
var html = thumb.outerHTML;
|
|
|
|
assert.ok( fileLink.match( imgRegex ), 'Thumbnail URL used in creating new image object' );
|
|
assert.strictEqual( filePageLink, '', 'File page link is sane when creating new image object' );
|
|
assert.strictEqual( fileTitle.title, fname, 'Filename is correct when passed into new image constructor' );
|
|
assert.strictEqual( index, 0, 'The only image we created in the gallery is set at index 0 in the images array' );
|
|
assert.ok( html.indexOf( ' src="' + imgSrc + '"' ) > 0, 'The image element passed in contains the src=... we want.' );
|
|
assert.ok( html.indexOf( ' alt="meow"' ) > 0, 'The image element passed in contains the alt=... we want.' );
|
|
assert.strictEqual( caption, 'Blah blah', 'The caption passed in is correct' );
|
|
assert.strictEqual( alt, 'meow', 'The alt text passed in is correct' );
|
|
};
|
|
|
|
$link.trigger( { type: 'click', which: 1 } );
|
|
clock.tick( 10 );
|
|
assert.ok( bootstrap.setupOverlay.called, 'Overlay was set up' );
|
|
|
|
clock.reset();
|
|
} );
|
|
|
|
QUnit.test( 'Only load the viewer on a valid hash (modern browsers)', function ( assert ) {
|
|
var bootstrap;
|
|
|
|
window.location.hash = '';
|
|
|
|
bootstrap = createBootstrap();
|
|
|
|
return hashTest( '/media', bootstrap, assert );
|
|
} );
|
|
|
|
QUnit.test( 'Only load the viewer on a valid hash (old browsers)', function ( assert ) {
|
|
var bootstrap;
|
|
|
|
window.location.hash = '';
|
|
|
|
bootstrap = createBootstrap();
|
|
bootstrap.browserHistory = undefined;
|
|
|
|
return hashTest( '/media', bootstrap, assert );
|
|
} );
|
|
|
|
QUnit.test( 'Load the viewer on a legacy hash (modern browsers)', function ( assert ) {
|
|
var bootstrap;
|
|
|
|
window.location.hash = '';
|
|
|
|
bootstrap = createBootstrap();
|
|
|
|
return hashTest( 'mediaviewer', bootstrap, assert );
|
|
} );
|
|
|
|
QUnit.test( 'Load the viewer on a legacy hash (old browsers)', function ( assert ) {
|
|
var bootstrap;
|
|
|
|
window.location.hash = '';
|
|
|
|
bootstrap = createBootstrap();
|
|
bootstrap.browserHistory = undefined;
|
|
|
|
return hashTest( 'mediaviewer', bootstrap, assert );
|
|
} );
|
|
|
|
QUnit.test( 'Overlay is set up on hash change', function ( assert ) {
|
|
var bootstrap;
|
|
|
|
window.location.hash = '#/media/foo';
|
|
|
|
bootstrap = createBootstrap();
|
|
this.sandbox.stub( bootstrap, 'setupOverlay' );
|
|
|
|
bootstrap.hash();
|
|
|
|
assert.ok( bootstrap.setupOverlay.called, 'Overlay is set up' );
|
|
} );
|
|
|
|
QUnit.test( 'Overlay is not set up on an irrelevant hash change', function ( assert ) {
|
|
var bootstrap;
|
|
|
|
window.location.hash = '#foo';
|
|
|
|
bootstrap = createBootstrap();
|
|
this.sandbox.stub( bootstrap, 'setupOverlay' );
|
|
bootstrap.loadViewer();
|
|
bootstrap.setupOverlay.reset();
|
|
|
|
bootstrap.hash();
|
|
|
|
assert.ok( !bootstrap.setupOverlay.called, 'Overlay is not set up' );
|
|
} );
|
|
|
|
QUnit.test( 'internalHashChange', function ( assert ) {
|
|
var bootstrap = createBootstrap(),
|
|
hash = '#/media/foo',
|
|
callCount = 0,
|
|
clock = this.sandbox.useFakeTimers();
|
|
|
|
window.location.hash = '';
|
|
|
|
bootstrap.loadViewer = function () {
|
|
callCount++;
|
|
return $.Deferred().reject();
|
|
};
|
|
|
|
bootstrap.setupEventHandlers();
|
|
|
|
bootstrap.internalHashChange( { hash: hash } );
|
|
clock.tick( 10 );
|
|
|
|
assert.ok( callCount === 0, 'Viewer should not be loaded' );
|
|
assert.strictEqual( window.location.hash, hash, 'Window\'s hash has been updated correctly' );
|
|
|
|
bootstrap.cleanupEventHandlers();
|
|
window.location.hash = '';
|
|
clock.restore();
|
|
} );
|
|
|
|
QUnit.test( 'internalHashChange (legacy)', function ( assert ) {
|
|
var bootstrap = createBootstrap(),
|
|
hash = '#mediaviewer/foo',
|
|
callCount = 0,
|
|
clock = this.sandbox.useFakeTimers();
|
|
|
|
window.location.hash = '';
|
|
|
|
bootstrap.loadViewer = function () {
|
|
callCount++;
|
|
return $.Deferred().reject();
|
|
};
|
|
|
|
bootstrap.setupEventHandlers();
|
|
|
|
bootstrap.internalHashChange( { hash: hash } );
|
|
clock.tick( 10 );
|
|
|
|
assert.ok( callCount === 0, 'Viewer should not be loaded' );
|
|
assert.strictEqual( window.location.hash, hash, 'Window\'s hash has been updated correctly' );
|
|
|
|
bootstrap.cleanupEventHandlers();
|
|
window.location.hash = '';
|
|
clock.restore();
|
|
} );
|
|
|
|
QUnit.test( 'Restoring article scroll position', function ( assert ) {
|
|
var stubbedScrollTop,
|
|
bootstrap = createBootstrap(),
|
|
$window = $( window ),
|
|
done = assert.async();
|
|
|
|
this.sandbox.stub( $.fn, 'scrollTop', function ( scrollTop ) {
|
|
if ( scrollTop !== undefined ) {
|
|
stubbedScrollTop = scrollTop;
|
|
return this;
|
|
} else {
|
|
return stubbedScrollTop;
|
|
}
|
|
} );
|
|
|
|
$window.scrollTop( 50 );
|
|
bootstrap.setupOverlay();
|
|
// Calling this a second time because it can happen in history navigation context
|
|
bootstrap.setupOverlay();
|
|
// Clear scrollTop to check it is restored
|
|
$window.scrollTop( 0 );
|
|
bootstrap.cleanupOverlay();
|
|
|
|
// Scroll restoration is on a setTimeout
|
|
setTimeout( function () {
|
|
assert.strictEqual( $( window ).scrollTop(), 50, 'Scroll is correctly reset to original top position' );
|
|
done();
|
|
} );
|
|
} );
|
|
|
|
QUnit.test( 'Preload JS/CSS dependencies on thumb hover', function ( assert ) {
|
|
var $div, bootstrap,
|
|
clock = this.sandbox.useFakeTimers(),
|
|
viewer = { initWithThumbs: $.noop };
|
|
|
|
// Create gallery with image that has valid name extension
|
|
$div = createThumb();
|
|
|
|
// Create a new bootstrap object to trigger the DOM scan, etc.
|
|
bootstrap = createBootstrap( viewer );
|
|
|
|
this.sandbox.stub( mw.loader, 'load' );
|
|
|
|
$div.mouseenter();
|
|
clock.tick( bootstrap.hoverWaitDuration - 50 );
|
|
$div.mouseleave();
|
|
|
|
assert.ok( !mw.loader.load.called, 'Dependencies should not be preloaded if the thumb is not hovered long enough' );
|
|
|
|
$div.mouseenter();
|
|
clock.tick( bootstrap.hoverWaitDuration + 50 );
|
|
$div.mouseleave();
|
|
|
|
assert.ok( mw.loader.load.called, 'Dependencies should be preloaded if the thumb is hovered long enough' );
|
|
|
|
clock.restore();
|
|
} );
|
|
|
|
QUnit.test( 'isAllowedThumb', function ( assert ) {
|
|
var $container = $( '<div>' ),
|
|
$thumb = $( '<img>' ).appendTo( $container ),
|
|
bootstrap = createBootstrap();
|
|
|
|
assert.ok( bootstrap.isAllowedThumb( $thumb ), 'Normal image in a div is allowed.' );
|
|
|
|
$container.addClass( 'metadata' );
|
|
assert.strictEqual( bootstrap.isAllowedThumb( $thumb ), false, 'Image in a metadata container is disallowed.' );
|
|
|
|
$container.prop( 'class', '' );
|
|
$container.addClass( 'noviewer' );
|
|
assert.strictEqual( bootstrap.isAllowedThumb( $thumb ), false, 'Image in a noviewer container is disallowed.' );
|
|
|
|
$container.prop( 'class', '' );
|
|
$container.addClass( 'noarticletext' );
|
|
assert.strictEqual( bootstrap.isAllowedThumb( $thumb ), false, 'Image in an empty article is disallowed.' );
|
|
|
|
$container.prop( 'class', '' );
|
|
$thumb.addClass( 'noviewer' );
|
|
assert.strictEqual( bootstrap.isAllowedThumb( $thumb ), false, 'Image with a noviewer class is disallowed.' );
|
|
} );
|
|
|
|
QUnit.test( 'findCaption', function ( assert ) {
|
|
var gallery = createGallery( 'foo.jpg', 'Baz' ),
|
|
thumb = createThumb( 'foo.jpg', 'Quuuuux' ),
|
|
link = createNormal( 'foo.jpg', 'Foobar' ),
|
|
multiple = createMultipleImage( [ [ 'foo.jpg', 'Image #1' ], [ 'bar.jpg', 'Image #2' ],
|
|
[ 'foobar.jpg', 'Image #3' ] ] ),
|
|
bootstrap = createBootstrap();
|
|
|
|
assert.strictEqual( bootstrap.findCaption( gallery.find( '.thumb' ), gallery.find( 'a.image' ) ), 'Baz', 'A gallery caption is found.' );
|
|
assert.strictEqual( bootstrap.findCaption( thumb, thumb.find( 'a.image' ) ), 'Quuuuux', 'A thumbnail caption is found.' );
|
|
assert.strictEqual( bootstrap.findCaption( $(), link ), 'Foobar', 'The caption is found even if the image is not a thumbnail.' );
|
|
assert.strictEqual( bootstrap.findCaption( multiple, multiple.find( 'img[src="bar.jpg"]' ).closest( 'a' ) ), 'Image #2', 'The caption is found in {{Multiple image}}.' );
|
|
} );
|
|
}( mediaWiki, jQuery ) );
|