Hide the controls after some time when in fullscreen mode

Also removes side-effects from several tests

Change-Id: Ifdc978f56f8c4caafadc8b192756645a9378f58a
Mingle: https://wikimedia.mingle.thoughtworks.com/projects/multimedia/cards/150
This commit is contained in:
Gilles Dubuc 2014-02-03 12:23:31 +01:00
parent 923a117304
commit 3dd716a3f2
7 changed files with 340 additions and 63 deletions

View file

@ -362,17 +362,11 @@
};
MMVP.updateControls = function () {
var ui = this.ui,
prevNextTop = ( ( ui.$imageWrapper.height() / 2 ) - 60 ) + 'px';
var numImages = this.lightbox.images ? this.lightbox.images.length : 0,
showNextButton = this.lightbox.currentIndex < (numImages - 1),
showPreviousButton = this.lightbox.currentIndex > 0;
ui.$postDiv.css( 'top', ui.$imageWrapper.height() );
ui.$nextButton.add( ui.$prevButton ).css( {
top: prevNextTop
} );
ui.$nextButton.toggleClass( 'disabled', this.lightbox.currentIndex >= ( ( this.lightbox.images ? this.lightbox.images.length : 0 ) - 1 ) );
ui.$prevButton.toggleClass( 'disabled', this.lightbox.currentIndex <= 0 );
this.ui.updateControls( showNextButton, showPreviousButton );
};
MMVP.registerLogging = function () {
@ -921,9 +915,7 @@
MultiLightbox = window.MultiLightbox;
lightboxHooks = window.lightboxHooks;
var viewer = new MultimediaViewer();
mw.mediaViewer = viewer;
mw.mediaViewer = new MultimediaViewer();
handleHash();
window.addEventListener( 'popstate', handleHash );

View file

@ -124,6 +124,11 @@
this.$postDiv.css( 'top', ( $( window ).height() - 83 ) + 'px' );
MLBInterface.prototype.attach.call( this, parentId );
// Buttons fading might not had been reset properly after a hard fullscreen exit
// This needs to happen after the parent attach() because the buttons need to be attached
// to the DOM for $.fn.stop() to work
this.stopButtonsFade();
};
LIP.unattach = function () {
@ -149,6 +154,11 @@
this.handleEvent( 'keydown', function( e ) { ui.keydown( e ); } );
// mousemove generates a ton of events, which is why we throttle it
this.handleEvent( 'mousemove.lip', $.throttle( 250, function( e ) {
ui.mousemove( e );
} ) );
MLBInterface.prototype.load.call( this, image );
};
@ -242,7 +252,7 @@
// and we aren't sure why, but it's not really necessary
// with the new interface anyway - it's basically fullscreen
// already!
this.$closeButton
this.$buttons = this.$closeButton
.add( this.$fullscreenButton )
.add( this.$nextButton )
.add( this.$prevButton )
@ -683,14 +693,27 @@
} );
};
LIP.enterFullscreen = function () {
MLBInterface.prototype.enterFullscreen.call( this );
this.viewer.resize( this );
};
LIP.fullscreenChange = function( e ) {
MLBInterface.prototype.fullscreenChange.call( this, e );
// Fullscreen change events can happen after unattach(), in which
// case we shouldn't do anything UI-related
if ( !this.currentlyAttached ) {
return;
}
LIP.exitFullscreen = function () {
MLBInterface.prototype.exitFullscreen.call( this );
this.viewer.resize( this );
if ( this.isFullscreen ) {
// When entering fullscreen without a mousemove, the browser
// still thinks that the cursor is where it was prior to entering
// fullscreen. I.e. on top of the fullscreen button
// Thus, we purposefully reset the saved position, so that
// the fade out really takes place (otherwise it's cancelled
// by updateControls which is called a few times when fullscreen opens)
this.mousePosition = { x: 0, y: 0 };
this.fadeOutButtons();
}
};
/**
@ -731,5 +754,117 @@
}
};
/**
* @method
* Handles mousemove events on the document
*/
LIP.mousemove = function ( e ) {
if ( e ) {
// Saving the mouse position is useful whenever we need to
// run LIP.mousemove manually, such as when going to the next/prev
// element
this.mousePosition = { x: e.pageX, y: e.pageY};
}
this.revealButtonsAndFadeIfNeeded();
};
/**
* @method
* Reveals all active buttons and schedule a fade out if needed
*/
LIP.revealButtonsAndFadeIfNeeded = function () {
// Only fullscreen mode sees its buttons fade out when not used
if ( !this.isFullscreen ) {
return;
}
if ( this.buttonsFadeTimeout ) {
clearTimeout( this.buttonsFadeTimeout );
}
// Stop ongoing animations and make sure the buttons that need to be displayed are displayed
this.stopButtonsFade();
// this.mousePosition can be empty, for instance when we enter fullscreen and haven't
// recorded a real mousemove event yet
if ( !this.mousePosition
|| !this.isAnyActiveButtonHovered( this.mousePosition.x, this.mousePosition.y ) ) {
this.fadeOutButtons();
}
};
/**
* @method
* Fades out the active buttons
*/
LIP.fadeOutButtons = function () {
var ui = this;
// We don't use animation chaining because delay() can't be stop()ed
this.buttonsFadeTimeout = setTimeout( function() {
ui.$buttons.not( '.disabled' ).animate( { opacity: 0 }, 1000 );
}, 1500 );
};
/**
* @method
* Stops the fading animation of the buttons and cancel any opacity value
*/
LIP.stopButtonsFade = function () {
this.$buttons
.stop( true )
.css( 'opacity', '' );
};
/**
* @method
* Checks if any active buttons are currently hovered, given a position
* @param {number} x The horizontal coordinate of the position
* @param {number} y The vertical coordinate of the position
* @return bool
*/
LIP.isAnyActiveButtonHovered = function ( x, y ) {
// We don't use mouseenter/mouseleave events because content is subject
// to change underneath the cursor, eg. when entering fullscreen or
// when going prev/next (the button can disappear when reaching ends)
var hovered = false;
this.$buttons.not( '.disabled' ).each( function( idx, e ) {
var $e = $( e ),
offset = $e.offset();
if ( y >= offset.top
&& y <= offset.top + $e.height()
&& x >= offset.left
&& x <= offset.left + $e.width() ) {
hovered = true;
}
} );
return hovered;
};
/**
* @method
* Updates the next and prev buttons
* @param bool showPrevButton Whether the prev button should be revealed or not
* @param bool showNextButton Whether the next button should be revealed or not
*/
LIP.updateControls = function ( showPrevButton, showNextButton ) {
var prevNextTop = ( ( this.$imageWrapper.height() / 2 ) - 60 ) + 'px';
this.$postDiv.css( 'top', this.$imageWrapper.height() );
this.$nextButton.add( this.$prevButton ).css( {
top: prevNextTop
} );
this.$nextButton.toggleClass( 'disabled', !showPrevButton );
this.$prevButton.toggleClass( 'disabled', !showNextButton );
this.revealButtonsAndFadeIfNeeded();
};
mw.LightboxInterface = LightboxInterface;
}( mediaWiki, jQuery, OO, window.LightboxInterface ) );

