diff --git a/MultimediaViewer.php b/MultimediaViewer.php index 9664c0ed9..eff8baf97 100644 --- a/MultimediaViewer.php +++ b/MultimediaViewer.php @@ -125,6 +125,12 @@ $wgResourceModules += array( 'mmv.ui.fileUsage', 'mmv.ui.metadataPanel', ), + + 'messages' => array( + 'multimediaviewer-close-popup-text', + 'multimediaviewer-fullscreen-popup-text', + 'multimediaviewer-defullscreen-popup-text', + ), ), 'mmv.ThumbnailWidthCalculator' => $wgMediaViewerResourceTemplate + array( @@ -535,6 +541,14 @@ $wgResourceModules += array( 'mypreferences', 'multimediaviewer-metadata-error', + + 'multimediaviewer-title-popup-text', + 'multimediaviewer-author-popup-text', + 'multimediaviewer-source-popup-text', + 'multimediaviewer-panel-open-popup-text', + 'multimediaviewer-panel-close-popup-text', + 'multimediaviewer-next-image-popup-text', + 'multimediaviewer-prev-image-popup-text', ), ), diff --git a/MultimediaViewerHooks.php b/MultimediaViewerHooks.php index 4ee3f0f39..fb6b31e29 100644 --- a/MultimediaViewerHooks.php +++ b/MultimediaViewerHooks.php @@ -156,6 +156,7 @@ class MultimediaViewerHooks { 'durationSamplingFactor' => $wgMediaViewerDurationLoggingSamplingFactor, 'networkPerformanceSamplingFactor' => $wgNetworkPerformanceSamplingFactor, 'actionLoggingSamplingFactorMap' => $wgMediaViewerActionLoggingSamplingFactorMap, + 'tooltipDelay' => 1000, ); $vars['wgMediaViewer'] = true; $vars['wgMediaViewerIsInBeta'] = $wgMediaViewerIsInBeta; diff --git a/i18n/en.json b/i18n/en.json index c741c9314..24c93a4a7 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -98,5 +98,15 @@ "multimediaviewer-description-page-button-text": "More details", "multimediaviewer-description-page-popup-text": "More details on $1", "multimediaviewer-commons-subtitle": "The free media repository", - "multimediaviewer-view-expanded": "Expand view" + "multimediaviewer-view-expanded": "Expand view", + "multimediaviewer-close-popup-text": "Close this tool. Or press 'Esc' to exit", + "multimediaviewer-fullscreen-popup-text": "Show in full screen", + "multimediaviewer-defullscreen-popup-text": "Exit full screen", + "multimediaviewer-next-image-popup-text": "Show next image", + "multimediaviewer-prev-image-popup-text": "Show previous image", + "multimediaviewer-title-popup-text": "File name", + "multimediaviewer-author-popup-text": "Author", + "multimediaviewer-source-popup-text": "Source", + "multimediaviewer-panel-open-popup-text": "More details", + "multimediaviewer-panel-close-popup-text": "Fewer details" } diff --git a/i18n/qqq.json b/i18n/qqq.json index 415a276c8..421c4ae15 100644 --- a/i18n/qqq.json +++ b/i18n/qqq.json @@ -103,5 +103,15 @@ "multimediaviewer-description-page-button-text": "Text of the button on top of the metadata panel which links to the file description page.\n\nSee also:\n* {{msg-mw|Multimediaviewer-description-page-popup-text}}", "multimediaviewer-description-page-popup-text": "Additional popup text of the button on top of the metadata panel, which links to the file description page.\n\nParameters:\n* $1 - the name of the site where the file comes from (e.g. \"Wikimedia Commons\")\nSee also:\n* {{msg-mw|Multimediaviewer-description-page-button-text}}.", "multimediaviewer-commons-subtitle": "Additional text to display under {{msg-mw|multimediaviewer-repository}} when the image is from Commons.", - "multimediaviewer-view-expanded": "Label for a link on a file page to view the current image in the media viewer." + "multimediaviewer-view-expanded": "Label for a link on a file page to view the current image in the media viewer.", + "multimediaviewer-close-popup-text": "Tooltip for the button that closes the media viewer.", + "multimediaviewer-fullscreen-popup-text": "Tooltip for a button that puts the viewer into full screen.", + "multimediaviewer-defullscreen-popup-text": "Tooltip for a button that exits fullscreen mode.", + "multimediaviewer-next-image-popup-text": "Tooltip for a button that navigates to the next image in a collection.", + "multimediaviewer-prev-image-popup-text": "Tooltip for a button that navigates to the previous image in a collection.", + "multimediaviewer-title-popup-text": "Tooltip that identifies the title of a file in the media viewer.", + "multimediaviewer-author-popup-text": "Tooltip that identifies the author of a file in the media viewer.", + "multimediaviewer-source-popup-text": "Tooltip that identifies the source of a file in the media viewer.", + "multimediaviewer-panel-open-popup-text": "Tooltip for a button that expands more metadata in the media viewer.", + "multimediaviewer-panel-close-popup-text": "Tooltip that closes the extra metadata view in the media viewer." } diff --git a/resources/mmv/mmv.lightboxinterface.js b/resources/mmv/mmv.lightboxinterface.js index 54236df32..7b98572ff 100644 --- a/resources/mmv/mmv.lightboxinterface.js +++ b/resources/mmv/mmv.lightboxinterface.js @@ -233,11 +233,17 @@ * Setup for canvas navigation buttons */ LIP.setupCanvasButtons = function () { - var ui = this; + var ui = this, + tooltipDelay = mw.config.get( 'wgMultimediaViewer').tooltipDelay; this.$closeButton = $( '
' ) .text( ' ' ) .addClass( 'mw-mmv-close' ) + .prop( 'title', mw.message( 'multimediaviewer-close-popup-text' ).text() ) + .tipsy( { + delayIn: tooltipDelay, + gravity: this.isRTL() ? 'nw' : 'ne' + } ) .click( function () { ui.unattach(); } ); @@ -245,6 +251,11 @@ this.$fullscreenButton = $( '
' ) .text( ' ' ) .addClass( 'mw-mmv-fullscreen' ) + .prop( 'title', mw.message( 'multimediaviewer-fullscreen-popup-text' ).text() ) + .tipsy( { + delayIn: tooltipDelay, + gravity: this.isRTL() ? 'nw' : 'ne' + } ) .click( function () { if ( ui.isFullscreen ) { ui.exitFullscreen(); @@ -270,8 +281,14 @@ if ( this.isFullscreen ) { mw.mmv.actionLogger.log( 'fullscreen' ); + + this.$fullscreenButton + .prop( 'title', mw.message( 'multimediaviewer-defullscreen-popup-text' ).text() ); } else { mw.mmv.actionLogger.log( 'defullscreen' ); + + this.$fullscreenButton + .prop( 'title', mw.message( 'multimediaviewer-fullscreen-popup-text' ).text() ); } if ( !this.fullscreenButtonJustPressed && !e.fullscreen ) { diff --git a/resources/mmv/ui/mmv.ui.canvasButtons.js b/resources/mmv/ui/mmv.ui.canvasButtons.js index de4c48ac5..056722ce5 100644 --- a/resources/mmv/ui/mmv.ui.canvasButtons.js +++ b/resources/mmv/ui/mmv.ui.canvasButtons.js @@ -29,7 +29,8 @@ * @param {jQuery} $fullscreenButton The fullscreen button from the parent class. */ function CanvasButtons( $container, $closeButton, $fullscreenButton ) { - var buttons = this; + var buttons = this, + tooltipDelay = mw.config.get( 'wgMultimediaViewer').tooltipDelay; mw.mmv.ui.Element.call( this, $container ); @@ -39,16 +40,30 @@ this.$viewFile = $( '
' ) .text( ' ' ) .prop( 'title', mw.message( 'multimediaviewer-viewfile-link' ).text() ) + .tipsy( { + delayIn: tooltipDelay, + gravity: this.isRTL() ? 'sw' : 'se' + } ) .addClass( 'mw-mmv-viewfile' ) .click( function () { $( document ).trigger( 'mmv-viewfile' ); } ); this.$next = $( '
' ) + .prop( 'title', mw.message( 'multimediaviewer-next-image-popup-text' ).text() ) + .tipsy( { + delayIn: tooltipDelay, + gravity: this.isRTL() ? 'w' : 'e' + } ) .addClass( 'mw-mmv-next-image disabled' ) .html( ' ' ); this.$prev = $( '
' ) + .prop( 'title', mw.message( 'multimediaviewer-prev-image-popup-text' ).text() ) + .tipsy( { + delayIn: tooltipDelay, + gravity: this.isRTL() ? 'e' : 'w' + } ) .addClass( 'mw-mmv-prev-image disabled' ) .html( ' ' ); diff --git a/resources/mmv/ui/mmv.ui.js b/resources/mmv/ui/mmv.ui.js index 883677147..28077c9bb 100644 --- a/resources/mmv/ui/mmv.ui.js +++ b/resources/mmv/ui/mmv.ui.js @@ -16,7 +16,8 @@ */ ( function ( mw, $ ) { - var EP; + var EP, + cachedRTL; /** * Represents a UI element. @@ -47,6 +48,18 @@ } EP = Element.prototype; + /** + * Checks whether the document is RTL. Assumes it doesn't change. + * @returns {boolean} + */ + EP.isRTL = function () { + if ( cachedRTL === undefined ) { + cachedRTL = $( document.body ).hasClass( 'rtl' ); + } + + return cachedRTL; + }; + /** * @abstract * Sets the data for the element. diff --git a/resources/mmv/ui/mmv.ui.metadataPanel.js b/resources/mmv/ui/mmv.ui.metadataPanel.js index 2763430d3..58d403b58 100644 --- a/resources/mmv/ui/mmv.ui.metadataPanel.js +++ b/resources/mmv/ui/mmv.ui.metadataPanel.js @@ -154,6 +154,11 @@ .appendTo( this.$titleAndCredit ); this.$title = $( '' ) + .prop( 'title', mw.message( 'multimediaviewer-title-popup-text' ) ) + .tipsy( { + delayIn: mw.config.get( 'wgMultimediaViewer').tooltipDelay, + gravity: this.isRTL() ? 'se' : 'sw' + } ) .addClass( 'mw-mmv-title' ); this.title = new mw.mmv.ui.TruncatableTextField( this.$titlePara, this.$title ); @@ -521,6 +526,8 @@ * @param {string} author With unsafe HTML */ MPP.setCredit = function ( source, author ) { + var tooltipDelay = mw.config.get( 'wgMultimediaViewer').tooltipDelay; + this.source = source || null; this.author = author || null; @@ -537,6 +544,20 @@ } else if ( source ) { this.creditField.set( this.source ); } + + this.$titleAndCredit.find( '.mw-mmv-author' ) + .prop( 'title', mw.message( 'multimediaviewer-author-popup-text' ).text() ) + .tipsy( { + delayIn: tooltipDelay, + gravity: this.isRTL() ? 'se' : 'sw' + } ); + + this.$titleAndCredit.find( '.mw-mmv-source' ) + .prop( 'title', mw.message( 'multimediaviewer-source-popup-text' ).text() ) + .tipsy( { + delayIn: tooltipDelay, + gravity: this.isRTL() ? 'se' : 'sw' + } ); }; /** diff --git a/resources/mmv/ui/mmv.ui.metadataPanelScroller.js b/resources/mmv/ui/mmv.ui.metadataPanelScroller.js index 50cb88089..bcc81fe26 100644 --- a/resources/mmv/ui/mmv.ui.metadataPanelScroller.js +++ b/resources/mmv/ui/mmv.ui.metadataPanelScroller.js @@ -76,7 +76,16 @@ MPSP.initialize = function () { var panel = this; + this.dragBarGravity = 's'; + this.$dragBar = $( '
' ) + .prop( 'title', mw.message( 'multimediaviewer-panel-open-popup-text' ).text() ) + .tipsy( { + delayIn: mw.config.get( 'wgMultimediaViewer').tooltipDelay, + gravity: function () { + return panel.dragBarGravity; + } + } ) .addClass( 'mw-mmv-drag-affordance' ) .appendTo( this.$controlBar ) .click( function () { @@ -106,13 +115,25 @@ scrollTopWhenClosed = 0, scrollTop = $.scrollTo().scrollTop(), panelIsOpen = scrollTop > scrollTopWhenClosed, - scrollTopTarget = panelIsOpen ? scrollTopWhenClosed : scrollTopWhenOpen; + scrollTopTarget = panelIsOpen ? scrollTopWhenClosed : scrollTopWhenOpen, + wasOpen = scrollTopTarget === scrollTopWhenOpen; if ( forceDirection ) { scrollTopTarget = forceDirection === 'down' ? scrollTopWhenClosed : scrollTopWhenOpen; } - mw.mmv.actionLogger.log( scrollTopTarget === scrollTopWhenOpen ? 'metadata-open' : 'metadata-close' ); + mw.mmv.actionLogger.log( wasOpen ? 'metadata-open' : 'metadata-close' ); + + this.$dragBar + .prop( 'title', + mw.message( + 'multimediaviewer-panel-' + + ( !wasOpen ? 'open' : 'close' ) + + '-popup-text' + ).text() + ); + + this.dragBarGravity = wasOpen ? 'n' : 's'; $.scrollTo( scrollTopTarget, this.toggleScrollDuration ); }; diff --git a/resources/mmv/ui/mmv.ui.stripeButtons.js b/resources/mmv/ui/mmv.ui.stripeButtons.js index 9b07da594..1ee2fcd9f 100644 --- a/resources/mmv/ui/mmv.ui.stripeButtons.js +++ b/resources/mmv/ui/mmv.ui.stripeButtons.js @@ -60,13 +60,18 @@ * @param {string} popupText HTML code for the popup text */ SBP.createButton = function ( cssClass, text, popupText ) { + var tooltipDelay = mw.config.get( 'wgMultimediaViewer' ).tooltipDelay; + return $( '' ) .addClass( 'mw-mmv-stripe-button empty ' + cssClass ) // .text( text ) // disabled while we have 3 buttons to save space .prop( 'title', popupText ) // elements are right-floated so we use prepend instead of append to keep the order .prependTo( this.$buttonContainer ) - .tipsy( { gravity: $( document.body ).hasClass( 'rtl' ) ? 'sw' : 'se' } ); + .tipsy( { + gravity: $( document.body ).hasClass( 'rtl' ) ? 'sw' : 'se', + delayIn: tooltipDelay + } ); }; /** diff --git a/tests/qunit/mmv/ui/mmv.ui.metadataPanel.test.js b/tests/qunit/mmv/ui/mmv.ui.metadataPanel.test.js index 1c81c5b72..06d2f21f1 100644 --- a/tests/qunit/mmv/ui/mmv.ui.metadataPanel.test.js +++ b/tests/qunit/mmv/ui/mmv.ui.metadataPanel.test.js @@ -116,7 +116,7 @@ ); } ); - QUnit.test( 'Setting image information works as expected', 16, function ( assert ) { + QUnit.test( 'Setting image information works as expected', 19, function ( assert ) { var gender, $qf = $( '#qunit-fixture' ), panel = new mw.mmv.ui.MetadataPanel( $qf, $( '
' ).appendTo( $qf ) ), @@ -170,7 +170,10 @@ assert.strictEqual( panel.$title.text(), title, 'Title is correctly set' ); assert.ok( !panel.$credit.hasClass( 'empty' ), 'Credit is not empty' ); assert.ok( !panel.$datetimeLi.hasClass( 'empty' ), 'Date/Time is not empty' ); - assert.strictEqual( panel.creditField.$element.html(), '' + imageData.author + ' - LostBar', 'Source and author are correctly set' ); + assert.strictEqual( panel.creditField.$element.find( '.mw-mmv-author' ).text(), imageData.author, 'Author text is correctly set' ); + assert.strictEqual( panel.creditField.$element.find( '.mw-mmv-author' ).attr( 'original-title' ), 'Author', 'Author tooltip is correctly set' ); + assert.strictEqual( panel.creditField.$element.find( '.mw-mmv-source' ).html(), 'LostBar', 'Source text is correctly set' ); + assert.strictEqual( panel.creditField.$element.find( '.mw-mmv-source' ).attr( 'original-title' ), 'Source', 'Source tooltip is correctly set' ); assert.ok( panel.$datetime.text().indexOf( 'August 26 2013' ) > 0, 'Correct date is displayed' ); assert.strictEqual( panel.$license.text(), 'CC BY 2.0', 'License is correctly set' ); assert.ok( panel.$license.prop( 'target' ), 'License information opens in new window' );