Gergő Tisza has uploaded a new change for review. https://gerrit.wikimedia.org/r/132133
Change subject: Minimal zoom implementation ...................................................................... Minimal zoom implementation Just a link to the full-size file for now. Linking to the zoom viewer over a certain size would be easy, but it is currently disabled by the toolserver's idiotic inactivity policy; hopefully that gets fixed soon. Change-Id: I9ce9d2a2d27b75470eae2806d9f9ce2f95f4dac2 Mingle: https://wikimedia.mingle.thoughtworks.com/projects/multimedia/cards/588 --- M resources/mmv/mmv.js M resources/mmv/mmv.lightboxinterface.js M resources/mmv/ui/mmv.ui.canvas.js M resources/mmv/ui/mmv.ui.canvasButtons.js M resources/mmv/ui/mmv.ui.canvasButtons.less M tests/qunit/mmv/mmv.lightboxinterface.test.js M tests/qunit/mmv/mmv.test.js 7 files changed, 109 insertions(+), 20 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/MultimediaViewer refs/changes/33/132133/1 diff --git a/resources/mmv/mmv.js b/resources/mmv/mmv.js index b561267..c2e20bf 100755 --- a/resources/mmv/mmv.js +++ b/resources/mmv/mmv.js @@ -282,6 +282,7 @@ start = $.now(); imagePromise = this.fetchThumbnailForLightboxImage( image, imageWidths.real ); + metadataPromise = this.fetchSizeIndependentLightboxInfo( image.filePageTitle ); this.resetBlurredThumbnailStates(); if ( imagePromise.state() === 'pending' ) { @@ -289,6 +290,7 @@ } this.setupProgressBar( image, imagePromise, imageWidths.real ); + this.setupZoomControl( image, metadataPromise, imageWidths.cssWidth ); imagePromise.done( function ( thumbnail, imageElement ) { if ( viewer.currentIndex !== image.index ) { @@ -303,9 +305,7 @@ viewer.ui.canvas.showError( error ); } ); - metadataPromise = this.fetchSizeIndependentLightboxInfo( - image.filePageTitle - ).done( function ( imageInfo, repoInfo, localUsage, globalUsage, userInfo ) { + metadataPromise.done( function ( imageInfo, repoInfo, localUsage, globalUsage, userInfo ) { if ( viewer.currentIndex !== image.index ) { return; } @@ -517,6 +517,32 @@ progressBar.hide(); } } ); + }; + + /** + * Displays a zoom icon if the image can be zoomed. + * @param {mw.mmv.LightboxImage} image + * @param {jQuery.Promise.<mw.mmv.model.Image>} metadataPromise + * @param {number} imageWidth needed for caching progress + */ + MMVP.setupZoomControl = function ( image, metadataPromise, imageWidth ) { + var viewer = this; + + if ( image.originalWidth ) { + this.setupZoomControlNow( imageWidth, image.originalWidth ); + } else { + this.ui.buttons.toggleZoom( false ); + metadataPromise.done( function ( imageInfo ) { + if ( viewer.currentIndex !== image.index ) { + return; + } + viewer.setupZoomControlNow( imageWidth, imageInfo.width ); + } ); + } + }; + + MMVP.setupZoomControlNow = function ( imageWidth, originalImageWidth ) { + this.ui.buttons.toggleZoom( originalImageWidth > imageWidth ); }; /** @@ -865,6 +891,12 @@ $( document ).on( 'mmv-close.mmvp', function () { viewer.close(); + } ).on( 'mmv-zoom.mmvp', function () { + viewer.fetchSizeIndependentLightboxInfo( + viewer.currentImageFileTitle + ).done( function ( imageInfo ) { + viewer.ui.canvas.zoom( imageInfo ); + } ); } ).on( 'mmv-next.mmvp', function () { viewer.nextImage(); } ).on( 'mmv-prev.mmvp', function () { diff --git a/resources/mmv/mmv.lightboxinterface.js b/resources/mmv/mmv.lightboxinterface.js index 01776d4..8c0ca34 100644 --- a/resources/mmv/mmv.lightboxinterface.js +++ b/resources/mmv/mmv.lightboxinterface.js @@ -376,7 +376,7 @@ } this.buttons.setOffset( prevNextTop ); - this.buttons.toggle( showPrevButton, showNextButton ); + this.buttons.togglePrevNext( showPrevButton, showNextButton ); }; mw.mmv.LightboxInterface = LightboxInterface; diff --git a/resources/mmv/ui/mmv.ui.canvas.js b/resources/mmv/ui/mmv.ui.canvas.js index 2d04c27..b8127d9 100644 --- a/resources/mmv/ui/mmv.ui.canvas.js +++ b/resources/mmv/ui/mmv.ui.canvas.js @@ -257,7 +257,7 @@ } ); }; - C.unblur = function() { + C.unblur = function () { // We apply empty CSS values to remove the inline styles applied by jQuery // so that they don't get in the way of styles defined in CSS this.$image.css( { '-webkit-filter' : '', 'opacity' : '' } ) @@ -265,6 +265,21 @@ }; /** + * Switches into zoom mode. For now, we just open the full-sized image in a new window. + * @param {mw.mmv.model.Image} imageInfo + */ + C.zoom = function ( imageInfo ) { + // temporary zoom solution + var zoomedImageUrl = imageInfo.url; + // disable this while zoom viewer is broken +// if ( imageInfo.width * imageInfo.height > 2000000 ) { +// zoomedImageUrl = 'http://toolserver.org/~dschwen/iip/wip.php?f=' +// + encodeURIComponent( imageInfo.title.getMain() ); +// } + window.open( zoomedImageUrl ); + }; + + /** * Displays a message and error icon when loading the image fails. * @param {string} error error message */ diff --git a/resources/mmv/ui/mmv.ui.canvasButtons.js b/resources/mmv/ui/mmv.ui.canvasButtons.js index dd64074..ea564d0 100644 --- a/resources/mmv/ui/mmv.ui.canvasButtons.js +++ b/resources/mmv/ui/mmv.ui.canvasButtons.js @@ -36,6 +36,10 @@ this.$close = $closeButton; this.$fullscreen = $fullscreenButton; + this.$zoom = $( '<div>' ) + .addClass( 'mw-mmv-zoom disabled' ) + .html( ' ' ); + this.$next = $( '<div>' ) .addClass( 'mw-mmv-next-image disabled' ) .html( ' ' ); @@ -49,6 +53,7 @@ this.$buttons = this.$close .add( this.$fullscreen ) + .add( this.$zoom ) .add( this.$next ) .add( this.$prev ); @@ -64,6 +69,10 @@ this.$fullscreen.click( function () { $container.trigger( $.Event( 'mmv-fullscreen' ) ); + } ); + + this.$zoom.click( function () { + $container.trigger( $.Event( 'mmv-zoom' ) ); } ); this.$next.click( function () { @@ -104,12 +113,20 @@ * @param {boolean} showPrevButton * @param {boolean} showNextButton */ - CBP.toggle = function ( showPrevButton, showNextButton ) { + CBP.togglePrevNext = function ( showPrevButton, showNextButton ) { this.$next.toggleClass( 'disabled', !showPrevButton ); this.$prev.toggleClass( 'disabled', !showNextButton ); }; /** + * Toggles whether the zoom control is visible. + * @param {boolean} visible + */ + CBP.toggleZoom = function ( visible ) { + this.$zoom.toggleClass( 'disabled', !visible ); + }; + + /** * Fades out the active buttons */ CBP.fadeOut = function () { diff --git a/resources/mmv/ui/mmv.ui.canvasButtons.less b/resources/mmv/ui/mmv.ui.canvasButtons.less index 6e38716..eeda6f9 100644 --- a/resources/mmv/ui/mmv.ui.canvasButtons.less +++ b/resources/mmv/ui/mmv.ui.canvasButtons.less @@ -5,6 +5,7 @@ .mw-mmv-close, .mw-mmv-fullscreen, +.mw-mmv-zoom, .mw-mmv-next-image, .mw-mmv-prev-image { cursor: pointer; @@ -19,23 +20,22 @@ } .unselectable; -} -.mw-mmv-close.hidden, -.mw-mmv-fullscreen.hidden, -.mw-mmv-next-image.hidden, -.mw-mmv-prev-image.hidden { - display: none; + &.disabled, + &.hidden { + display: none; + } } .cursor-hidden { - .mw-mmv-close, .mw-mmv-fullscreen, .mw-mmv-next-image, .mw-mmv-prev-image { + .mw-mmv-close, .mw-mmv-fullscreen, .mw-mmv-zoom, .mw-mmv-next-image, .mw-mmv-prev-image { cursor: none; } } .mw-mmv-close, -.mw-mmv-fullscreen { +.mw-mmv-fullscreen, +.mw-mmv-zoom { right: @buttons-offset; left: auto; transition: opacity 0.25s; @@ -50,11 +50,6 @@ width: 80px; height: 120px; transition: opacity 0.25s, margin 0.25s; - - &.disabled { - display: none; - cursor: none; - } } .mw-mmv-close { @@ -78,6 +73,14 @@ background-image: url(img/mw-defullscreen-ltr.svg); } +.mw-mmv-zoom { + top: (@buttons-offset + 72px); + /* @embed */ + background-image: url(img/mw-zoom-ltr.svg); + width: 21px; + height: 22px; +} + .mw-mmv-next-image { /* @embed */ background-image: url(img/next-ltr.svg); diff --git a/tests/qunit/mmv/mmv.lightboxinterface.test.js b/tests/qunit/mmv/mmv.lightboxinterface.test.js index 5b6e057..6ad6e04 100644 --- a/tests/qunit/mmv/mmv.lightboxinterface.test.js +++ b/tests/qunit/mmv/mmv.lightboxinterface.test.js @@ -202,7 +202,7 @@ restoreScrollTo(); } ); - QUnit.test( 'isAnyActiveButtonHovered', 20, function ( assert ) { + QUnit.test( 'isAnyActiveButtonHovered', 25, function ( assert ) { var lightbox = new mw.mmv.LightboxInterface(); stubScrollTo(); diff --git a/tests/qunit/mmv/mmv.test.js b/tests/qunit/mmv/mmv.test.js index ba62370..a946fad 100644 --- a/tests/qunit/mmv/mmv.test.js +++ b/tests/qunit/mmv/mmv.test.js @@ -110,6 +110,7 @@ viewer.scroll = $.noop; viewer.preloadFullscreenThumbnail = $.noop; viewer.fetchSizeIndependentLightboxInfo = function () { return $.Deferred().resolve(); }; + viewer.setupZoomControl = $.noop; viewer.ui = { setupForLoad : $.noop, canvas : { set : $.noop, @@ -163,6 +164,7 @@ viewer.preloadImagesMetadata = $.noop; viewer.preloadThumbnails = $.noop; viewer.fetchSizeIndependentLightboxInfo = function () { return $.Deferred().resolve(); }; + viewer.setupZoomControl = $.noop; viewer.ui = { setupForLoad : $.noop, canvas : { set : $.noop, @@ -355,6 +357,7 @@ viewer.preloadFullscreenThumbnail = $.noop; viewer.fetchSizeIndependentLightboxInfo = this.sandbox.stub(); + viewer.setupZoomControl = $.noop; viewer.ui = { setupForLoad : $.noop, canvas : { set : $.noop, @@ -401,6 +404,25 @@ assert.ok( viewer.displayRealThumbnail.called, 'The second image being done loading should result in the image being shown'); } ); + QUnit.test( 'Zoom control', 4, function( assert ) { + var viewer = new mw.mmv.MultimediaViewer(); + + viewer.currentIndex = 0; + viewer.ui = { buttons: { toggleZoom: this.sandbox.stub() } }; + + viewer.setupZoomControl( { index: 0, originalWidth: 1000 }, $.Deferred(), 500 ); + assert.ok( viewer.ui.buttons.toggleZoom.lastCall.calledWith( true ), 'Original larger, size available: zoom control is visible' ); + + viewer.setupZoomControl( { index: 0, originalWidth: 1000 }, $.Deferred(), 1000 ); + assert.ok( viewer.ui.buttons.toggleZoom.lastCall.calledWith( false ), 'Original the same, size available: zoom control is not visible' ); + + viewer.setupZoomControl( { index: 0 }, $.Deferred().resolve( { width: 1000 } ), 500 ); + assert.ok( viewer.ui.buttons.toggleZoom.lastCall.calledWith( true ), 'Original larger, size unavailable: zoom control is visible' ); + + viewer.setupZoomControl( { index: 0 }, $.Deferred().resolve( { width: 1000 } ), 1000 ); + assert.ok( viewer.ui.buttons.toggleZoom.lastCall.calledWith( false ), 'Original the same, size unavailable: zoom control is not visible' ); + } ); + QUnit.test( 'Events are not trapped after the viewer is closed', 0, function( assert ) { var i, j, k, eventParameters, viewer = new mw.mmv.MultimediaViewer(), -- To view, visit https://gerrit.wikimedia.org/r/132133 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9ce9d2a2d27b75470eae2806d9f9ce2f95f4dac2 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/MultimediaViewer Gerrit-Branch: master Gerrit-Owner: Gergő Tisza <gti...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits