mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/MultimediaViewer
synced 2024-09-24 10:49:40 +00:00
Merge "Log image dimensions"
This commit is contained in:
commit
2203f89236
|
@ -45,6 +45,16 @@ if ( !isset( $wgMediaViewerAttributionLoggingSamplingFactor ) ) {
|
|||
$wgMediaViewerAttributionLoggingSamplingFactor = false;
|
||||
}
|
||||
|
||||
if ( !isset( $wgMediaViewerDimensionLoggingSamplingFactor ) ) {
|
||||
/**
|
||||
* If set, records whether image dimension data was available. A value of 1000 means there will be an
|
||||
* 1:1000 chance to log the dimension event.
|
||||
* False if unset.
|
||||
* @var int|bool
|
||||
*/
|
||||
$wgMediaViewerDimensionLoggingSamplingFactor = false;
|
||||
}
|
||||
|
||||
if ( !isset( $wgMediaViewerActionLoggingSamplingFactorMap ) ) {
|
||||
/**
|
||||
* If set, records user actions via EventLogging and applies a sampling factor according to the map. A "default" key in the map must be set.
|
||||
|
@ -813,6 +823,7 @@ $wgResourceModules += array(
|
|||
'mmv.provider',
|
||||
'mmv.routing',
|
||||
'mmv.logging.DurationLogger',
|
||||
'mmv.logging.DimensionLogger',
|
||||
'jquery.fullscreen',
|
||||
'jquery.hidpi',
|
||||
'jquery.scrollTo',
|
||||
|
@ -902,6 +913,19 @@ $wgResourceModules += array(
|
|||
),
|
||||
),
|
||||
|
||||
'mmv.logging.DimensionLogger' => $wgMediaViewerResourceTemplate + array(
|
||||
'scripts' => array(
|
||||
'mmv/logging/mmv.logging.DimensionLogger.js',
|
||||
),
|
||||
|
||||
'dependencies' => array(
|
||||
'mmv.base',
|
||||
'mmv.logging.Logger',
|
||||
'oojs',
|
||||
'jquery.hidpi',
|
||||
),
|
||||
),
|
||||
|
||||
'mmv.head' => $wgMediaViewerResourceTemplate + array(
|
||||
'scripts' => array(
|
||||
'mmv/mmv.head.js',
|
||||
|
@ -936,10 +960,13 @@ $wgExtensionFunctions[] = function () {
|
|||
$wgEventLoggingSchemas[ 'MultimediaViewerNetworkPerformance' ] = 7917896;
|
||||
$wgEventLoggingSchemas[ 'MultimediaViewerDuration' ] = 8572641;
|
||||
$wgEventLoggingSchemas[ 'MultimediaViewerAttribution' ] = 9758179;
|
||||
$wgEventLoggingSchemas[ 'MultimediaViewerDimensions' ] = 10014238;
|
||||
|
||||
$wgResourceModules['mmv.logging.ActionLogger']['dependencies'][] = 'ext.eventLogging';
|
||||
$wgResourceModules['mmv.logging.Performance']['dependencies'][] = 'ext.eventLogging';
|
||||
$wgResourceModules['mmv.logging.DurationLogger']['dependencies'][] = 'ext.eventLogging';
|
||||
$wgResourceModules['mmv.logging.AttributionLogger']['dependencies'][] = 'ext.eventLogging';
|
||||
$wgResourceModules['mmv.logging.DimensionLogger']['dependencies'][] = 'ext.eventLogging';
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -139,8 +139,9 @@ class MultimediaViewerHooks {
|
|||
* @return bool
|
||||
*/
|
||||
public static function resourceLoaderGetConfigVars( &$vars ) {
|
||||
global $wgAPIPropModules, $wgMediaViewerActionLoggingSamplingFactorMap, $wgNetworkPerformanceSamplingFactor, $wgMediaViewerDurationLoggingSamplingFactor,
|
||||
$wgMediaViewerAttributionLoggingSamplingFactor, $wgMediaViewerIsInBeta, $wgMediaViewerUseThumbnailGuessing;
|
||||
global $wgMediaViewerActionLoggingSamplingFactorMap, $wgNetworkPerformanceSamplingFactor,
|
||||
$wgMediaViewerDurationLoggingSamplingFactor, $wgMediaViewerAttributionLoggingSamplingFactor,
|
||||
$wgMediaViewerDimensionLoggingSamplingFactor, $wgMediaViewerIsInBeta, $wgMediaViewerUseThumbnailGuessing;
|
||||
$vars['wgMultimediaViewer'] = array(
|
||||
'infoLink' => self::$infoLink,
|
||||
'discussionLink' => self::$discussionLink,
|
||||
|
@ -150,6 +151,7 @@ class MultimediaViewerHooks {
|
|||
'networkPerformanceSamplingFactor' => $wgNetworkPerformanceSamplingFactor,
|
||||
'actionLoggingSamplingFactorMap' => $wgMediaViewerActionLoggingSamplingFactorMap,
|
||||
'attributionSamplingFactor' => $wgMediaViewerAttributionLoggingSamplingFactor,
|
||||
'dimensionSamplingFactor' => $wgMediaViewerDimensionLoggingSamplingFactor,
|
||||
'tooltipDelay' => 1000,
|
||||
);
|
||||
$vars['wgMediaViewer'] = true;
|
||||
|
@ -192,6 +194,8 @@ class MultimediaViewerHooks {
|
|||
'tests/qunit/mmv/logging/mmv.logging.DurationLogger.test.js',
|
||||
'tests/qunit/mmv/logging/mmv.logging.Performance.test.js',
|
||||
'tests/qunit/mmv/logging/mmv.logging.ActionLogger.test.js',
|
||||
'tests/qunit/mmv/logging/mmv.logging.AttributionLogger.test.js',
|
||||
'tests/qunit/mmv/logging/mmv.logging.DimensionLogger.test.js',
|
||||
'tests/qunit/mmv/model/mmv.model.test.js',
|
||||
'tests/qunit/mmv/model/mmv.model.IwTitle.test.js',
|
||||
'tests/qunit/mmv/model/mmv.model.TaskQueue.test.js',
|
||||
|
|
|
@ -63,5 +63,6 @@
|
|||
this.log( data );
|
||||
};
|
||||
|
||||
mw.mmv.logging.AttributionLogger = AttributionLogger;
|
||||
mw.mmv.attributionLogger = new AttributionLogger();
|
||||
}( mediaWiki, jQuery, OO ) );
|
76
resources/mmv/logging/mmv.logging.DimensionLogger.js
Normal file
76
resources/mmv/logging/mmv.logging.DimensionLogger.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* This file is part of the MediaWiki extension MultimediaViewer.
|
||||
*
|
||||
* MultimediaViewer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MultimediaViewer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MultimediaViewer. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
( function ( mw, $, oo ) {
|
||||
var DL;
|
||||
|
||||
/**
|
||||
* Writes EventLogging entries for size measurements related to thumbnail size selection
|
||||
* (bucket size vs. display size).
|
||||
* @class mw.mmv.logging.DimensionLogger
|
||||
* @extends mw.mmv.logging.Logger
|
||||
* @constructor
|
||||
*/
|
||||
function DimensionLogger() {}
|
||||
|
||||
oo.inheritClass( DimensionLogger, mw.mmv.logging.Logger );
|
||||
|
||||
DL = DimensionLogger.prototype;
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @inheritdoc
|
||||
*/
|
||||
DL.samplingFactor = mw.config.get( 'wgMultimediaViewer' ).dimensionSamplingFactor;
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @inheritdoc
|
||||
*/
|
||||
DL.schema = 'MultimediaViewerDimensions';
|
||||
|
||||
/**
|
||||
* Logs dimension data.
|
||||
* @param {mw.mmv.model.ThumbnailWidth} imageWidths widths of the imagethat will be displayed
|
||||
* @param {{width: Number, height: Number}} canvasDimensions canvas width and height in CSS pixels
|
||||
* @param {string} context reason for requesting the image, one of 'show', 'resize', 'preload'
|
||||
*/
|
||||
DL.logDimensions = function ( imageWidths, canvasDimensions, context ) {
|
||||
var data;
|
||||
|
||||
data = {
|
||||
screenWidth: screen.width,
|
||||
screenHeight: screen.height,
|
||||
viewportWidth: $( window).width(),
|
||||
viewportHeight: $( window).height(),
|
||||
canvasWidth: canvasDimensions.width,
|
||||
canvasHeight: canvasDimensions.height,
|
||||
devicePixelRatio: $.devicePixelRatio(),
|
||||
imgWidth: imageWidths.cssWidth,
|
||||
imageAspectRatio: imageWidths.cssWidth / imageWidths.cssHeight,
|
||||
thumbWidth: imageWidths.real,
|
||||
context: context,
|
||||
samplingFactor: this.samplingFactor
|
||||
};
|
||||
mw.log( 'mw.mmw.logger.DimensionLogger', data );
|
||||
|
||||
this.log( data );
|
||||
};
|
||||
|
||||
mw.mmv.logging.DimensionLogger = DimensionLogger;
|
||||
mw.mmv.dimensionLogger = new DimensionLogger();
|
||||
}( mediaWiki, jQuery, OO ) );
|
|
@ -179,14 +179,18 @@
|
|||
* @param {mw.mmv.LightboxInterface} ui lightbox that got resized
|
||||
*/
|
||||
MMVP.resize = function ( ui ) {
|
||||
var viewer = this,
|
||||
image = this.thumbs[ this.currentIndex ].image,
|
||||
imageWidths;
|
||||
var imageWidths, canvasDimensions,
|
||||
viewer = this,
|
||||
image = this.thumbs[ this.currentIndex ].image;
|
||||
|
||||
this.preloadThumbnails();
|
||||
|
||||
if ( image ) {
|
||||
imageWidths = ui.canvas.getCurrentImageWidths();
|
||||
canvasDimensions = ui.canvas.getDimensions();
|
||||
|
||||
mw.mmv.dimensionLogger.logDimensions( imageWidths, canvasDimensions, 'resize' );
|
||||
|
||||
this.fetchThumbnailForLightboxImage(
|
||||
image, imageWidths.real
|
||||
).then( function( thumbnail, image ) {
|
||||
|
@ -229,6 +233,7 @@
|
|||
*/
|
||||
MMVP.loadImage = function ( image, initialImage ) {
|
||||
var imageWidths,
|
||||
canvasDimensions,
|
||||
imagePromise,
|
||||
metadataPromise,
|
||||
start,
|
||||
|
@ -259,10 +264,11 @@
|
|||
// this.preloadFullscreenThumbnail( image ); // disabled - #474
|
||||
|
||||
imageWidths = this.ui.canvas.getCurrentImageWidths();
|
||||
|
||||
canvasDimensions = this.ui.canvas.getDimensions();
|
||||
|
||||
start = $.now();
|
||||
|
||||
mw.mmv.dimensionLogger.logDimensions( imageWidths, canvasDimensions, 'show' );
|
||||
imagePromise = this.fetchThumbnailForLightboxImage( image, imageWidths.real );
|
||||
|
||||
this.resetBlurredThumbnailStates();
|
||||
|
@ -614,16 +620,20 @@
|
|||
|
||||
this.thumbnailPreloadQueue = this.pushLightboxImagesIntoQueue( function( lightboxImage ) {
|
||||
return function() {
|
||||
var imageWidths, canvasDimensions;
|
||||
|
||||
// viewer.ui.canvas.getLightboxImageWidths needs the viewer to be open
|
||||
// because it needs to read the size of visible elements
|
||||
if ( !viewer.isOpen ) {
|
||||
return;
|
||||
}
|
||||
|
||||
return viewer.fetchThumbnailForLightboxImage(
|
||||
lightboxImage,
|
||||
viewer.ui.canvas.getLightboxImageWidths( lightboxImage ).real
|
||||
);
|
||||
imageWidths = viewer.ui.canvas.getLightboxImageWidths( lightboxImage );
|
||||
canvasDimensions = viewer.ui.canvas.getDimensions();
|
||||
|
||||
mw.mmv.dimensionLogger.logDimensions( imageWidths, canvasDimensions, 'preload' );
|
||||
|
||||
return viewer.fetchThumbnailForLightboxImage( lightboxImage, imageWidths.real );
|
||||
};
|
||||
} );
|
||||
|
||||
|
@ -634,10 +644,11 @@
|
|||
* Preload the fullscreen size of the current image.
|
||||
*/
|
||||
MMVP.preloadFullscreenThumbnail = function( image ) {
|
||||
this.fetchThumbnailForLightboxImage(
|
||||
image,
|
||||
this.ui.canvas.getLightboxImageWidthsForFullscreen( image ).real
|
||||
);
|
||||
var imageWidths = this.ui.canvas.getLightboxImageWidthsForFullscreen( image),
|
||||
canvasDimensions = this.ui.canvas.getDimensions( true );
|
||||
|
||||
mw.mmv.dimensionLogger.logDimensions( imageWidths, canvasDimensions, 'preload' );
|
||||
this.fetchThumbnailForLightboxImage( image, imageWidths.real );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -716,7 +727,7 @@
|
|||
thumbnailPromise = this.guessedThumbnailInfoProvider.get(
|
||||
fileTitle, sampleUrl, width, originalWidth, originalHeight
|
||||
).then( null, function () { // catch rejection, use fallback
|
||||
return viewer.thumbnailInfoProvider.get( fileTitle, width );
|
||||
return viewer.thumbnailInfoProvider.get( fileTitle, width );
|
||||
} );
|
||||
} else {
|
||||
thumbnailPromise = this.thumbnailInfoProvider.get( fileTitle, width );
|
||||
|
|
|
@ -339,13 +339,13 @@
|
|||
};
|
||||
|
||||
/**
|
||||
* Gets the widths for a given lightbox image.
|
||||
* @param {mw.mmv.LightboxImage} image
|
||||
* @returns {mw.mmv.model.ThumbnailWidth}
|
||||
* Returns width and height of the canvas area (i.e. the space available for the image).
|
||||
* @param {boolean} forFullscreen if true, return size in fullscreen mode; otherwise, return current size
|
||||
* (which might still be fullscreen mode).
|
||||
* @return {{width: Number, height: Number}} width and height in CSS pixels
|
||||
*/
|
||||
C.getLightboxImageWidths = function ( image ) {
|
||||
var thumb = image.thumbnail,
|
||||
$window = $( window ),
|
||||
C.getDimensions = function ( forFullscreen ) {
|
||||
var $window = $( window ),
|
||||
$aboveFold = $( '.mw-mmv-above-fold' ),
|
||||
isFullscreened = !!$aboveFold.closest( '.jq-fullscreened' ).length,
|
||||
// Don't rely on this.$imageWrapper's sizing because it's fragile.
|
||||
|
@ -354,8 +354,30 @@
|
|||
availableWidth = $window.width(),
|
||||
availableHeight = $window.height() - ( isFullscreened ? 0 : $aboveFold.height() );
|
||||
|
||||
if ( forFullscreen ) {
|
||||
return {
|
||||
width: screen.width,
|
||||
height: screen.height
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
width: availableWidth,
|
||||
height: availableHeight
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the widths for a given lightbox image.
|
||||
* @param {mw.mmv.LightboxImage} image
|
||||
* @returns {mw.mmv.model.ThumbnailWidth}
|
||||
*/
|
||||
C.getLightboxImageWidths = function ( image ) {
|
||||
var thumb = image.thumbnail,
|
||||
canvasDimensions = this.getDimensions();
|
||||
|
||||
return this.thumbnailWidthCalculator.calculateWidths(
|
||||
availableWidth, availableHeight, thumb.width, thumb.height );
|
||||
canvasDimensions.width, canvasDimensions.height, thumb.width, thumb.height );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -366,10 +388,11 @@
|
|||
* @returns {mw.mmv.model.ThumbnailWidth}
|
||||
*/
|
||||
C.getLightboxImageWidthsForFullscreen = function ( image ) {
|
||||
var thumb = image.thumbnail;
|
||||
var thumb = image.thumbnail,
|
||||
canvasDimensions = this.getDimensions( true );
|
||||
|
||||
return this.thumbnailWidthCalculator.calculateWidths(
|
||||
screen.width, screen.height, thumb.width, thumb.height );
|
||||
canvasDimensions.width, canvasDimensions.height, thumb.width, thumb.height );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
( function ( mw, $ ) {
|
||||
QUnit.module( 'mmv.logging.AttributionLogger', QUnit.newMwEnvironment() );
|
||||
|
||||
QUnit.test( 'log()', 2, function ( assert ) {
|
||||
var fakeEventLog = { logEvent : this.sandbox.stub() },
|
||||
logger = new mw.mmv.logging.AttributionLogger(),
|
||||
image = { author: 'foo', source: 'bar', license: {} },
|
||||
emptyImage = {};
|
||||
|
||||
this.sandbox.stub( logger, 'loadDependencies' ).returns( $.Deferred().resolve() );
|
||||
this.sandbox.stub( mw, 'log' );
|
||||
|
||||
logger.samplingFactor = 1;
|
||||
logger.setEventLog( fakeEventLog );
|
||||
|
||||
logger.logAttribution( image );
|
||||
assert.ok( true, 'logDimensions() did not throw errors' );
|
||||
|
||||
logger.logAttribution( emptyImage );
|
||||
assert.ok( true, 'logDimensions() did not throw errors for empty image' );
|
||||
} );
|
||||
}( mediaWiki, jQuery ) );
|
17
tests/qunit/mmv/logging/mmv.logging.DimensionLogger.test.js
Normal file
17
tests/qunit/mmv/logging/mmv.logging.DimensionLogger.test.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
( function ( mw, $ ) {
|
||||
QUnit.module( 'mmv.logging.DimensionLogger', QUnit.newMwEnvironment() );
|
||||
|
||||
QUnit.test( 'log()', 1, function ( assert ) {
|
||||
var fakeEventLog = { logEvent : this.sandbox.stub() },
|
||||
logger = new mw.mmv.logging.DimensionLogger();
|
||||
|
||||
this.sandbox.stub( logger, 'loadDependencies' ).returns( $.Deferred().resolve() );
|
||||
this.sandbox.stub( mw, 'log' );
|
||||
|
||||
logger.samplingFactor = 1;
|
||||
logger.setEventLog( fakeEventLog );
|
||||
|
||||
logger.logDimensions( 640, 480, 200, 'resize' );
|
||||
assert.ok( true, 'logDimensions() did not throw errors' );
|
||||
} );
|
||||
}( mediaWiki, jQuery ) );
|
|
@ -116,7 +116,9 @@
|
|||
canvas: { set : $.noop,
|
||||
unblurWithAnimation: $.noop,
|
||||
unblur: $.noop,
|
||||
getCurrentImageWidths: function () { return { real : 0 }; } },
|
||||
getCurrentImageWidths: function () { return { real : 0 }; },
|
||||
getDimensions: function () { return {}; }
|
||||
},
|
||||
panel: {
|
||||
setImageInfo: $.noop,
|
||||
scroller: {
|
||||
|
@ -172,7 +174,9 @@
|
|||
canvas : { set : $.noop,
|
||||
unblurWithAnimation: $.noop,
|
||||
unblur: $.noop,
|
||||
getCurrentImageWidths : function () { return { real : 0 }; } },
|
||||
getCurrentImageWidths : function () { return { real : 0 }; },
|
||||
getDimensions: function () { return {}; }
|
||||
},
|
||||
panel : {
|
||||
setImageInfo : $.noop,
|
||||
scroller: {
|
||||
|
@ -364,8 +368,11 @@
|
|||
viewer.ui = {
|
||||
setFileReuseData: $.noop,
|
||||
setupForLoad : $.noop,
|
||||
canvas : { set : $.noop,
|
||||
getCurrentImageWidths : function () { return { real : 0 }; } },
|
||||
canvas : {
|
||||
set : $.noop,
|
||||
getCurrentImageWidths : function () { return { real : 0 }; },
|
||||
getDimensions: function () { return {}; }
|
||||
},
|
||||
panel : {
|
||||
setImageInfo : this.sandbox.stub(),
|
||||
scroller: {
|
||||
|
|
Loading…
Reference in a new issue