View file

@ -67,19 +67,6 @@
lbinterface.unattach();
}
} );
$( document ).on( 'jq-fullscreen-change', function ( e ) {
lbinterface.isFullscreen = e.fullscreen;
lightboxHooks.callAll( 'fullscreen', this, e.fullscreen );
if ( !lbinterface.fullscreenButtonJustPressed && !e.fullscreen ) {
// Close the interface all the way if the user pressed 'esc'
lbinterface.unattach();
} else if ( lbinterface.fullscreenButtonJustPressed ) {
lbinterface.fullscreenButtonJustPressed = false;
}
} );
}
LIP = LightboxInterface.prototype;
@ -106,15 +93,28 @@
* @param {string} [parentId] parent id where we want to attach the UI. Mainly for testing.
*/
LIP.attach = function ( parentId ) {
var lbinterface = this,
$parent;
// Re-appending the same content can have nasty side-effects
// Such as the browser leaving fullscreen mode if the fullscreened element is part of it
if ( this.currentlyAttached ) {
return;
}
var parent = $( parentId || document.body );
$( document ).on( 'jq-fullscreen-change.lip', function( e ) {
lbinterface.fullscreenChange( e );
} );
parent
$parent = $( parentId || document.body );
// Clean up fullscreen data because hard-existing fullscreen might have left
// jquery.fullscreen unable to remove the class and attribute, since $main wasn't
// attached to the DOM anymore at the time the jq-fullscreen-change event triggered
this.$main.data( 'isFullscreened', false ).removeClass( 'jq-fullscreened' );
this.isFullscreen = false;
$parent
.append(
this.$wrapper,
this.$overlay
@ -129,6 +129,8 @@
// TODO(aarcos): This is global and it breaks tests.
lightboxHooks.callAll( 'closeInterface', this );
$( document ).off( 'jq-fullscreen-change.lip' );
this.$wrapper.detach();
this.$overlay.detach();
@ -268,5 +270,18 @@
}
};
LIP.fullscreenChange = function ( e ) {
this.isFullscreen = e.fullscreen;
lightboxHooks.callAll( 'fullscreen', e.element, e.fullscreen );
if ( !this.fullscreenButtonJustPressed && !e.fullscreen ) {
// Close the interface all the way if the user pressed 'esc'
this.unattach();
} else if ( this.fullscreenButtonJustPressed ) {
this.fullscreenButtonJustPressed = false;
}
};
window.LightboxInterface = LightboxInterface;
}( jQuery ) );

