From e4b8e860c8a8d395ba49f955a719fc248945ef61 Mon Sep 17 00:00:00 2001 From: Sn1per Date: Sun, 28 Dec 2014 21:04:22 +0000 Subject: [PATCH] Show custom Attribution line instead of Author/Credit when available - Adds attribution variable to Image model - In mmv.ui.metadataPanel and mmv.EmbedFileFormatter, display attribution line instead of author and credit when it is set - Update junit tests for mmv.model.Image and mmv.EmbedFileFormatter Bug: T67445 Change-Id: Idfe542a1542d28cf8d27c1720ab0bd54324b2f37 --- resources/mmv/mmv.EmbedFileFormatter.js | 32 +++++++++++-------- resources/mmv/model/mmv.model.Image.js | 9 +++++- .../mmv/provider/mmv.provider.ImageInfo.js | 1 + resources/mmv/ui/mmv.ui.metadataPanel.js | 22 +++++++++++-- .../qunit/mmv/mmv.EmbedFileFormatter.test.js | 8 ++++- tests/qunit/mmv/model/mmv.model.Image.test.js | 10 +++--- 6 files changed, 60 insertions(+), 22 deletions(-) diff --git a/resources/mmv/mmv.EmbedFileFormatter.js b/resources/mmv/mmv.EmbedFileFormatter.js index 49a0ddbcb..849efdd64 100644 --- a/resources/mmv/mmv.EmbedFileFormatter.js +++ b/resources/mmv/mmv.EmbedFileFormatter.js @@ -78,27 +78,33 @@ * Byline construction * @param {string} [author] author name (can contain HTML) * @param {string} [source] source name (can contain HTML) + * @param {string} [attribution] custom attribution line (can contain HTML) * @param {Function} [formatterFunction] Format function for the text - defaults to whitelisting HTML links, but all else sanitized. * @return {string} Byline (can contain HTML) */ - EFFP.getByline = function ( author, source, formatterFunction ) { + EFFP.getByline = function ( author, source, attribution, formatterFunction ) { var formatter = this; formatterFunction = formatterFunction || function ( txt ) { return formatter.htmlUtils.htmlToTextWithLinks( txt ); }; - author = author && formatterFunction( author ); - source = source && formatterFunction( source ); - - if ( author && source ) { - return mw.message( - 'multimediaviewer-credit', - author, - source - ).parse(); + if ( attribution ) { + attribution = attribution && formatterFunction( attribution ); + return attribution; } else { - return author || source; + author = author && formatterFunction( author ); + source = source && formatterFunction( source ); + + if ( author && source ) { + return mw.message( + 'multimediaviewer-credit', + author, + source + ).parse(); + } else { + return author || source; + } } }; @@ -112,7 +118,7 @@ formatter = this, titleText = info.imageInfo.title.getNameText(), titleUrl = this.getLinkUrl( info ), - byline = this.getByline( info.imageInfo.author, info.imageInfo.source, function ( txt ) { + byline = this.getByline( info.imageInfo.author, info.imageInfo.source, info.imageInfo.attribution, function ( txt ) { return formatter.htmlUtils.htmlToText( txt ); } ); @@ -152,7 +158,7 @@ titleText = info.imageInfo.title.getNameText(), titleUrl = this.getLinkUrl( info ), $title = $( '' ).text( titleText ).prop( 'href', titleUrl ), - byline = this.getByline( info.imageInfo.author, info.imageInfo.source ); + byline = this.getByline( info.imageInfo.author, info.imageInfo.source, info.imageInfo.attribution ); creditParams = [ 'multimediaviewer-html-embed-credit-text-t', diff --git a/resources/mmv/model/mmv.model.Image.js b/resources/mmv/model/mmv.model.Image.js index c5c3b0630..6b3caf612 100644 --- a/resources/mmv/model/mmv.model.Image.js +++ b/resources/mmv/model/mmv.model.Image.js @@ -41,6 +41,7 @@ * @param {number} authorCount * @param {mw.mmv.model.License} license * @param {string} permission + * @param {string} attribution Custom attribution string that replaces credit line when set * @param {number} latitude * @param {number} longitude */ @@ -64,6 +65,7 @@ authorCount, license, permission, + attribution, latitude, longitude ) { @@ -125,6 +127,9 @@ /** @property {string} additional license conditions by the author (note that this is usually a big ugly HTML blob) */ this.permission = permission; + /** @property {string} attribution custom attribution string set by uploader that replaces credit line */ + this.attribution = attribution; + /** @property {number} latitude The latitude of the place where the image was created */ this.latitude = latitude; @@ -150,7 +155,7 @@ */ Image.newFromImageInfo = function ( title, imageInfo ) { var name, uploadDateTime, anonymizedUploadDateTime, creationDateTime, imageData, - description, source, author, authorCount, license, permission, + description, source, author, authorCount, license, permission, attribution, latitude, longitude, innerInfo = imageInfo.imageinfo[0], extmeta = innerInfo.extmetadata; @@ -176,6 +181,7 @@ license = this.newLicenseFromImageInfo( extmeta ); permission = this.parseExtmeta( extmeta.Permission, 'string' ); + attribution = this.parseExtmeta( extmeta.Attribution, 'string' ); latitude = this.parseExtmeta( extmeta.GPSLatitude, 'float' ); longitude = this.parseExtmeta( extmeta.GPSLongitude, 'float' ); @@ -206,6 +212,7 @@ authorCount, license, permission, + attribution, latitude, longitude ); diff --git a/resources/mmv/provider/mmv.provider.ImageInfo.js b/resources/mmv/provider/mmv.provider.ImageInfo.js index 44f6a5866..75fdb6499 100644 --- a/resources/mmv/provider/mmv.provider.ImageInfo.js +++ b/resources/mmv/provider/mmv.provider.ImageInfo.js @@ -71,6 +71,7 @@ 'GPSLatitude', 'GPSLongitude', 'Permission', + 'Attribution', 'AttributionRequired', 'NonFree' ].join('|'); diff --git a/resources/mmv/ui/mmv.ui.metadataPanel.js b/resources/mmv/ui/mmv.ui.metadataPanel.js index 08092dfeb..bf263ea17 100644 --- a/resources/mmv/ui/mmv.ui.metadataPanel.js +++ b/resources/mmv/ui/mmv.ui.metadataPanel.js @@ -475,14 +475,17 @@ /** * Set source and author. + * @param {string} attribution Custom attribution string * @param {string} source With unsafe HTML * @param {string} author With unsafe HTML * @param {number} authorCount * @param {string} filepageUrl URL of the file page (used when other data is not available) */ - MPP.setCredit = function ( source, author, authorCount, filepageUrl ) { + MPP.setCredit = function ( attribution, source, author, authorCount, filepageUrl ) { // sanitization will be done by TruncatableTextField.set() - if ( author && source ) { + if ( attribution && ( authorCount <= 1 || !authorCount ) ) { + this.creditField.set( this.wrapAttribution( attribution ) ); + } else if ( author && source ) { this.creditField.set( mw.message( 'multimediaviewer-credit', @@ -546,6 +549,19 @@ return $wrapper.get( 0 ).outerHTML; }; + /** + * Wraps an attribution string with MediaViewer styles + * @param {string} attribution Warning - unsafe HTML sometimes goes here + * @return {string} unsafe HTML + */ + MPP.wrapAttribution = function ( attribution ) { + return $( '' ) + .addClass( 'mw-mmv-author' ) + .addClass( 'mw-mmv-source' ) + .append( $.parseHTML( attribution ) ) + .get( 0 ).outerHTML; + }; + /** * Sets the license display in the panel * @param {mw.mmv.model.License|null} license license data (could be missing) @@ -693,7 +709,7 @@ // these handle text truncation and should be called when everything that can push text down // (e.g. floated buttons) has already been laid out this.setTitle( image, imageData ); - this.setCredit( imageData.source, imageData.author, imageData.authorCount, imageData.descriptionUrl ); + this.setCredit( imageData.attribution, imageData.source, imageData.author, imageData.authorCount, imageData.descriptionUrl ); if ( imageData.permission ) { this.setPermission( imageData.permission ); diff --git a/tests/qunit/mmv/mmv.EmbedFileFormatter.test.js b/tests/qunit/mmv/mmv.EmbedFileFormatter.test.js index 54c7c6968..5ae7b5f5b 100644 --- a/tests/qunit/mmv/mmv.EmbedFileFormatter.test.js +++ b/tests/qunit/mmv/mmv.EmbedFileFormatter.test.js @@ -18,16 +18,22 @@ assert.ok( formatter, 'constructor with no argument works'); } ); - QUnit.test( 'getByline():', 4, function ( assert ) { + QUnit.test( 'getByline():', 5, function ( assert ) { var formatter = new mw.mmv.EmbedFileFormatter(), author = 'Homer', source = 'Iliad', + attribution = 'Cat', byline; // Works with no arguments byline = formatter.getByline(); assert.strictEqual( byline, undefined, 'No argument case handled correctly.' ); + + // Attribution present + byline = formatter.getByline( author, source, attribution ); + assert.ok( byline.match ( /Cat/ ), 'Attribution found in bylines' ); + // Author and source present byline = formatter.getByline( author, source ); assert.ok( byline.match ( /Homer|Iliad/ ), 'Author and source found in bylines' ); diff --git a/tests/qunit/mmv/model/mmv.model.Image.test.js b/tests/qunit/mmv/model/mmv.model.Image.test.js index 7686ffd06..526264019 100644 --- a/tests/qunit/mmv/model/mmv.model.Image.test.js +++ b/tests/qunit/mmv/model/mmv.model.Image.test.js @@ -18,7 +18,7 @@ ( function( mw ) { QUnit.module( 'mmv.model.Image', QUnit.newMwEnvironment() ); - QUnit.test( 'Image model constructor sanity check', 22, function ( assert ) { + QUnit.test( 'Image model constructor sanity check', 23, function ( assert ) { var title = mw.Title.newFromText( 'File:Foobar.jpg' ), name = 'Foo bar', @@ -39,12 +39,13 @@ authorCount = 1, permission = 'only use for good, not evil', license = new mw.mmv.model.License( 'cc0' ), + attribution = 'Created by my cats on a winter morning', latitude = 39.12381283, longitude = 100.983829, imageData = new mw.mmv.model.Image( title, name, size, width, height, mime, url, descurl, repo, user, datetime, anondatetime, origdatetime, - description, source, author, authorCount, license, permission, + description, source, author, authorCount, license, permission, attribution, latitude, longitude ); assert.strictEqual( imageData.title, title, 'Title is set correctly' ); @@ -66,6 +67,7 @@ assert.strictEqual( imageData.authorCount, authorCount, 'Author is set correctly' ); assert.strictEqual( imageData.license, license, 'License is set correctly' ); assert.strictEqual( imageData.permission, permission, 'Permission is set correctly' ); + assert.strictEqual( imageData.attribution, attribution, 'Attribution is set correctly' ); assert.strictEqual( imageData.latitude, latitude, 'Latitude is set correctly' ); assert.strictEqual( imageData.longitude, longitude, 'Longitude is set correctly' ); assert.ok( imageData.thumbUrls, 'Thumb URL cache is set up properly' ); @@ -77,13 +79,13 @@ mw.Title.newFromText( 'File:Foobar.pdf.jpg' ), 'Foo bar', 10, 10, 10, 'image/jpeg', 'http://example.org', 'http://example.com', 'example', 'tester', '2013-11-10', '20131110', '2013-11-09', 'Blah blah blah', - 'A person', 'Another person', 1, 'CC-BY-SA-3.0', 'Permitted' + 'A person', 'Another person', 1, 'CC-BY-SA-3.0', 'Permitted', 'My cat' ), secondImageData = new mw.mmv.model.Image( mw.Title.newFromText( 'File:Foobar.pdf.jpg' ), 'Foo bar', 10, 10, 10, 'image/jpeg', 'http://example.org', 'http://example.com', 'example', 'tester', '2013-11-10', '20131110', '2013-11-09', 'Blah blah blah', - 'A person', 'Another person', 1, 'CC-BY-SA-3.0', 'Permitted', + 'A person', 'Another person', 1, 'CC-BY-SA-3.0', 'Permitted', 'My cat', '39.91820938', '78.09812938' );