mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/MultimediaViewer
synced 2024-11-24 00:03:56 +00:00
ThumbnailInfo: support multi lingual SVG
Bug: T208564 Change-Id: Icf082ca0dc94bc4739fd31b795de76f8a0083b70
This commit is contained in:
parent
4e1c2e841f
commit
4672f2eb57
|
@ -2,7 +2,7 @@
|
||||||
"modules": [
|
"modules": [
|
||||||
{
|
{
|
||||||
"resourceModule": "mmv",
|
"resourceModule": "mmv",
|
||||||
"maxSize": "26.6 kB"
|
"maxSize": "26.9 kB"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"resourceModule": "mmv.ui.restriction",
|
"resourceModule": "mmv.ui.restriction",
|
||||||
|
|
|
@ -206,7 +206,7 @@ class MultimediaViewer {
|
||||||
|
|
||||||
this.currentIndex = image.index;
|
this.currentIndex = image.index;
|
||||||
|
|
||||||
this.currentImageFileTitle = image.filePageTitle;
|
this.currentImage = image;
|
||||||
|
|
||||||
if ( !this.isOpen ) {
|
if ( !this.isOpen ) {
|
||||||
$( document ).trigger( $.Event( 'mmv-setup-overlay' ) );
|
$( document ).trigger( $.Event( 'mmv-setup-overlay' ) );
|
||||||
|
@ -632,9 +632,9 @@ class MultimediaViewer {
|
||||||
guessing = true;
|
guessing = true;
|
||||||
thumbnailPromise = this.guessedThumbnailInfoProvider.get(
|
thumbnailPromise = this.guessedThumbnailInfoProvider.get(
|
||||||
fileTitle, sampleUrl, width, originalWidth, originalHeight
|
fileTitle, sampleUrl, width, originalWidth, originalHeight
|
||||||
).then( null, () => this.thumbnailInfoProvider.get( fileTitle, width ) );
|
).then( null, () => this.thumbnailInfoProvider.get( fileTitle, sampleUrl, width ) );
|
||||||
} else {
|
} else {
|
||||||
thumbnailPromise = this.thumbnailInfoProvider.get( fileTitle, width );
|
thumbnailPromise = this.thumbnailInfoProvider.get( fileTitle, sampleUrl, width );
|
||||||
}
|
}
|
||||||
|
|
||||||
imagePromise = thumbnailPromise.then( ( thumbnail ) => this.imageProvider.get( thumbnail.url ) );
|
imagePromise = thumbnailPromise.then( ( thumbnail ) => this.imageProvider.get( thumbnail.url ) );
|
||||||
|
@ -644,7 +644,7 @@ class MultimediaViewer {
|
||||||
// As a side effect this introduces an extra (harmless) retry of a failed thumbnailInfoProvider.get call
|
// As a side effect this introduces an extra (harmless) retry of a failed thumbnailInfoProvider.get call
|
||||||
// because thumbnailInfoProvider.get is already called above when guessedThumbnailInfoProvider.get fails.
|
// because thumbnailInfoProvider.get is already called above when guessedThumbnailInfoProvider.get fails.
|
||||||
imagePromise = imagePromise
|
imagePromise = imagePromise
|
||||||
.then( null, () => this.thumbnailInfoProvider.get( fileTitle, width )
|
.then( null, () => this.thumbnailInfoProvider.get( fileTitle, sampleUrl, width )
|
||||||
.then( ( thumbnail ) => this.imageProvider.get( thumbnail.url ) ) );
|
.then( ( thumbnail ) => this.imageProvider.get( thumbnail.url ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -748,7 +748,7 @@ class MultimediaViewer {
|
||||||
*/
|
*/
|
||||||
setTitle() {
|
setTitle() {
|
||||||
// update title after route change, see T225387
|
// update title after route change, see T225387
|
||||||
document.title = this.createDocumentTitle( this.currentImageFileTitle );
|
document.title = this.createDocumentTitle( this.currentImage && this.currentImage.filePageTitle );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -813,13 +813,13 @@ class MultimediaViewer {
|
||||||
} ).on( 'mmv-resize-end.mmvp', () => {
|
} ).on( 'mmv-resize-end.mmvp', () => {
|
||||||
this.resize( this.ui );
|
this.resize( this.ui );
|
||||||
} ).on( 'mmv-request-thumbnail.mmvp', ( e, size ) => {
|
} ).on( 'mmv-request-thumbnail.mmvp', ( e, size ) => {
|
||||||
if ( this.currentImageFileTitle ) {
|
if ( this.currentImage && this.currentImage.filePageTitle ) {
|
||||||
return this.thumbnailInfoProvider.get( this.currentImageFileTitle, size );
|
return this.thumbnailInfoProvider.get( this.currentImage.filePageTitle, this.currentImage.src, size );
|
||||||
} else {
|
} else {
|
||||||
return $.Deferred().reject();
|
return $.Deferred().reject();
|
||||||
}
|
}
|
||||||
} ).on( 'mmv-viewfile.mmvp', () => {
|
} ).on( 'mmv-viewfile.mmvp', () => {
|
||||||
this.imageInfoProvider.get( this.currentImageFileTitle ).done( ( imageInfo ) => {
|
this.imageInfoProvider.get( this.currentImage.filePageTitle ).done( ( imageInfo ) => {
|
||||||
document.location = imageInfo.url;
|
document.location = imageInfo.url;
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
|
@ -42,12 +42,15 @@ class ThumbnailInfo extends Api {
|
||||||
* is smaller).
|
* is smaller).
|
||||||
*
|
*
|
||||||
* @param {mw.Title} file
|
* @param {mw.Title} file
|
||||||
|
* @param {string} sampleUrl a thumbnail URL for the same file (but with different size).
|
||||||
* @param {number} width thumbnail width in pixels
|
* @param {number} width thumbnail width in pixels
|
||||||
* @param {number} height thumbnail height in pixels
|
* @param {number} height thumbnail height in pixels
|
||||||
* @return {jQuery.Promise.<Thumbnail>}
|
* @return {jQuery.Promise.<Thumbnail>}
|
||||||
*/
|
*/
|
||||||
get( file, width, height ) {
|
get( file, sampleUrl, width, height ) {
|
||||||
const cacheKey = `${ file.getPrefixedDb() }|${ width || '' }|${ height || '' }`;
|
const match = sampleUrl.match( /(lang|page)([\d\-a-z]+)-(\d+)px/ ); // multi lingual SVG or PDF page
|
||||||
|
const iiurlparam = match ? `${ match[ 1 ] }${ match[ 2 ] }-${ width }px` : undefined;
|
||||||
|
const cacheKey = [ file.getPrefixedDb(), width || '', height || '', iiurlparam || '' ].join();
|
||||||
|
|
||||||
return this.getCachedPromise( cacheKey, () => this.apiGetWithMaxAge( {
|
return this.getCachedPromise( cacheKey, () => this.apiGetWithMaxAge( {
|
||||||
formatversion: 2,
|
formatversion: 2,
|
||||||
|
@ -55,6 +58,7 @@ class ThumbnailInfo extends Api {
|
||||||
prop: 'imageinfo',
|
prop: 'imageinfo',
|
||||||
titles: file.getPrefixedDb(),
|
titles: file.getPrefixedDb(),
|
||||||
iiprop: 'url',
|
iiprop: 'url',
|
||||||
|
iiurlparam,
|
||||||
iiurlwidth: width,
|
iiurlwidth: width,
|
||||||
iiurlheight: height
|
iiurlheight: height
|
||||||
} ).then( ( data ) => this.getQueryPage( data ) ).then( ( page ) => {
|
} ).then( ( data ) => this.getQueryPage( data ) ).then( ( page ) => {
|
||||||
|
|
|
@ -739,7 +739,7 @@ class MetadataPanel extends UiElement {
|
||||||
this.$datetimeUpdatedLi.removeClass( 'empty' );
|
this.$datetimeUpdatedLi.removeClass( 'empty' );
|
||||||
}
|
}
|
||||||
|
|
||||||
this.buttons.set( imageData );
|
this.buttons.set( image, imageData );
|
||||||
this.description.set( imageData.description, image.caption );
|
this.description.set( imageData.description, image.caption );
|
||||||
|
|
||||||
this.setLicense( imageData.license, imageData.descriptionUrl );
|
this.setLicense( imageData.license, imageData.descriptionUrl );
|
||||||
|
|
|
@ -44,16 +44,29 @@ class StripeButtons extends UiElement {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
|
* @param {LightboxImage} image
|
||||||
* @param {ImageModel} imageInfo
|
* @param {ImageModel} imageInfo
|
||||||
*/
|
*/
|
||||||
set( imageInfo ) {
|
set( image, imageInfo ) {
|
||||||
|
const match = image && image.src ?
|
||||||
|
image.src.match( /(lang|page)([\d\-a-z]+)-(\d+)px/ ) : // multi lingual SVG or PDF page
|
||||||
|
null;
|
||||||
|
const params = {};
|
||||||
|
if ( match ) {
|
||||||
|
params[ match[ 1 ] ] = match[ 2 ];
|
||||||
|
}
|
||||||
|
|
||||||
let descriptionUrl = imageInfo.descriptionUrl;
|
let descriptionUrl = imageInfo.descriptionUrl;
|
||||||
let isCommons = String( descriptionUrl ).includes( '//commons.wikimedia.org/' );
|
let isCommons = String( descriptionUrl ).includes( '//commons.wikimedia.org/' );
|
||||||
|
|
||||||
if ( imageInfo.pageID ) {
|
if ( imageInfo.pageID ) {
|
||||||
// The file has a local description page, override the description URL
|
// The file has a local description page, override the description URL
|
||||||
descriptionUrl = imageInfo.title.getUrl();
|
descriptionUrl = imageInfo.title.getUrl( params );
|
||||||
isCommons = false;
|
isCommons = false;
|
||||||
|
} else {
|
||||||
|
const parsedUrl = new mw.Uri( descriptionUrl );
|
||||||
|
parsedUrl.extend( params );
|
||||||
|
descriptionUrl = parsedUrl.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$descriptionPage.empty()
|
this.$descriptionPage.empty()
|
||||||
|
|
|
@ -460,7 +460,7 @@ const { MultimediaViewerBootstrap } = require( 'mmv.bootstrap' );
|
||||||
const originalWidth = 50;
|
const originalWidth = 50;
|
||||||
const viewer = getMultimediaViewer();
|
const viewer = getMultimediaViewer();
|
||||||
|
|
||||||
viewer.thumbnailInfoProvider.get = function ( fileTitle, width ) {
|
viewer.thumbnailInfoProvider.get = function ( fileTitle, sampleUrl, width ) {
|
||||||
assert.strictEqual( width, expectedWidth );
|
assert.strictEqual( width, expectedWidth );
|
||||||
return $.Deferred().reject();
|
return $.Deferred().reject();
|
||||||
};
|
};
|
||||||
|
@ -603,7 +603,7 @@ const { MultimediaViewerBootstrap } = require( 'mmv.bootstrap' );
|
||||||
const oldDocumentTitle = document.title;
|
const oldDocumentTitle = document.title;
|
||||||
|
|
||||||
this.sandbox.stub( mw.loader, 'using' ).returns( $.Deferred().resolve( viewer ) );
|
this.sandbox.stub( mw.loader, 'using' ).returns( $.Deferred().resolve( viewer ) );
|
||||||
viewer.currentImageFileTitle = title;
|
viewer.currentImage = { filePageTitle: title };
|
||||||
bootstrap.setupEventHandlers();
|
bootstrap.setupEventHandlers();
|
||||||
viewer.setTitle();
|
viewer.setTitle();
|
||||||
|
|
||||||
|
|
|
@ -84,55 +84,76 @@ const { ThumbnailInfo } = require( 'mmv' );
|
||||||
assert.true( thumbnailInfoProvider instanceof ThumbnailInfo );
|
assert.true( thumbnailInfoProvider instanceof ThumbnailInfo );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
QUnit.test( 'ThumbnailInfo get test', ( assert ) => {
|
QUnit.test( 'ThumbnailInfo get test', function ( assert ) {
|
||||||
let apiCallCount = 0;
|
const api = { get: this.sandbox.stub().returns( $.Deferred().resolve( {
|
||||||
const api = { get: function () {
|
query: {
|
||||||
apiCallCount++;
|
pages: [
|
||||||
return $.Deferred().resolve( {
|
{
|
||||||
query: {
|
ns: 6,
|
||||||
pages: [
|
title: 'File:Stuff.jpg',
|
||||||
{
|
missing: true,
|
||||||
ns: 6,
|
imagerepository: 'shared',
|
||||||
title: 'File:Stuff.jpg',
|
imageinfo: [
|
||||||
missing: true,
|
{
|
||||||
imagerepository: 'shared',
|
thumburl: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/Stuff.jpg/51px-Stuff.jpg',
|
||||||
imageinfo: [
|
thumbwidth: 95,
|
||||||
{
|
thumbheight: 200,
|
||||||
thumburl: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/Stuff.jpg/51px-Stuff.jpg',
|
url: 'https://upload.wikimedia.org/wikipedia/commons/1/19/Stuff.jpg',
|
||||||
thumbwidth: 95,
|
descriptionurl: 'https://commons.wikimedia.org/wiki/File:Stuff.jpg'
|
||||||
thumbheight: 200,
|
}
|
||||||
url: 'https://upload.wikimedia.org/wikipedia/commons/1/19/Stuff.jpg',
|
]
|
||||||
descriptionurl: 'https://commons.wikimedia.org/wiki/File:Stuff.jpg'
|
}
|
||||||
}
|
]
|
||||||
]
|
}
|
||||||
}
|
} ) ) };
|
||||||
]
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
} };
|
|
||||||
const file = new mw.Title( 'File:Stuff.jpg' );
|
const file = new mw.Title( 'File:Stuff.jpg' );
|
||||||
const thumbnailInfoProvider = new ThumbnailInfo( api );
|
const thumbnailInfoProvider = new ThumbnailInfo( api );
|
||||||
|
|
||||||
return thumbnailInfoProvider.get( file, 100 ).then( ( thumbnail ) => {
|
return thumbnailInfoProvider.get( file, '', 100 ).then( ( thumbnail ) => {
|
||||||
assert.strictEqual( thumbnail.url,
|
assert.strictEqual( thumbnail.url,
|
||||||
'https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/Stuff.jpg/51px-Stuff.jpg',
|
'https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/Stuff.jpg/51px-Stuff.jpg',
|
||||||
'URL is set correctly' );
|
'URL is set correctly' );
|
||||||
assert.strictEqual( thumbnail.width, 95, 'actual width is set correctly' );
|
assert.strictEqual( thumbnail.width, 95, 'actual width is set correctly' );
|
||||||
assert.strictEqual( thumbnail.height, 200, 'actual height is set correctly' );
|
assert.strictEqual( thumbnail.height, 200, 'actual height is set correctly' );
|
||||||
} ).then( () => {
|
} ).then( () => {
|
||||||
assert.strictEqual( apiCallCount, 1 );
|
assert.strictEqual( api.get.calledOnce, true );
|
||||||
|
assert.deepEqual( api.get.getCall( 0 ).args[ 0 ], {
|
||||||
|
formatversion: 2,
|
||||||
|
action: 'query',
|
||||||
|
prop: 'imageinfo',
|
||||||
|
titles: 'File:Stuff.jpg',
|
||||||
|
iiprop: 'url',
|
||||||
|
iiurlheight: undefined,
|
||||||
|
iiurlparam: undefined,
|
||||||
|
iiurlwidth: 100
|
||||||
|
} );
|
||||||
// call the data provider a second time to check caching
|
// call the data provider a second time to check caching
|
||||||
return thumbnailInfoProvider.get( file, 100 );
|
return thumbnailInfoProvider.get( file, '', 100 );
|
||||||
} ).then( () => {
|
} ).then( () => {
|
||||||
assert.strictEqual( apiCallCount, 1 );
|
assert.strictEqual( api.get.calledOnce, true );
|
||||||
// call a third time with different size to check caching
|
// call a third time with different size to check caching
|
||||||
return thumbnailInfoProvider.get( file, 110 );
|
return thumbnailInfoProvider.get( file, '', 110 );
|
||||||
} ).then( () => {
|
} ).then( () => {
|
||||||
assert.strictEqual( apiCallCount, 2 );
|
assert.strictEqual( api.get.calledTwice, true );
|
||||||
// call it again, with a height specified, to check caching
|
// call it again, with a height specified, to check caching
|
||||||
return thumbnailInfoProvider.get( file, 110, 100 );
|
return thumbnailInfoProvider.get( file, '', 110, 100 );
|
||||||
} ).then( () => {
|
} ).then( () => {
|
||||||
assert.strictEqual( apiCallCount, 3 );
|
assert.strictEqual( api.get.calledThrice, true );
|
||||||
|
// call it again, with multi lingual SVG
|
||||||
|
const file2 = new mw.Title( 'File:Multilingual_SVG_example.svg' );
|
||||||
|
const sampleUrl = 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/1e/Multilingual_SVG_example.svg/langit-120px-Multilingual_SVG_example.svg.png';
|
||||||
|
return thumbnailInfoProvider.get( file2, sampleUrl, 100 );
|
||||||
|
} ).then( () => {
|
||||||
|
assert.deepEqual( api.get.getCall( api.get.callCount - 1 ).args[ 0 ], {
|
||||||
|
action: 'query',
|
||||||
|
formatversion: 2,
|
||||||
|
iiprop: 'url',
|
||||||
|
iiurlheight: undefined,
|
||||||
|
iiurlparam: 'langit-100px',
|
||||||
|
iiurlwidth: 100,
|
||||||
|
prop: 'imageinfo',
|
||||||
|
titles: 'File:Multilingual_SVG_example.svg'
|
||||||
|
} );
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
@ -144,7 +165,7 @@ const { ThumbnailInfo } = require( 'mmv' );
|
||||||
const done = assert.async();
|
const done = assert.async();
|
||||||
const thumbnailInfoProvider = new ThumbnailInfo( api );
|
const thumbnailInfoProvider = new ThumbnailInfo( api );
|
||||||
|
|
||||||
thumbnailInfoProvider.get( file, 100 ).fail( () => {
|
thumbnailInfoProvider.get( file, '', 100 ).fail( () => {
|
||||||
assert.true( true, 'promise rejected when no data is returned' );
|
assert.true( true, 'promise rejected when no data is returned' );
|
||||||
done();
|
done();
|
||||||
} );
|
} );
|
||||||
|
@ -166,7 +187,7 @@ const { ThumbnailInfo } = require( 'mmv' );
|
||||||
const done = assert.async();
|
const done = assert.async();
|
||||||
const thumbnailInfoProvider = new ThumbnailInfo( api );
|
const thumbnailInfoProvider = new ThumbnailInfo( api );
|
||||||
|
|
||||||
thumbnailInfoProvider.get( file, 100 ).fail( () => {
|
thumbnailInfoProvider.get( file, '', 100 ).fail( () => {
|
||||||
assert.true( true, 'promise rejected when imageinfo is missing' );
|
assert.true( true, 'promise rejected when imageinfo is missing' );
|
||||||
done();
|
done();
|
||||||
} );
|
} );
|
||||||
|
@ -190,7 +211,7 @@ const { ThumbnailInfo } = require( 'mmv' );
|
||||||
const done = assert.async();
|
const done = assert.async();
|
||||||
const thumbnailInfoProvider = new ThumbnailInfo( api );
|
const thumbnailInfoProvider = new ThumbnailInfo( api );
|
||||||
|
|
||||||
thumbnailInfoProvider.get( file ).fail( ( errorMessage ) => {
|
thumbnailInfoProvider.get( file, '' ).fail( ( errorMessage ) => {
|
||||||
assert.strictEqual( errorMessage, 'file does not exist: File:Stuff.jpg',
|
assert.strictEqual( errorMessage, 'file does not exist: File:Stuff.jpg',
|
||||||
'error message is set correctly for missing file' );
|
'error message is set correctly for missing file' );
|
||||||
done();
|
done();
|
||||||
|
@ -216,7 +237,7 @@ const { ThumbnailInfo } = require( 'mmv' );
|
||||||
const done = assert.async();
|
const done = assert.async();
|
||||||
const thumbnailInfoProvider = new ThumbnailInfo( api );
|
const thumbnailInfoProvider = new ThumbnailInfo( api );
|
||||||
|
|
||||||
thumbnailInfoProvider.get( file, 100 ).fail( () => {
|
thumbnailInfoProvider.get( file, '', 100 ).fail( () => {
|
||||||
assert.true( true, 'promise rejected when thumbnail info is missing' );
|
assert.true( true, 'promise rejected when thumbnail info is missing' );
|
||||||
done();
|
done();
|
||||||
} );
|
} );
|
||||||
|
|
|
@ -112,7 +112,8 @@ QUnit.test( '.setImageInfo()', function ( assert ) {
|
||||||
);
|
);
|
||||||
const title = 'Foo bar';
|
const title = 'Foo bar';
|
||||||
const image = {
|
const image = {
|
||||||
filePageTitle: mw.Title.newFromText( 'File:' + title + '.jpg' )
|
filePageTitle: mw.Title.newFromText( 'File:' + title + '.jpg' ),
|
||||||
|
src: 'https://upload.wikimedia.org/wikipedia/commons/3/3a/Foobar.jpg'
|
||||||
};
|
};
|
||||||
const imageData = {
|
const imageData = {
|
||||||
title: image.filePageTitle,
|
title: image.filePageTitle,
|
||||||
|
|
|
@ -48,7 +48,7 @@ const { StripeButtons } = require( 'mmv' );
|
||||||
const buttons = createStripeButtons();
|
const buttons = createStripeButtons();
|
||||||
const fakeImageInfo = { descriptionUrl: '//commons.wikimedia.org/wiki/File:Foo.jpg' };
|
const fakeImageInfo = { descriptionUrl: '//commons.wikimedia.org/wiki/File:Foo.jpg' };
|
||||||
|
|
||||||
buttons.set( fakeImageInfo );
|
buttons.set( null, fakeImageInfo );
|
||||||
buttons.empty();
|
buttons.empty();
|
||||||
|
|
||||||
assert.true( true, 'No error on set()/empty().' );
|
assert.true( true, 'No error on set()/empty().' );
|
||||||
|
@ -62,16 +62,16 @@ const { StripeButtons } = require( 'mmv' );
|
||||||
const descriptionUrlCommons = 'https://commons.wikimedia.org/desc';
|
const descriptionUrlCommons = 'https://commons.wikimedia.org/desc';
|
||||||
const descriptionUrl2 = 'http://example.com/different-desc';
|
const descriptionUrl2 = 'http://example.com/different-desc';
|
||||||
|
|
||||||
buttons.set( { descriptionUrl } );
|
buttons.set( null, { descriptionUrl } );
|
||||||
|
|
||||||
assert.strictEqual( $button.hasClass( 'mw-mmv-repo-button-commons' ), false, 'Button does not have commons class non-Commons files' );
|
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' );
|
assert.strictEqual( $button.find( 'a' ).addBack().filter( 'a' ).attr( 'href' ), descriptionUrl, 'Description page link is correct' );
|
||||||
|
|
||||||
buttons.set( { descriptionUrl: descriptionUrlCommons } );
|
buttons.set( null, { descriptionUrl: descriptionUrlCommons } );
|
||||||
|
|
||||||
assert.strictEqual( $button.hasClass( 'mw-mmv-repo-button-commons' ), true, 'Button commons class for Commons files' );
|
assert.strictEqual( $button.hasClass( 'mw-mmv-repo-button-commons' ), true, 'Button commons class for Commons files' );
|
||||||
|
|
||||||
buttons.set( {
|
buttons.set( null, {
|
||||||
descriptionUrl,
|
descriptionUrl,
|
||||||
pageID: 1,
|
pageID: 1,
|
||||||
title: { getUrl: () => descriptionUrl2 }
|
title: { getUrl: () => descriptionUrl2 }
|
||||||
|
|
Loading…
Reference in a new issue