View file

@ -1,7 +1,7 @@
( function ( mw, $ ) {
QUnit.module( 'multilightbox.interface', QUnit.newMwEnvironment() );
QUnit.test( 'Sanity test, object creation and ui construction', 6, function ( assert ) {
QUnit.test( 'Sanity test, object creation and ui construction', 9, function ( assert ) {
var lightbox = new window.LightboxInterface();
function checkIfUIAreasAttachedToDocument( inDocument ) {
@ -20,17 +20,10 @@
// UI areas should now be attached to the document.
checkIfUIAreasAttachedToDocument(1);
/*
* TODO(aarcos): We cannot test the section below because unattach()
* depends on global lightboxHooks that expect a mw.LightboxInterface object.
* Fix once this dependency is resolved.
// Unattach lightbox from document
//lightbox.unattach();
lightbox.unattach();
// UI areas not attached to the document anymore.
//checkIfUIAreasAttachedToDocument(0);
*/
checkIfUIAreasAttachedToDocument(0);
} );
QUnit.asyncTest( 'Check we are saving the resize listener', 2, function ( assert ) {
@ -56,7 +49,7 @@
lightbox.load(img);
} );
QUnit.test( 'Fullscreen mode', 4, function ( assert ) {
QUnit.test( 'Fullscreen mode', 6, function ( assert ) {
var lightbox = new window.LightboxInterface(),
oldFnEnterFullscreen = $.fn.enterFullscreen,
oldFnExitFullscreen = $.fn.exitFullscreen;
@ -84,6 +77,24 @@
'Fullscreened area doesn\'t have the fullscreen class anymore');
assert.strictEqual( lightbox.isFullscreen , false, 'Lightbox knows it\'s not in fullscreen mode');
// Entering fullscreen
lightbox.$fullscreenButton.click();
// Hard-exiting fullscreen
lightbox.$closeButton.click();
// Re-attach after hard-exit
lightbox.attach( '#qunit-fixture' );
assert.strictEqual( lightbox.$main.hasClass( 'jq-fullscreened' ) , false,
'Fullscreened area doesn\'t have the fullscreen class anymore');
assert.strictEqual( lightbox.isFullscreen , false, 'Lightbox knows it\'s not in fullscreen mode');
// Unattach lightbox from document
lightbox.unattach();
$.fn.enterFullscreen = oldFnEnterFullscreen;
$.fn.exitFullscreen = oldFnExitFullscreen;
} );

View file

@ -44,7 +44,7 @@
// Check that the close button on the lightbox still follow the spec (being visible right away)
assert.strictEqual( $( '#qunit-fixture .mlb-close' ).length, 1, 'There should be a close button' );
assert.strictEqual( $( '#qunit-fixture .mlb-close' ).is(':visible'), true, 'The close button should be visible' );
assert.ok( $( '#qunit-fixture .mlb-close' ).is(':visible'), 'The close button should be visible' );
// Unattach lightbox from document
lightbox.unattach();
@ -64,10 +64,10 @@
}
for ( i = 0; i < thingsShouldHaveEmptyClass.length; i++ ) {
assert.strictEqual( lightbox[thingsShouldHaveEmptyClass[i]].hasClass( 'empty' ), true, 'We successfully applied the empty class to the ' + thingsShouldHaveEmptyClass[i] + ' element' );
assert.ok( lightbox[thingsShouldHaveEmptyClass[i]].hasClass( 'empty' ), 'We successfully applied the empty class to the ' + thingsShouldHaveEmptyClass[i] + ' element' );
}
assert.strictEqual( lightbox.$dragIcon.hasClass( 'pointing-down' ), false, 'We successfully reset the chevron' );
assert.ok( !lightbox.$dragIcon.hasClass( 'pointing-down' ), 'We successfully reset the chevron' );
} );
QUnit.test( 'Handler registration and clearance work OK', 2, function ( assert ) {
@ -121,10 +121,12 @@
);
} );
QUnit.test( 'Fullscreen mode', 3, function ( assert ) {
QUnit.test( 'Fullscreen mode', 8, function ( assert ) {
var lightbox = new mw.LightboxInterface( mw.mediaViewer ),
oldFnEnterFullscreen = $.fn.enterFullscreen,
oldFnExitFullscreen = $.fn.exitFullscreen;
oldFnExitFullscreen = $.fn.exitFullscreen,
oldRevealButtonsAndFadeIfNeeded,
buttonOffset;
// Since we don't want these tests to really open fullscreen
// which is subject to user security confirmation,
@ -137,17 +139,43 @@
lightbox.viewer.ui = lightbox;
lightbox.viewer.lightbox = lightbox;
assert.strictEqual( lightbox.$imageMetadata.is( ':visible' ) , true, 'Image metadata is visible' );
assert.ok( !lightbox.isFullscreen, 'Lightbox knows that it\'s not in fullscreen mode' );
assert.ok( lightbox.$imageMetadata.is( ':visible' ), 'Image metadata is visible' );
// Entering fullscreen
lightbox.fadeOutButtons = function() {
assert.ok( true, 'Opening fullscreen triggers a fadeout' );
};
// Pretend that the mouse cursor is on top of the button
buttonOffset = lightbox.$fullscreenButton.offset();
lightbox.mousePosition = { x: buttonOffset.left, y: buttonOffset.top };
// Enter fullscreen
lightbox.$fullscreenButton.click();
assert.strictEqual( lightbox.$imageMetadata.is( ':visible' ) , false, 'Image metadata is hidden' );
lightbox.fadeOutButtons = $.noop;
assert.ok( lightbox.isFullscreen, 'Lightbox knows that it\'s in fullscreen mode' );
// Exiting fullscreen
oldRevealButtonsAndFadeIfNeeded = lightbox.revealButtonsAndFadeIfNeeded;
lightbox.revealButtonsAndFadeIfNeeded = function() {
assert.ok( true, 'Moving the cursor triggers a reveal + fade' );
oldRevealButtonsAndFadeIfNeeded.call( this );
};
// Pretend that the mouse cursor moved to the top-left corner
lightbox.mousemove( { pageX: 0, pageY: 0 } );
lightbox.revealButtonsAndFadeIfNeeded = $.noop;
assert.ok( !lightbox.$imageMetadata.is( ':visible' ), 'Image metadata is hidden' );
// Exit fullscreen
lightbox.$fullscreenButton.click();
assert.strictEqual( lightbox.$imageMetadata.is( ':visible' ) , true, 'Image metadata is visible' );
assert.ok( lightbox.$imageMetadata.is( ':visible' ), 'Image metadata is visible' );
assert.ok( !lightbox.isFullscreen, 'Lightbox knows that it\'s not in fullscreen mode' );
// Unattach lightbox from document
lightbox.unattach();
@ -156,6 +184,41 @@
$.fn.exitFullscreen = oldFnExitFullscreen;
} );
QUnit.test( 'isAnyActiveButtonHovered', 20, function ( assert ) {
var lightbox = new mw.LightboxInterface( mw.mediaViewer );
// Attach lightbox to testing fixture to avoid interference with other tests.
lightbox.attach( '#qunit-fixture' );
$.each ( lightbox.$buttons, function ( idx, e ) {
var $e = $( e ),
offset = $e.offset(),
width = $e.width(),
height = $e.height(),
disabled = $e.hasClass( 'disabled' );
assert.strictEqual( lightbox.isAnyActiveButtonHovered( offset.left, offset.top ),
!disabled,
'Hover detection works for top-left corner of element' );
assert.strictEqual( lightbox.isAnyActiveButtonHovered( offset.left + width, offset.top ),
!disabled,
'Hover detection works for top-right corner of element' );
assert.strictEqual( lightbox.isAnyActiveButtonHovered( offset.left, offset.top + height ),
!disabled,
'Hover detection works for bottom-left corner of element' );
assert.strictEqual( lightbox.isAnyActiveButtonHovered( offset.left + width, offset.top + height ),
!disabled,
'Hover detection works for bottom-right corner of element' );
assert.strictEqual( lightbox.isAnyActiveButtonHovered(
offset.left + ( width / 2 ), offset.top + ( height / 2 ) ),
!disabled,
'Hover detection works for center of element' );
} );
// Unattach lightbox from document
lightbox.unattach();
} );
QUnit.test( 'Metadata scrolling', 13, function ( assert ) {
var lightbox = new mw.LightboxInterface( mw.mediaViewer ),
keydown = $.Event( 'keydown' ),
@ -219,15 +282,15 @@
lightbox.load( { getImageElement: function() { return $.Deferred().reject(); } } );
assert.strictEqual( $.scrollTo().scrollTop(), 0, 'scrollTo scrollTop should be set to 0' );
assert.strictEqual( lightbox.$dragIcon.hasClass( 'pointing-down' ), false,
assert.ok( !lightbox.$dragIcon.hasClass( 'pointing-down' ),
'Chevron pointing up' );
keydown.which = 38; // Up arrow
$document.trigger( keydown );
assert.strictEqual( $.scrollTo().scrollTop(), lightbox.$imageMetadata.height() + 1,
assert.strictEqual( Math.round( $.scrollTo().scrollTop() ), lightbox.$imageMetadata.height() + 1,
'scrollTo scrollTop should be set to the metadata height + 1 after pressing up arrow' );
assert.strictEqual( lightbox.$dragIcon.hasClass( 'pointing-down' ), true,
assert.ok( lightbox.$dragIcon.hasClass( 'pointing-down' ),
'Chevron pointing down after pressing up arrow' );
keydown.which = 40; // Down arrow
@ -235,21 +298,21 @@
assert.strictEqual( $.scrollTo().scrollTop(), 0,
'scrollTo scrollTop should be set to 0 after pressing down arrow' );
assert.strictEqual( lightbox.$dragIcon.hasClass( 'pointing-down' ), false,
assert.ok( !lightbox.$dragIcon.hasClass( 'pointing-down' ),
'Chevron pointing up after pressing down arrow' );
lightbox.$dragIcon.click();
assert.strictEqual( $.scrollTo().scrollTop(), lightbox.$imageMetadata.height() + 1,
assert.strictEqual( Math.round( $.scrollTo().scrollTop() ), lightbox.$imageMetadata.height() + 1,
'scrollTo scrollTop should be set to the metadata height + 1 after clicking the chevron once' );
assert.strictEqual( lightbox.$dragIcon.hasClass( 'pointing-down' ), true,
assert.ok( lightbox.$dragIcon.hasClass( 'pointing-down' ),
'Chevron pointing down after clicking the chevron once' );
lightbox.$dragIcon.click();
assert.strictEqual( $.scrollTo().scrollTop(), 0,
'scrollTo scrollTop should be set to 0 after clicking the chevron twice' );
assert.strictEqual( lightbox.$dragIcon.hasClass( 'pointing-down' ), false,
assert.ok( !lightbox.$dragIcon.hasClass( 'pointing-down' ),
'Chevron pointing up after clicking the chevron twice' );
// Unattach lightbox from document

View file

@ -76,6 +76,9 @@
link3.trigger( 'click' );
assert.notStrictEqual( viewer.lightbox, null, 'There are legit links, a lightbox should be created.' );
// Clean up the viewer, to avoid seeing it catch events when running other tests
mw.mmvTestHelpers.resetViewer();
} );
QUnit.test( 'Skip images with invalid extensions', 1, function ( assert ) {
@ -97,6 +100,9 @@
link.trigger( 'click' );
assert.strictEqual( viewer.lightbox, null, 'There are not legit links, a lightbox should not be created.' );
// Clean up the viewer, to avoid seeing it catch events when running other tests
mw.mmvTestHelpers.resetViewer();
} );
QUnit.test( 'Accept only left clicks without modifier keys, skip the rest', 1, function ( assert ) {
@ -132,6 +138,9 @@
// Skip invalid right click, no image is loaded
link.trigger( rightClick );
// Clean up the viewer, to avoid seeing it catch events when running other tests
mw.mmvTestHelpers.resetViewer();
} );
QUnit.test( 'Do not load the resized image if no data returning from the api', 1, function ( assert ) {
@ -143,6 +152,9 @@
viewer.loadResizedImage( ui, data );
assert.ok( true, 'Resized image is not replaced since we have not data.' );
// Clean up the viewer, to avoid seeing it catch events when running other tests
mw.mmvTestHelpers.resetViewer();
} );
QUnit.test( 'Logging works as expected', 4 * logTests.length, function ( assert ) {
@ -174,6 +186,9 @@
mw.log = backupLog;
mw.eventLog = backupEventLog;
// Clean up the viewer, to avoid seeing it catch events when running other tests
mw.mmvTestHelpers.resetViewer();
} );
QUnit.test( 'Profiling works as expected', ( 12 * profileTests.length ), function ( assert ) {
@ -221,6 +236,9 @@
mw.log = backupLog;
mw.eventLog = backupEventLog;
// Clean up the viewer, to avoid seeing it catch events when running other tests
mw.mmvTestHelpers.resetViewer();
} );
QUnit.asyncTest( 'Make sure we get sane values for the eventlogging timing', 2, function ( assert ) {
@ -240,6 +258,9 @@
} else {
mw.eventLog = backupEventLog;
QUnit.start();
// Clean up the viewer, to avoid seeing it catch events when running other tests
mw.mmvTestHelpers.resetViewer();
}
}
};
@ -259,6 +280,9 @@
};
link.trigger( 'click' );
// Clean up the viewer, to avoid seeing it catch events when running other tests
mw.mmvTestHelpers.resetViewer();
} );
QUnit.test( 'Validate new LightboxImage object has sane constructor parameters', 6, function ( assert ) {
@ -281,6 +305,9 @@
viewer = new mw.MultimediaViewer();
mw.MultimediaViewer.prototype.createNewImage = backup;
// Clean up the viewer, to avoid seeing it catch events when running other tests
mw.mmvTestHelpers.resetViewer();
} );
QUnit.test( 'Validate new LightboxImage object has sane constructor parameters', 6, function ( assert ) {
@ -303,6 +330,9 @@
viewer = new mw.MultimediaViewer();
mw.MultimediaViewer.prototype.createNewImage = backup;
// Clean up the viewer, to avoid seeing it catch events when running other tests
mw.mmvTestHelpers.resetViewer();
} );
QUnit.test( 'We get sane image sizes when we ask for them', 5, function ( assert ) {
@ -313,6 +343,9 @@
assert.strictEqual( viewer.findNextHighestImageSize( 320.00001 ), 640, 'Asking for greater than an image bucket definitely gives us the next size up' );
assert.strictEqual( viewer.findNextHighestImageSize( 2000 ), 2560, 'The image bucketing also works on big screens' );
assert.strictEqual( viewer.findNextHighestImageSize( 3000 ), 2880, 'The image bucketing also works on REALLY big screens' );
// Clean up the viewer, to avoid seeing it catch events when running other tests
mw.mmvTestHelpers.resetViewer();
} );
QUnit.test( 'Metadata div is only animated once', 4, function ( assert ) {
@ -335,6 +368,9 @@
assert.strictEqual( animationRan, false, 'The second call to animateMetadataDivOnce did not lead to an animation' );
$.fn.animate = backupAnimation;
// Clean up the viewer, to avoid seeing it catch events when running other tests
mw.mmvTestHelpers.resetViewer();
} );
QUnit.test( 'HTML whitelisting works', 2, function ( assert ) {
@ -351,6 +387,9 @@
viewer.whitelistHtml( $sandbox.empty().append( nwljq ) );
assert.strictEqual( $sandbox.html(), whitelisted, 'Not-whitelisted elements are removed.' );
// Clean up the viewer, to avoid seeing it catch events when running other tests
mw.mmvTestHelpers.resetViewer();
} );
QUnit.test( 'The location data is set correctly', 11, function ( assert ) {
@ -386,6 +425,9 @@
};
viewer.setLocationData( imageData );
// Clean up the viewer, to avoid seeing it catch events when running other tests
mw.mmvTestHelpers.resetViewer();
} );
QUnit.test( 'The location data is set correctly with weird values', 11, function ( assert ) {
@ -421,6 +463,9 @@
};
viewer.setLocationData( imageData );
// Clean up the viewer, to avoid seeing it catch events when running other tests
mw.mmvTestHelpers.resetViewer();
} );
QUnit.test( 'The location data is not set if no value is passed in', 1, function ( assert ) {
@ -443,6 +488,9 @@
viewer.setLocationData( imageData );
assert.strictEqual( called, false, 'The interface data-setter method is not called if there are no coordinates available for the image.' );
// Clean up the viewer, to avoid seeing it catch events when running other tests
mw.mmvTestHelpers.resetViewer();
} );
QUnit.test( 'getImageSizeApiArgs(): Limited by height and limited by width', 4, function ( assert ) {
@ -479,6 +527,9 @@
assert.strictEqual( widths.requested, 640 * $.devicePixelRatio(), 'Correct requested width was computed.' );
ui.unattach();
// Clean up the viewer, to avoid seeing it catch events when running other tests
mw.mmvTestHelpers.resetViewer();
} );
QUnit.asyncTest( 'loadAndSetImage(): Basic load', 9, function ( assert ) {
@ -528,6 +579,9 @@
requestedWidth = 640;
profileEvent = 'image-load';
viewer.loadAndSetImage( ui, imageData, targetWidth, requestedWidth, profileEvent );
// Clean up the viewer, to avoid seeing it catch events when running other tests
mw.mmvTestHelpers.resetViewer();
} );
QUnit.test( 'Hash handling', 5, function ( assert ) {

View file

@ -13,5 +13,12 @@
$( document ).trigger( $.Event( 'jq-fullscreen-change', { element: this, fullscreen: false } ) );
};
// TODO: remove once viewer isn't being referenced by interfaces anymore
// and event listening code has been cleaned up
MTH.resetViewer = function() {
lightboxHooks.constructor();
mw.mediaViewer.constructor();
};
mw.mmvTestHelpers = MTH;
} )( mediaWiki, jQuery );