Remove FileRepoInfo API and Repo model

Repo was only used in two locations:
1. StripeButtons.set for `isCommons` - can be replaced by `descriptionUrl.includes('//commons.wikimedia.org/')`
2. EmbedFileFormatter.getSiteLink (unused)

Furthermore:
- Simplify StripeButtons (we only have one button)
- Unwrap info objects consisting of `ImageModel` and `Repo`
- Remove unused EmbedFileFormatter.getSiteLink
- Inline EmbedFileFormatter.getCaption and EmbedFileFormatter.getLinkUrl
- Fix JSDoc type `ImageModel`

Reduces mmv bundle size from 28012 to 27246.

Bug: T77349
Change-Id: Ia4388fe4d5e1d6112a992e826453cd5799a6a4b4
This commit is contained in:
Simon Legner 2024-05-29 10:54:16 +02:00
parent 82e36ddc61
commit 21438d2b22
28 changed files with 155 additions and 784 deletions

View file

@ -2,7 +2,7 @@
"modules": [
{
"resourceModule": "mmv",
"maxSize": "27.6 kB"
"maxSize": "26.8 kB"
},
{
"resourceModule": "mmv.ui.restriction",

View file

@ -47,13 +47,11 @@
"mmv/model/mmv.model.IwTitle.js",
"mmv/model/mmv.model.License.js",
"mmv/model/mmv.model.Image.js",
"mmv/model/mmv.model.Repo.js",
"mmv/model/mmv.model.Thumbnail.js",
"mmv/model/mmv.model.TaskQueue.js",
"mmv/model/mmv.model.ThumbnailWidth.js",
"mmv/provider/mmv.provider.Api.js",
"mmv/provider/mmv.provider.ImageInfo.js",
"mmv/provider/mmv.provider.FileRepoInfo.js",
"mmv/provider/mmv.provider.ThumbnailInfo.js",
"mmv/provider/mmv.provider.GuessedThumbnailInfo.js",
"mmv/provider/mmv.provider.Image.js",
@ -350,10 +348,8 @@
"tests/qunit/mmv/model/mmv.model.TaskQueue.test.js",
"tests/qunit/mmv/model/mmv.model.License.test.js",
"tests/qunit/mmv/model/mmv.model.Image.test.js",
"tests/qunit/mmv/model/mmv.model.Repo.test.js",
"tests/qunit/mmv/provider/mmv.provider.Api.test.js",
"tests/qunit/mmv/provider/mmv.provider.ImageInfo.test.js",
"tests/qunit/mmv/provider/mmv.provider.FileRepoInfo.test.js",
"tests/qunit/mmv/provider/mmv.provider.ThumbnailInfo.test.js",
"tests/qunit/mmv/provider/mmv.provider.GuessedThumbnailInfo.test.js",
"tests/qunit/mmv/provider/mmv.provider.Image.test.js",

View file

@ -16,10 +16,13 @@
"jsdoc": {
"preferredTypes": {
"Config": "Config",
"ImageModel": "ImageModel",
"DownloadDialog": "DownloadDialog",
"License": "License",
"LightboxImage": "LightboxImage",
"MultimediaViewer": "MultimediaViewer",
"Repo": "Repo",
"OptionsDialog": "OptionsDialog",
"ReuseDialog": "ReuseDialog",
"TaskQueue": "TaskQueue",
"TaskQueueLightboxImage": "TaskQueueLightboxImage",
"Thumbnail": "Thumbnail",

View file

@ -22,22 +22,6 @@ const { HtmlUtils } = require( 'mmv.bootstrap' );
* Converts data in various formats needed by the Embed sub-dialog
*/
class EmbedFileFormatter {
/**
* Returns the caption of the image (possibly a fallback generated from image metadata).
*
* @param {Object} info
* @param {Image} info.imageInfo
* @param {string} [info.caption]
* @return {string}
*/
getCaption( info ) {
if ( info.caption ) {
return HtmlUtils.htmlToText( info.caption );
} else {
return info.imageInfo.title.getNameText();
}
}
/**
* Helper function to generate thumbnail wikicode
*
@ -59,12 +43,13 @@ class EmbedFileFormatter {
* Helper function to generate thumbnail wikicode
*
* @param {Object} info
* @param {Image} info.imageInfo
* @param {ImageModel} info.imageInfo
* @param {number} [width]
* @return {string}
*/
getThumbnailWikitextFromEmbedFileInfo( info, width ) {
return this.getThumbnailWikitext( info.imageInfo.title, width, this.getCaption( info ), info.alt );
const caption = info.caption ? HtmlUtils.htmlToText( info.caption ) : info.imageInfo.title.getNameText();
return this.getThumbnailWikitext( info.imageInfo.title, width, caption, info.alt );
}
/**
@ -97,17 +82,16 @@ class EmbedFileFormatter {
/**
* Generates the plain text embed code for the image credit line.
*
* @param {Object} info
* @param {Image} info.imageInfo
* @param {ImageModel} imageInfo
* @return {string}
*/
getCreditText( info ) {
const shortURL = info.imageInfo.descriptionShortUrl;
const license = info.imageInfo.license;
getCreditText( imageInfo ) {
const shortURL = imageInfo.descriptionShortUrl;
const license = imageInfo.license;
const byline = this.getByline(
info.imageInfo.author,
info.imageInfo.source,
info.imageInfo.attribution,
imageInfo.author,
imageInfo.source,
imageInfo.attribution,
( txt ) => HtmlUtils.htmlToText( txt )
);
@ -135,23 +119,20 @@ class EmbedFileFormatter {
}
creditParams.push( shortURL );
const creditText = mw.message.apply( mw, creditParams ).plain();
return creditText;
return mw.message.apply( mw, creditParams ).plain();
}
/**
* Generates the HTML embed code for the image credit line.
*
* @param {Object} info
* @param {Image} info.imageInfo
* @param {ImageModel} imageInfo
* @return {string}
*/
getCreditHtml( info ) {
const shortURL = info.imageInfo.descriptionShortUrl;
getCreditHtml( imageInfo ) {
const shortURL = imageInfo.descriptionShortUrl;
const shortLink = HtmlUtils.makeLinkText( mw.message( 'multimediaviewer-html-embed-credit-link-text' ), { href: shortURL } );
const license = info.imageInfo.license;
const byline = this.getByline( info.imageInfo.author, info.imageInfo.source, info.imageInfo.attribution );
const license = imageInfo.license;
const byline = this.getByline( imageInfo.author, imageInfo.source, imageInfo.attribution );
if ( !byline && !license ) {
return shortLink;
@ -175,36 +156,14 @@ class EmbedFileFormatter {
}
creditParams.push( shortLink );
const creditText = mw.message.apply( mw, creditParams ).plain();
return creditText;
}
/**
* Returns HTML code for a link to the site of the image.
*
* @param {Object} info
* @param {Image} info.imageInfo
* @return {string}
*/
getSiteLink( info ) {
const siteName = info.repoInfo.displayName;
const siteUrl = info.repoInfo.getSiteLink();
if ( siteUrl ) {
return HtmlUtils.jqueryToHtml(
$( '<a>' ).prop( 'href', siteUrl ).text( siteName )
);
} else {
return siteName;
}
return mw.message.apply( mw, creditParams ).plain();
}
/**
* Generates the HTML embed code for the image.
*
* @param {Object} info
* @param {Image} info.imageInfo
* @param {ImageModel} info.imageInfo
* @param {string} imgUrl URL to the file itself.
* @param {number} [width] Width to put into the image element.
* @param {number} [height] Height to put into the image element.
@ -214,7 +173,7 @@ class EmbedFileFormatter {
return HtmlUtils.jqueryToHtml(
$( '<p>' ).append(
$( '<a>' )
.attr( 'href', this.getLinkUrl( info ) )
.attr( 'href', info.imageInfo.descriptionUrl + getMediaHash( info.imageInfo.title ) )
.append(
$( '<img>' )
.attr( 'src', imgUrl )
@ -223,21 +182,10 @@ class EmbedFileFormatter {
.attr( 'width', width )
),
$( '<br>' ),
this.getCreditHtml( info )
this.getCreditHtml( info.imageInfo )
)
);
}
/**
* Generate a link which we will be using for sharing stuff.
*
* @param {Object} info
* @param {Image} info.imageInfo
* @return {string} URL
*/
getLinkUrl( info ) {
return info.imageInfo.descriptionUrl + getMediaHash( info.imageInfo.title );
}
}
module.exports = EmbedFileFormatter;

View file

@ -51,11 +51,10 @@ class DownloadDialog extends Dialog {
/**
* Sets data needed by contained tabs and makes dialog launch link visible.
*
* @param {Image} image
* @param {Repo} repo
* @param {ImageModel} image
*/
set( image, repo ) {
this.download.set( image, repo );
set( image ) {
this.download.set( image );
this.showImageWarnings( image );
}

View file

@ -33,7 +33,7 @@ class DownloadPane extends UiElement {
this.createDownloadSection( this.$container );
this.createAttributionButton( this.$container );
/** @property {Image|null} Image the download button currently points to. */
/** @property {ImageModel|null} Image the download button currently points to. */
this.image = null;
}
@ -226,13 +226,11 @@ class DownloadPane extends UiElement {
/**
* Sets the text in the attribution input element.
*
* @param {Object} embed
* @param {Image} embed.imageInfo
* @param {Repo} embed.repoInfo
* @param {ImageModel} imageInfo
*/
setAttributionText( embed ) {
this.htmlCredit = this.formatter.getCreditHtml( embed );
this.textCredit = this.formatter.getCreditText( embed );
setAttributionText( imageInfo ) {
this.htmlCredit = this.formatter.getCreditHtml( imageInfo );
this.textCredit = this.formatter.getCreditText( imageInfo );
this.selectAttribution( this.currentAttrView );
}
@ -250,10 +248,9 @@ class DownloadPane extends UiElement {
/**
* Sets the data on the element.
*
* @param {Image} image
* @param {Repo} repo
* @param {ImageModel} image
*/
set( image, repo ) {
set( image ) {
const license = image && image.license;
const sizes = Utils.getPossibleImageSizesForHtml( image.width, image.height );
@ -268,12 +265,8 @@ class DownloadPane extends UiElement {
this.$downloadSizeMenu.val( 'original' );
this.handleSizeSwitch();
if ( image && repo ) {
const embedFileInfo = {
imageInfo: image,
repoInfo: repo
};
this.setAttributionText( embedFileInfo );
if ( image ) {
this.setAttributionText( image );
}
const attributionCtaMessage = ( license && license.needsAttribution() ) ?

View file

@ -54,15 +54,13 @@ class ReuseDialog extends Dialog {
/**
* Sets data needed by contained panes and makes dialog launch link visible.
*
* @param {Image} image
* @param {Repo} repo
* @param {ImageModel} image
* @param {string} caption
* @param {string} alt
*/
set( image, repo, caption, alt ) {
set( image, caption, alt ) {
this.share.set( image );
this.embed.set( image, repo, caption, alt );
this.embed.set( image, repo, caption );
this.embed.set( image, caption, alt );
this.showImageWarnings( image );
}

View file

@ -245,21 +245,14 @@ class Embed extends UiElement {
/**
* Sets the data on the element.
*
* @param {Image} image
* @param {Repo} repo
* @param {ImageModel} imageInfo
* @param {string} [caption]
* @param {string} [alt]
*/
set( image, repo, caption, alt ) {
const sizes = this.getSizeOptions( image.width, image.height );
set( imageInfo, caption, alt ) {
const sizes = this.getSizeOptions( imageInfo.width, imageInfo.height );
this.embedFileInfo = { imageInfo: image, repoInfo: repo };
if ( caption ) {
this.embedFileInfo.caption = caption;
}
if ( alt ) {
this.embedFileInfo.alt = alt;
}
this.embedFileInfo = { imageInfo, caption, alt };
Utils.updateSelectOptions( sizes.html, this.$embedSizeSwitchHtml.children() );
Utils.updateSelectOptions( sizes.wikitext, this.$embedSizeSwitchWikitext.children() );

View file

@ -53,7 +53,7 @@ class Share extends UiElement {
/**
* @inheritdoc
* @param {Image} image
* @param {ImageModel} image
*/
set( image ) {
const url = image.descriptionUrl + getMediaHash( image.title );

View file

@ -18,7 +18,6 @@
const { getMediaHash } = require( 'mmv.head' );
const ViewLogger = require( './logging/mmv.logging.ViewLogger.js' );
const Api = require( './provider/mmv.provider.Api.js' );
const FileRepoInfo = require( './provider/mmv.provider.FileRepoInfo.js' );
const GuessedThumbnailInfo = require( './provider/mmv.provider.GuessedThumbnailInfo.js' );
const ImageProvider = require( './provider/mmv.provider.Image.js' );
const ImageInfo = require( './provider/mmv.provider.ImageInfo.js' );
@ -26,7 +25,6 @@ const ThumbnailInfo = require( './provider/mmv.provider.ThumbnailInfo.js' );
const ImageModel = require( './model/mmv.model.Image.js' );
const IwTitle = require( './model/mmv.model.IwTitle.js' );
const License = require( './model/mmv.model.License.js' );
const { Repo, ForeignApiRepo, ForeignDbRepo } = require( './model/mmv.model.Repo.js' );
const TaskQueue = require( './model/mmv.model.TaskQueue.js' );
const Thumbnail = require( './model/mmv.model.Thumbnail.js' );
const ThumbnailWidth = require( './model/mmv.model.ThumbnailWidth.js' );
@ -82,13 +80,6 @@ class MultimediaViewer {
maxage: apiCacheFiveMinutes
} );
/**
* @property {FileRepoInfo}
* @private
*/
this.fileRepoInfoProvider = new FileRepoInfo( api,
{ maxage: apiCacheMaxAge } );
/**
* @property {ThumbnailInfo}
* @private
@ -259,8 +250,6 @@ class MultimediaViewer {
// this.preloadFullscreenThumbnail( image ); // disabled - #474
const imageWidths = this.ui.canvas.getCurrentImageWidths();
const start = Date.now();
const imagePromise = this.fetchThumbnailForLightboxImage( image, imageWidths.real );
if ( imagePromise.state() === 'pending' ) {
@ -282,13 +271,11 @@ class MultimediaViewer {
imageElement.className = `mw-mmv-final-image ${ image.filePageTitle.getExtension().toLowerCase() }`;
imageElement.alt = image.alt;
$.when( metadataPromise, pluginsPromise ).then( ( metadata ) => {
$( document ).trigger( $.Event( 'mmv-metadata', { viewer: this, image: image, imageInfo: metadata[ 0 ] } ) );
$.when( metadataPromise, pluginsPromise ).then( ( imageInfo ) => {
$( document ).trigger( $.Event( 'mmv-metadata', { viewer: this, image, imageInfo } ) );
} );
this.displayRealThumbnail( thumbnail, imageElement, imageWidths, Date.now() - start );
return $.Deferred().resolve( thumbnail, imageElement );
this.displayRealThumbnail( thumbnail, imageElement, imageWidths );
},
// fail
( error ) => {
@ -299,17 +286,15 @@ class MultimediaViewer {
metadataPromise.then(
// done
( imageInfo, repoInfo ) => {
( imageInfo ) => {
if ( this.currentIndex !== image.index ) {
return;
}
this.ui.panel.setImageInfo( image, imageInfo, repoInfo );
this.ui.panel.setImageInfo( image, imageInfo );
// File reuse steals a bunch of information from the DOM, so do it last
this.ui.setFileReuseData( imageInfo, repoInfo, image.caption, image.alt );
return $.Deferred().resolve( imageInfo, repoInfo );
this.ui.setFileReuseData( imageInfo, image.caption, image.alt );
},
// fail
( error ) => {
@ -617,17 +602,10 @@ class MultimediaViewer {
* information).
*
* @param {mw.Title} fileTitle Title of the file page for the image.
* @return {jQuery.Promise.<Image, Repo>}
* @return {jQuery.Promise.<ImageModel>}
*/
fetchSizeIndependentLightboxInfo( fileTitle ) {
const imageInfoPromise = this.imageInfoProvider.get( fileTitle );
const repoInfoPromise = this.fileRepoInfoProvider.get( fileTitle );
return $.when(
imageInfoPromise, repoInfoPromise
).then( ( imageInfo, repoInfoHash ) => {
return $.Deferred().resolve( imageInfo, repoInfoHash[ imageInfo.repo ] );
} );
return this.imageInfoProvider.get( fileTitle );
}
/**
@ -936,9 +914,6 @@ module.exports = {
CanvasButtons,
Description,
Dialog,
FileRepoInfo,
ForeignApiRepo,
ForeignDbRepo,
GuessedThumbnailInfo,
ImageInfo,
ImageModel,
@ -952,7 +927,6 @@ module.exports = {
OptionsDialog,
Permission,
ProgressBar,
Repo,
StripeButtons,
TaskQueue,
Thumbnail,

View file

@ -118,11 +118,13 @@ class LightboxInterface extends UiElement {
this.buttons = new CanvasButtons( this.$preDiv, this.$closeButton, this.$fullscreenButton );
this.canvas = new Canvas( this.$innerWrapper, this.$imageWrapper, this.$wrapper );
/** @property {DialogProxy|ReuseDialog} */
this.fileReuse = new DialogProxy( 'mmv-reuse-open', ( req ) => {
const { ReuseDialog } = req( 'mmv.ui.reuse' );
this.fileReuse = new ReuseDialog( this.$innerWrapper, this.buttons.$download, this.config );
return this.fileReuse;
} );
/** @property {DialogProxy|DownloadDialog} */
this.downloadDialog = new DialogProxy( 'mmv-download-open', ( req ) => {
const { DownloadDialog } = req( 'mmv.ui.reuse' );
this.downloadDialog = new DownloadDialog( this.$innerWrapper, this.buttons.$download, this.config );
@ -134,15 +136,14 @@ class LightboxInterface extends UiElement {
/**
* Sets up the file reuse data in the DOM
*
* @param {Image} image
* @param {Repo} repo
* @param {ImageModel} image
* @param {string} caption
* @param {string} alt
*/
setFileReuseData( image, repo, caption, alt ) {
setFileReuseData( image, caption, alt ) {
this.buttons.set( image );
this.fileReuse.set( image, repo, caption, alt );
this.downloadDialog.set( image, repo );
this.fileReuse.set( image, caption, alt );
this.downloadDialog.set( image );
}
/**

View file

@ -169,7 +169,7 @@ class ImageModel {
* @static
* @param {mw.Title} title
* @param {Object} imageInfo
* @return {Image}
* @return {ImageModel}
*/
static newFromImageInfo( title, imageInfo ) {
let name;

View file

@ -1,207 +0,0 @@
/*
* 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/>.
*/
/**
* Represents information about a single image repository
*/
class Repo {
/**
* @param {string} displayName
* @param {string} favIcon URL to the repo's favicon
* @param {boolean} isLocal
*/
constructor(
displayName,
favIcon,
isLocal
) {
/** @property {string} displayName Human-readable name of the repository */
this.displayName = displayName;
/** @property {string} favIcon An icon that represents the repository */
this.favIcon = favIcon;
/** @property {boolean} isLocal Whether the repository is the local wiki */
this.isLocal = isLocal;
}
/**
* Returns true if the repo is Wikimedia Commons.
*
* @return {boolean}
*/
isCommons() {
// there does not seem to be a sensible way to do this
return this.displayName === 'Wikimedia Commons';
}
/**
* Gets the article path for the repository.
*
* @param {boolean} absolute if true, the URL will be absolute (if false, it still might be)
* @return {string} Replace $1 with the page name you want to link to.
*/
getArticlePath( absolute ) {
let articlePath = mw.config.get( 'wgArticlePath' );
if ( absolute ) {
articlePath = mw.config.get( 'wgServer' ) + articlePath;
}
return articlePath;
}
/**
* Gets the a link to the site where the image was uploaded to.
* This is a hack and might break for wikis with exotic config; unfortunately no
* better data is provided currently.
*
* @return {string}
*/
getSiteLink() {
return this.getArticlePath( true ).replace( '$1', '' );
}
}
/**
* Represents information about a foreign API repository
*/
class ForeignApiRepo extends Repo {
/**
* @inheritdoc
* @param {string} displayName
* @param {string} favIcon
* @param {boolean} isLocal
* @param {string} apiUrl URL to the wiki's api.php
* @param {string} server Hostname for the wiki
* @param {string} articlePath Path to articles on the wiki, relative to the hostname.
*/
constructor(
displayName,
favIcon,
isLocal,
apiUrl,
server,
articlePath
) {
super( displayName, favIcon, isLocal );
/** @property {string} apiUrl URL to the wiki's api.php */
this.apiUrl = apiUrl;
/** @property {string} server Hostname for the wiki */
this.server = server;
/** @property {string} articlePath Path to articles on the wiki, relative to the hostname */
this.articlePath = articlePath;
/** @property {string} absoluteArticlePath Path to articles on the wiki, relative to nothing */
this.absoluteArticlePath = server + articlePath;
}
/**
* @override
* @inheritdoc
*/
getArticlePath() {
return this.absoluteArticlePath;
}
/**
* @override
* @inheritdoc
*/
isCommons() {
// eslint-disable-next-line security/detect-unsafe-regex
return /^(https?:)?\/\/commons\.wikimedia\.org/.test( this.server );
}
}
/**
* Represents information about a foreign, shared DB repository
*/
class ForeignDbRepo extends Repo {
/**
* @inheritdoc
* @param {string} displayName
* @param {string} favIcon
* @param {boolean} isLocal
* @param {string} descBaseUrl Base URL for description pages - should include the "File:" prefix or similar.
*/
constructor(
displayName,
favIcon,
isLocal,
descBaseUrl
) {
super( displayName, favIcon, isLocal );
/** @property {string} descBaseUrl Base URL for descriptions on the wiki - append a file's title to this to get the description page */
this.descBaseUrl = descBaseUrl;
}
/**
* @override
* @inheritdoc
*/
getArticlePath() {
return this.descBaseUrl.replace( /[^/:]*:$/, '$1' );
}
/**
* @override
* @inheritdoc
*/
isCommons() {
// eslint-disable-next-line security/detect-unsafe-regex
return /^(https?:)?\/\/commons\.wikimedia\.org/.test( this.descBaseUrl );
}
}
module.exports = {
Repo,
ForeignApiRepo,
ForeignDbRepo,
/**
* Creates a new object from repoInfo we found in an API response.
*
* @static
* @param {Object} repoInfo
* @return {Repo}
*/
newFromRepoInfo( repoInfo ) {
if ( repoInfo.apiurl ) {
return new ForeignApiRepo(
repoInfo.displayname,
repoInfo.favicon,
false,
repoInfo.apiurl,
repoInfo.server,
repoInfo.articlepath
);
} else if ( repoInfo.descBaseUrl ) {
return new ForeignDbRepo(
repoInfo.displayname,
repoInfo.favicon,
false,
repoInfo.descBaseUrl
);
} else {
return new Repo( repoInfo.displayname, repoInfo.favicon, repoInfo.local );
}
}
};

View file

@ -1,61 +0,0 @@
/*
* 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/>.
*/
const Api = require( './mmv.provider.Api.js' );
const { newFromRepoInfo } = require( '../model/mmv.model.Repo.js' );
/**
* Gets file repo information.
*/
class FileRepoInfo extends Api {
/**
* @param {mw.Api} api
* @param {Object} [options]
* @param {number} [options.maxage] cache expiration time, in seconds
* Will be used for both client-side cache (maxage) and reverse proxies (s-maxage)
*/
constructor( api, options ) {
super( api, options );
}
/**
* Runs an API GET request to get the repo info.
*
* @return {jQuery.Promise.<Object.<string, Repo>>} a promise which resolves to
* a hash of Repo objects, indexed by repo names.
*/
get() {
return this.getCachedPromise( '*', () => {
return this.apiGetWithMaxAge( {
formatversion: 2,
action: 'query',
meta: 'filerepoinfo',
uselang: 'content'
} ).then( ( data ) => {
return this.getQueryField( 'repos', data );
} ).then( ( reposArray ) => {
const reposHash = {};
reposArray.forEach( ( repo ) => {
reposHash[ repo.name ] = newFromRepoInfo( repo );
} );
return reposHash;
} );
} );
}
}
module.exports = FileRepoInfo;

View file

@ -16,7 +16,6 @@
*/
const Api = require( './mmv.provider.Api.js' );
const FileRepoInfo = require( './mmv.provider.FileRepoInfo.js' );
const GuessedThumbnailInfo = require( './mmv.provider.GuessedThumbnailInfo.js' );
const ImageProvider = require( './mmv.provider.Image.js' );
const ImageInfo = require( './mmv.provider.ImageInfo.js' );
@ -24,7 +23,6 @@ const ThumbnailInfo = require( './mmv.provider.ThumbnailInfo.js' );
module.exports = {
Api,
FileRepoInfo,
GuessedThumbnailInfo,
ImageInfo,
ImageProvider,

View file

@ -247,7 +247,7 @@ class CanvasButtons extends UiElement {
}
/**
* @param {Image} image
* @param {ImageModel} image
*/
set( image ) {
this.$reuse.prop( 'href', image.descriptionUrl );

View file

@ -191,7 +191,7 @@ class Dialog extends UiElement {
}
/**
* @param {Image} image
* @param {ImageModel} image
* @return {string[]}
*/
getImageWarnings( image ) {
@ -215,7 +215,7 @@ class Dialog extends UiElement {
}
/**
* @param {Image} image
* @param {ImageModel} image
*/
showImageWarnings( image ) {
const warnings = this.getImageWarnings( image );

View file

@ -388,7 +388,7 @@ class MetadataPanel extends UiElement {
* - the filename (without extension)
*
* @param {LightboxImage} image
* @param {Image} imageData
* @param {ImageModel} imageData
*/
setTitle( image, imageData ) {
let title;
@ -662,7 +662,7 @@ class MetadataPanel extends UiElement {
/**
* Sets location data in the interface.
*
* @param {Image} imageData
* @param {ImageModel} imageData
*/
setLocationData( imageData ) {
if ( !imageData.hasCoords() ) {
@ -723,10 +723,9 @@ class MetadataPanel extends UiElement {
* Set all the image information in the panel
*
* @param {LightboxImage} image
* @param {Image} imageData
* @param {Repo} repoData
* @param {ImageModel} imageData
*/
setImageInfo( image, imageData, repoData ) {
setImageInfo( image, imageData ) {
if ( imageData.creationDateTime ) {
this.$datetimeCreated.text(
mw.msg( 'multimediaviewer-datetime-created', this.formatDate( imageData.creationDateTime ) )
@ -740,7 +739,7 @@ class MetadataPanel extends UiElement {
this.$datetimeUpdatedLi.removeClass( 'empty' );
}
this.buttons.set( imageData, repoData );
this.buttons.set( imageData );
this.description.set( imageData.description, image.caption );
this.setLicense( imageData.license, imageData.descriptionUrl );

View file

@ -34,87 +34,42 @@ class StripeButtons extends UiElement {
.appendTo( $container );
/**
* This holds the actual buttons.
*
* @property {Object.<string, jQuery>}
* A button linking to the file description page.
*/
this.buttons = {};
this.initDescriptionPageButton();
}
/**
* Creates a button linking to the file description page.
*
* @protected
*/
initDescriptionPageButton() {
this.buttons.$descriptionPage = $( '<a>' )
this.$descriptionPage = $( '<a>' )
.addClass( 'mw-mmv-stripe-button empty mw-mmv-description-page-button cdx-button cdx-button--weight-primary cdx-button--action-progressive cdx-button--size-large cdx-button--fake-button cdx-button--fake-button--enabled' )
// elements are right-floated so we use prepend instead of append to keep the order
.prependTo( this.$buttonContainer );
}
/**
* Runs code for each button, similarly to $.each.
*
* @protected
* @param {function(jQuery, string)} callback a function that will be called with each button
*/
eachButton( callback ) {
for ( const buttonName in this.buttons ) {
callback( this.buttons[ buttonName ], buttonName );
}
}
/**
* @inheritdoc
* @param {Image} imageInfo
* @param {Repo} repoInfo
* @param {ImageModel} imageInfo
*/
set( imageInfo, repoInfo ) {
this.eachButton( ( $button ) => {
$button.removeClass( 'empty' );
} );
this.setDescriptionPageButton( imageInfo, repoInfo );
}
/**
* Updates the button linking to the file page.
*
* @protected
* @param {Image} imageInfo
* @param {Repo} repoInfo
*/
setDescriptionPageButton( imageInfo, repoInfo ) {
const $button = this.buttons.$descriptionPage;
let isCommons = repoInfo.isCommons();
set( imageInfo ) {
let descriptionUrl = imageInfo.descriptionUrl;
let isCommons = String( descriptionUrl ).includes( '//commons.wikimedia.org/' );
if ( repoInfo.isLocal === false && imageInfo.pageID ) {
if ( imageInfo.pageID ) {
// The file has a local description page, override the description URL
descriptionUrl = imageInfo.title.getUrl();
isCommons = false;
}
$button.empty()
this.$descriptionPage.empty()
.append( $( '<span>' ).addClass( 'cdx-button__icon' ) )
.append( mw.msg( 'multimediaviewer-repository-local' ) )
.attr( 'href', descriptionUrl );
$button.toggleClass( 'mw-mmv-repo-button-commons', isCommons );
.attr( 'href', descriptionUrl )
.removeClass( 'empty' )
.toggleClass( 'mw-mmv-repo-button-commons', isCommons );
}
/**
* @inheritdoc
*/
empty() {
this.eachButton( ( $button ) => {
$button.addClass( 'empty' );
} );
this.buttons.$descriptionPage.attr( { href: null, title: null, 'original-title': null } )
this.$descriptionPage.attr( { href: null, title: null, 'original-title': null } )
.addClass( 'empty' )
.removeClass( 'mw-mmv-repo-button-commons' );
}
}

View file

@ -31,10 +31,8 @@ require( './model/mmv.model.IwTitle.test.js' );
require( './model/mmv.model.TaskQueue.test.js' );
require( './model/mmv.model.License.test.js' );
require( './model/mmv.model.Image.test.js' );
require( './model/mmv.model.Repo.test.js' );
require( './provider/mmv.provider.Api.test.js' );
require( './provider/mmv.provider.ImageInfo.test.js' );
require( './provider/mmv.provider.FileRepoInfo.test.js' );
require( './provider/mmv.provider.ThumbnailInfo.test.js' );
require( './provider/mmv.provider.GuessedThumbnailInfo.test.js' );
require( './provider/mmv.provider.Image.test.js' );

View file

@ -1,4 +1,4 @@
const { License, ImageModel, Repo } = require( 'mmv' );
const { License, ImageModel } = require( 'mmv' );
const { EmbedFileFormatter } = require( 'mmv.ui.reuse' );
( function () {
@ -33,16 +33,8 @@ const { EmbedFileFormatter } = require( 'mmv.ui.reuse' );
options.authorCount,
license
);
const repoInfo = {
displayName: options.siteName,
getSiteLink: function () {
return options.siteUrl;
}
};
return {
imageInfo: imageInfo,
repoInfo: repoInfo,
caption: options.caption
};
}
@ -79,17 +71,6 @@ const { EmbedFileFormatter } = require( 'mmv.ui.reuse' );
assert.strictEqual( byline, '<span class="mw-mmv-source">Iliad</span>', 'Source found in bylines.' );
} );
QUnit.test( 'getSiteLink():', function ( assert ) {
const repoInfo = new Repo( 'Wikipedia', '//wikipedia.org/favicon.ico', true );
const info = { imageInfo: {}, repoInfo: repoInfo };
const formatter = new EmbedFileFormatter();
const siteUrl = repoInfo.getSiteLink();
const siteLink = formatter.getSiteLink( info );
assert.notStrictEqual( siteLink.indexOf( 'Wikipedia' ), -1, 'Site name is present in site link' );
assert.notStrictEqual( siteLink.indexOf( siteUrl ), -1, 'Site URL is present in site link' );
} );
QUnit.test( 'getThumbnailHtml():', function ( assert ) {
const formatter = new EmbedFileFormatter();
const titleText = 'Music Room';
@ -224,47 +205,37 @@ const { EmbedFileFormatter } = require( 'mmv.ui.reuse' );
const formatter = new EmbedFileFormatter();
let txt = formatter.getCreditText( {
repoInfo: {
displayName: 'Localcommons'
},
imageInfo: {
author,
source,
descriptionShortUrl: 'link',
title: {
getNameText: function () {
return 'Image Title';
}
author,
source,
descriptionShortUrl: 'link',
title: {
getNameText: function () {
return 'Image Title';
}
}
} );
}
);
assert.strictEqual( txt, '(multimediaviewer-text-embed-credit-text-b: (multimediaviewer-credit: Homer, Iliad), link)', 'Sense check' );
txt = formatter.getCreditText( {
repoInfo: {
displayName: 'Localcommons'
},
imageInfo: {
author,
source,
descriptionShortUrl: 'link',
title: {
getNameText: function () {
return 'Image Title';
}
},
license: {
getShortName: function () {
return 'WTFPL v2';
},
longName: 'Do What the Fuck You Want Public License Version 2',
isFree: this.sandbox.stub().returns( true )
author,
source,
descriptionShortUrl: 'link',
title: {
getNameText: function () {
return 'Image Title';
}
},
license: {
getShortName: function () {
return 'WTFPL v2';
},
longName: 'Do What the Fuck You Want Public License Version 2',
isFree: this.sandbox.stub().returns( true )
}
} );
}
);
assert.strictEqual( txt, '(multimediaviewer-text-embed-credit-text-bl: (multimediaviewer-credit: Homer, Iliad), WTFPL v2, link)', 'License message works' );
} );
@ -275,24 +246,16 @@ const { EmbedFileFormatter } = require( 'mmv.ui.reuse' );
const formatter = new EmbedFileFormatter();
let html = formatter.getCreditHtml( {
repoInfo: {
displayName: 'Localcommons',
getSiteLink: function () {
return 'quux';
}
},
imageInfo: {
author,
source,
descriptionShortUrl: 'some link',
title: {
getNameText: function () {
return 'Image Title';
}
author,
source,
descriptionShortUrl: 'some link',
title: {
getNameText: function () {
return 'Image Title';
}
}
} );
}
);
assert.strictEqual(
html,
@ -301,31 +264,23 @@ const { EmbedFileFormatter } = require( 'mmv.ui.reuse' );
);
html = formatter.getCreditHtml( {
repoInfo: {
displayName: 'Localcommons',
getSiteLink: function () {
return 'quux';
author,
source,
descriptionShortUrl: 'some link',
title: {
getNameText: function () {
return 'Image Title';
}
},
imageInfo: {
author,
source,
descriptionShortUrl: 'some link',
title: {
getNameText: function () {
return 'Image Title';
}
license: {
getShortLink: function () {
return '<a href="http://www.wtfpl.net/">WTFPL v2</a>';
},
license: {
getShortLink: function () {
return '<a href="http://www.wtfpl.net/">WTFPL v2</a>';
},
longName: 'Do What the Fuck You Want Public License Version 2',
isFree: this.sandbox.stub().returns( true )
}
longName: 'Do What the Fuck You Want Public License Version 2',
isFree: this.sandbox.stub().returns( true )
}
} );
}
);
assert.strictEqual(
html,

View file

@ -398,7 +398,6 @@ const { MultimediaViewerBootstrap } = require( 'mmv.bootstrap' );
viewer.imageProvider.get = () => $.Deferred().reject();
viewer.imageInfoProvider.get = () => $.Deferred().reject();
viewer.thumbnailInfoProvider.get = () => $.Deferred().reject();
viewer.fileRepoInfoProvider.get = () => $.Deferred().reject();
viewer.preloadFullscreenThumbnail = function () {};
viewer.initWithThumbs( [] );

View file

@ -1,128 +0,0 @@
/*
* 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/>.
*/
const { FileRepoInfo } = require( 'mmv' );
( function () {
QUnit.module( 'mmv.provider.FileRepoInfo', QUnit.newMwEnvironment() );
QUnit.test( 'FileRepoInfo constructor sense check', function ( assert ) {
const api = { get: function () {} };
const fileRepoInfoProvider = new FileRepoInfo( api );
assert.true( fileRepoInfoProvider instanceof FileRepoInfo );
} );
QUnit.test( 'FileRepoInfo get test', function ( assert ) {
let apiCallCount = 0;
const api = { get: function () {
apiCallCount++;
return $.Deferred().resolve( {
query: {
repos: [
{
name: 'shared',
displayname: 'Wikimedia Commons',
rootUrl: '//upload.beta.wmflabs.org/wikipedia/commons',
local: false,
url: '//upload.beta.wmflabs.org/wikipedia/commons',
thumbUrl: '//upload.beta.wmflabs.org/wikipedia/commons/thumb',
initialCapital: true,
descBaseUrl: '//commons.wikimedia.beta.wmflabs.org/wiki/File:',
scriptDirUrl: '//commons.wikimedia.beta.wmflabs.org/w',
fetchDescription: true,
favicon: 'http://en.wikipedia.org/favicon.ico'
},
{
name: 'wikimediacommons',
displayname: 'Wikimedia Commons',
rootUrl: '//upload.beta.wmflabs.org/wikipedia/en',
local: false,
url: '//upload.beta.wmflabs.org/wikipedia/en',
thumbUrl: '//upload.beta.wmflabs.org/wikipedia/en/thumb',
initialCapital: true,
scriptDirUrl: 'http://commons.wikimedia.org/w',
fetchDescription: true,
descriptionCacheExpiry: 43200,
apiurl: 'http://commons.wikimedia.org/w/api.php',
articlepath: '/wiki/$1',
server: '//commons.wikimedia.org',
favicon: '//commons.wikimedia.org/favicon.ico'
},
{
name: 'local',
displayname: null,
rootUrl: '//upload.beta.wmflabs.org/wikipedia/en',
local: true,
url: '//upload.beta.wmflabs.org/wikipedia/en',
thumbUrl: '//upload.beta.wmflabs.org/wikipedia/en/thumb',
initialCapital: true,
scriptDirUrl: '/w',
favicon: 'http://en.wikipedia.org/favicon.ico'
}
]
}
} );
} };
const fileRepoInfoProvider = new FileRepoInfo( api );
return fileRepoInfoProvider.get().then( function ( repos ) {
assert.strictEqual( repos.shared.displayName,
'Wikimedia Commons', 'displayName is set correctly' );
assert.strictEqual( repos.shared.favIcon,
'http://en.wikipedia.org/favicon.ico', 'favIcon is set correctly' );
assert.strictEqual( repos.shared.isLocal, false, 'isLocal is set correctly' );
assert.strictEqual( repos.shared.descBaseUrl,
'//commons.wikimedia.beta.wmflabs.org/wiki/File:', 'descBaseUrl is set correctly' );
assert.strictEqual( repos.wikimediacommons.displayName,
'Wikimedia Commons', 'displayName is set correctly' );
assert.strictEqual( repos.wikimediacommons.favIcon,
'//commons.wikimedia.org/favicon.ico', 'favIcon is set correctly' );
assert.strictEqual( repos.wikimediacommons.isLocal, false, 'isLocal is set correctly' );
assert.strictEqual( repos.wikimediacommons.apiUrl,
'http://commons.wikimedia.org/w/api.php', 'apiUrl is set correctly' );
assert.strictEqual( repos.wikimediacommons.server,
'//commons.wikimedia.org', 'server is set correctly' );
assert.strictEqual( repos.wikimediacommons.articlePath,
'/wiki/$1', 'articlePath is set correctly' );
assert.strictEqual( repos.local.displayName, null, 'displayName is set correctly' );
assert.strictEqual( repos.local.favIcon,
'http://en.wikipedia.org/favicon.ico', 'favIcon is set correctly' );
assert.strictEqual( repos.local.isLocal, true, 'isLocal is set correctly' );
} ).then( function () {
// call the data provider a second time to check caching
return fileRepoInfoProvider.get();
} ).then( function () {
assert.strictEqual( apiCallCount, 1 );
} );
} );
QUnit.test( 'FileRepoInfo fail test', function ( assert ) {
const api = { get: function () {
return $.Deferred().resolve( {} );
} };
const done = assert.async();
const fileRepoInfoProvider = new FileRepoInfo( api );
fileRepoInfoProvider.get().fail( function () {
assert.true( true, 'promise rejected when no data is returned' );
done();
} );
} );
}() );

View file

@ -48,6 +48,7 @@ const { Download: DownloadPane, Utils } = require( 'mmv.ui.reuse' );
assert.true( true, 'Menu options updated.' );
};
download.setAttributionText = () => {};
download.set( image );
assert.strictEqual( download.imageExtension, 'jpg', 'Image extension is set correctly.' );

View file

@ -122,17 +122,9 @@ QUnit.test( '.setImageInfo()', function ( assert ) {
return false;
}
};
const repoData = {
getArticlePath: function () {
return 'Foo';
},
isCommons: function () {
return false;
}
};
const clock = this.sandbox.useFakeTimers();
panel.setImageInfo( image, imageData, repoData );
panel.setImageInfo( image, imageData );
assert.strictEqual( panel.$title.text(), title, 'Title is correctly set' );
assert.notStrictEqual( panel.$credit.text(), '', 'Default credit is shown' );
@ -153,7 +145,7 @@ QUnit.test( '.setImageInfo()', function ( assert ) {
'http://creativecommons.org/licenses/by-sa/2.0/' );
imageData.restrictions = [ 'trademarked', 'default', 'insignia' ];
panel.setImageInfo( image, imageData, repoData );
panel.setImageInfo( image, imageData );
const creditPopupText = panel.creditField.$element.attr( 'original-title' );
clock.tick( 10 );
@ -170,7 +162,7 @@ QUnit.test( '.setImageInfo()', function ( assert ) {
assert.true( panel.$restrictions.children().last().children().hasClass( 'mw-mmv-restriction-default' ), 'Default restriction is correctly displayed last' );
imageData.creationDateTime = undefined;
panel.setImageInfo( image, imageData, repoData );
panel.setImageInfo( image, imageData );
clock.tick( 10 );
assert.false( panel.$datetimeUpdatedLi.hasClass( 'empty' ), 'Date/Time is not empty' );

View file

@ -15,7 +15,6 @@
* along with MultimediaViewer. If not, see <http://www.gnu.org/licenses/>.
*/
const { Repo } = require( 'mmv' );
const { ReuseDialog } = require( 'mmv.ui.reuse' );
( function () {
@ -144,13 +143,7 @@ const { ReuseDialog } = require( 'mmv.ui.reuse' );
width: 100,
height: 80
};
const embedFileInfo = {
imageInfo: title,
repoInfo: src,
caption: url
};
reuseDialog.set( image, embedFileInfo );
reuseDialog.set( image, 'caption' );
reuseDialog.empty();
assert.true( true, 'Set/empty did not cause an error.' );
@ -169,9 +162,8 @@ const { ReuseDialog } = require( 'mmv.ui.reuse' );
width: 100,
height: 80
};
const repoInfo = new Repo( 'Wikipedia', '//wikipedia.org/favicon.ico', true );
reuseDialog.set( image, repoInfo );
reuseDialog.set( image, 'caption' );
reuseDialog.setValues = undefined;
assert.strictEqual( reuseDialog.isOpen, false, 'Dialog closed by default.' );

View file

@ -117,19 +117,19 @@ const { Embed, Utils } = require( 'mmv.ui.reuse' );
const url = 'https://upload.wikimedia.org/wikipedia/commons/3/3a/Foobar.jpg';
const thumbUrl = 'https://upload.wikimedia.org/wikipedia/thumb/Foobar.jpg';
const imageInfo = { url, title };
const repoInfo = {};
const caption = '-';
const alt = undefined;
const info = {
imageInfo: imageInfo,
repoInfo: repoInfo,
caption: caption
imageInfo,
caption,
alt
};
let width = 10;
const height = 20;
embed.resetCurrentSizeMenuToDefault = () => {};
embed.set( imageInfo, repoInfo, caption );
embed.set( imageInfo, caption );
// Small image, no thumbnail info is passed
embed.formatter.getThumbnailHtml = function ( i, u, w, h ) {
@ -172,18 +172,18 @@ const { Embed, Utils } = require( 'mmv.ui.reuse' );
const url = 'https://upload.wikimedia.org/wikipedia/commons/3/3a/Foobar.jpg';
const imageInfo = { url, title };
const repoInfo = {};
const caption = '-';
const alt = undefined;
const info = {
imageInfo: imageInfo,
repoInfo: repoInfo,
caption: caption
imageInfo,
caption,
alt
};
const width = 10;
embed.resetCurrentSizeMenuToDefault = () => {};
embed.set( imageInfo, repoInfo, caption );
embed.set( imageInfo, caption );
embed.formatter.getThumbnailWikitextFromEmbedFileInfo = function ( i, w ) {
assert.deepEqual( i, info, 'EmbedFileInfo passed correctly.' );
@ -231,14 +231,6 @@ const { Embed, Utils } = require( 'mmv.ui.reuse' );
QUnit.test( 'set():', function ( assert ) {
const embed = new Embed( $qf );
const title = mw.Title.newFromText( 'File:Foobar.jpg' );
const src = 'https://upload.wikimedia.org/wikipedia/commons/3/3a/Foobar.jpg';
const url = 'https://commons.wikimedia.org/wiki/File:Foobar.jpg';
const embedFileInfo = {
imageInfo: title,
repoInfo: src,
caption: url
};
const width = 15;
const height = 20;
@ -259,7 +251,7 @@ const { Embed, Utils } = require( 'mmv.ui.reuse' );
assert.false( $.isPlainObject( embed.embedFileInfo ), 'embedFileInfo not set yet.' );
embed.set( { width: width, height: height }, embedFileInfo );
embed.set( { width, height }, 'caption' );
assert.true( $.isPlainObject( embed.embedFileInfo ), 'embedFileInfo set.' );
@ -298,20 +290,12 @@ const { Embed, Utils } = require( 'mmv.ui.reuse' );
QUnit.test( 'attach()/unattach():', function ( assert ) {
const embed = new Embed( $qf );
const title = mw.Title.newFromText( 'File:Foobar.jpg' );
const src = 'https://upload.wikimedia.org/wikipedia/commons/3/3a/Foobar.jpg';
const url = 'https://commons.wikimedia.org/wiki/File:Foobar.jpg';
const embedFileInfo = {
imageInfo: title,
repoInfo: src,
caption: url
};
const width = 15;
const height = 20;
embed.resetCurrentSizeMenuToDefault = () => {};
embed.set( { width: width, height: height }, embedFileInfo );
embed.set( { width, height }, 'caption' );
embed.handleTypeSwitch = function () {
assert.true( false, 'handleTypeSwitch should not have been called.' );

View file

@ -33,13 +33,13 @@ const { StripeButtons } = require( 'mmv' );
let buttons = createStripeButtons();
assert.true( buttons instanceof StripeButtons, 'UI element is created.' );
assert.strictEqual( buttons.buttons.$descriptionPage.length, 1, 'File page button created for anon.' );
assert.strictEqual( buttons.$descriptionPage.length, 1, 'File page button created for anon.' );
// now pretend we are logged in
mw.user.isAnon = () => false;
buttons = createStripeButtons();
assert.strictEqual( buttons.buttons.$descriptionPage.length, 1, 'File page button created for logged in.' );
assert.strictEqual( buttons.$descriptionPage.length, 1, 'File page button created for logged in.' );
mw.user.isAnon = oldMwUserIsAnon;
} );
@ -47,14 +47,8 @@ const { StripeButtons } = require( 'mmv' );
QUnit.test( 'set()/empty() sense test:', function ( assert ) {
const buttons = createStripeButtons();
const fakeImageInfo = { descriptionUrl: '//commons.wikimedia.org/wiki/File:Foo.jpg' };
const fakeRepoInfo = {
displayName: 'Wikimedia Commons',
isCommons: function () {
return true;
}
};
buttons.set( fakeImageInfo, fakeRepoInfo );
buttons.set( fakeImageInfo );
buttons.empty();
assert.true( true, 'No error on set()/empty().' );
@ -63,30 +57,25 @@ const { StripeButtons } = require( 'mmv' );
QUnit.test( 'Description page button', function ( assert ) {
const $qf = $( '#qunit-fixture' );
const buttons = new StripeButtons( $qf );
const $button = buttons.buttons.$descriptionPage;
const $button = buttons.$descriptionPage;
const descriptionUrl = 'http://example.com/desc';
const descriptionUrlCommons = 'https://commons.wikimedia.org/desc';
const descriptionUrl2 = 'http://example.com/different-desc';
const imageInfo = { descriptionUrl: descriptionUrl };
const repoInfo = {
isCommons: function () {
return false;
}
};
buttons.setDescriptionPageButton( imageInfo, repoInfo );
buttons.set( { descriptionUrl } );
assert.strictEqual( $button.hasClass( 'mw-mmv-repo-button-commons' ), false, 'Button does not have commons class non-Commons files' );
assert.strictEqual( $button.find( 'a' ).addBack().filter( 'a' ).attr( 'href' ), descriptionUrl, 'Description page link is correct' );
repoInfo.isCommons = () => true;
buttons.setDescriptionPageButton( imageInfo, repoInfo );
buttons.set( { descriptionUrl: descriptionUrlCommons } );
assert.strictEqual( $button.hasClass( 'mw-mmv-repo-button-commons' ), true, 'Button commons class for Commons files' );
imageInfo.pageID = 1;
imageInfo.title = { getUrl: () => descriptionUrl2 };
repoInfo.isLocal = false;
buttons.setDescriptionPageButton( imageInfo, repoInfo );
buttons.set( {
descriptionUrl,
pageID: 1,
title: { getUrl: () => descriptionUrl2 }
} );
assert.strictEqual(
$button.hasClass( 'mw-mmv-repo-button-commons' ), false,