Merge "Add section for attribution of downloads"

This commit is contained in:
jenkins-bot 2014-06-30 18:36:07 +00:00 committed by Gerrit Code Review
commit 02216b5ed3
9 changed files with 324 additions and 21 deletions

View file

@ -579,6 +579,14 @@ $wgResourceModules += array(
'messages' => array(
'multimediaviewer-credit',
'multimediaviewer-text-embed-credit-text-tbls',
'multimediaviewer-text-embed-credit-text-tls',
'multimediaviewer-text-embed-credit-text-tbs',
'multimediaviewer-text-embed-credit-text-tbl',
'multimediaviewer-text-embed-credit-text-tb',
'multimediaviewer-text-embed-credit-text-ts',
'multimediaviewer-text-embed-credit-text-tl',
'multimediaviewer-html-embed-credit-text-tbls',
'multimediaviewer-html-embed-credit-text-tls',
'multimediaviewer-html-embed-credit-text-tbs',
@ -711,6 +719,7 @@ $wgResourceModules += array(
'mediawiki.ui.button',
'mmv.ui.reuse.tab',
'mmv.ui.reuse.utils',
'mmv.embedFileFormatter',
),
'messages' => array(
@ -722,6 +731,10 @@ $wgResourceModules += array(
'multimediaviewer-download-large-button-name',
'multimediaviewer-embed-dimensions',
'multimediaviewer-embed-dimensions-with-file-format',
'multimediaviewer-download-attribution-cta-header',
'multimediaviewer-download-attribution-cta',
'multimediaviewer-attr-plain',
'multimediaviewer-attr-html',
),
),

View file

@ -76,6 +76,14 @@
"multimediaviewer-embed-wt": "Wikitext",
"multimediaviewer-embed-html": "HTML",
"multimediaviewer-embed-explanation": "Use this code to embed the file",
"multimediaviewer-text-embed-credit-text-tbls": "\"$1\" by $2. Licensed under $3 via $4.",
"multimediaviewer-text-embed-credit-text-tls": "\"$1\". Licensed under $2 via $3.",
"multimediaviewer-text-embed-credit-text-tbs": "\"$1\" by $2. Via $3.",
"multimediaviewer-text-embed-credit-text-tbl": "\"$1\" by $2. Licensed under $3.",
"multimediaviewer-text-embed-credit-text-tb": "\"$1\" by $2.",
"multimediaviewer-text-embed-credit-text-ts": "\"$1\". Via $2.",
"multimediaviewer-text-embed-credit-text-tl": "\"$1\". Licensed under $2.",
"multimediaviewer-text-embed-credit-text-t": "\"$1\".",
"multimediaviewer-html-embed-credit-text-tbls": "\"$1\" by $2. Licensed under $3 via $4.",
"multimediaviewer-html-embed-credit-text-tls": "\"$1\". Licensed under $2 via $3.",
"multimediaviewer-html-embed-credit-text-tbs": "\"$1\" by $2. Via $3.",
@ -108,5 +116,9 @@
"multimediaviewer-author-popup-text": "Author",
"multimediaviewer-source-popup-text": "Source",
"multimediaviewer-panel-open-popup-text": "More details",
"multimediaviewer-panel-close-popup-text": "Fewer details"
"multimediaviewer-panel-close-popup-text": "Fewer details",
"multimediaviewer-download-attribution-cta-header": "You need to attribute the author",
"multimediaviewer-download-attribution-cta": "Show me how",
"multimediaviewer-attr-plain": "Plain",
"multimediaviewer-attr-html": "HTML"
}

View file

@ -82,6 +82,14 @@
"multimediaviewer-embed-wt": "Used to represent a choice for embedding a file in a wiki page, as wikitext.",
"multimediaviewer-embed-html": "Used to represent a choice for embedding a file in an HTML document, as HTML.",
"multimediaviewer-embed-explanation": "Used below the embed textarea to explain what we expect the user to do.",
"multimediaviewer-text-embed-credit-text-tbls": "Credit text, used when generating plain text for attributing an image.\nWhich one of the multimediaviewer-text-embed-credit-text-* messages is used will depend on what information about the image is available.\n* $1 - name of the work (typically the filename without an extension)\n* $2 - name of the author\n* $3 - name of the license\n* $4 - name of the website/institution which was the direct source for this image\nEach of the parameters could be either plain text or a link.",
"multimediaviewer-text-embed-credit-text-tls": "Credit text, used when generating plain text to attribute an image.\nWhich one of the multimediaviewer-text-embed-credit-text-* messages is used will depend on what information about the image is available.\n* $1 - name of the work (typically the filename without an extension)\n* $2 - name of the license\n* $3 - name of the website/institution which was the direct source for this image\nEach of the parameters could be either plain text or a link.",
"multimediaviewer-text-embed-credit-text-tbs": "Credit text, used when generating plain text to attribute an image.\nWhich one of the multimediaviewer-text-embed-credit-text-* messages is used will depend on what information about the image is available.\n* $1 - name of the work (typically the filename without an extension)\n* $2 - name of the author\n* $3 - name of the website/institution which was the direct source for this image\nEach of the parameters could be either plain text or a link.",
"multimediaviewer-text-embed-credit-text-tbl": "Credit text, used when generating plain text to attribute an image.\nWhich one of the multimediaviewer-text-embed-credit-text-* messages is used will depend on what information about the image is available.\n* $1 - name of the work (typically the filename without an extension)\n* $2 - name of the author\n* $3 - name of the license\nEach of the parameters could be either plain text or a link.",
"multimediaviewer-text-embed-credit-text-tb": "Credit text, used when generating plain text to attribute an image.\nWhich one of the multimediaviewer-text-embed-credit-text-* messages is used will depend on what information about the image is available.\n* $1 - name of the work (typically the filename without an extension)\n* $2 - name of the author\nEach of the parameters could be either plain text or a link.",
"multimediaviewer-text-embed-credit-text-ts": "Credit text, used when generating plain text to attribute an image.\nWhich one of the multimediaviewer-text-embed-credit-text-* messages is used will depend on what information about the image is available.\n* $1 - name of the work (typically the filename without an extension)\n* $2 - name of the website/institution which was the direct source for this image\nEach of the parameters could be either plain text or a link.",
"multimediaviewer-text-embed-credit-text-tl": "Credit text, used when generating plain text to attribute an image.\nWhich one of the multimediaviewer-text-embed-credit-text-* messages is used will depend on what information about the image is available.\n* $1 - name of the work (typically the filename without an extension)\n* $2 - name of the license\nEach of the parameters could be either plain text or a link.",
"multimediaviewer-text-embed-credit-text-t": "Credit text, used when generating plain text to attribute an image.\nWhich one of the multimediaviewer-text-embed-credit-text-* messages is used will depend on what information about the image is available.\n* $1 - name of the work (typically the filename without an extension)\nEach of the parameters could be either plain text or a link.",
"multimediaviewer-html-embed-credit-text-tbls": "Credit text, used when generating HTML to reuse an image.\nWhich one of the multimediaviewer-html-embed-credit-text-* messages is used will depend on what information about the image is available.\n* $1 - name of the work (typically the filename without an extension)\n* $2 - name of the author\n* $3 - name of the license\n* $4 - name of the website/institution which was the direct source for this image\nEach of the parameters could be either plain text or a link.",
"multimediaviewer-html-embed-credit-text-tls": "Credit text, used when generating HTML to reuse an image.\nWhich one of the multimediaviewer-html-embed-credit-text-* messages is used will depend on what information about the image is available.\n* $1 - name of the work (typically the filename without an extension)\n* $2 - name of the license\n* $3 - name of the website/institution which was the direct source for this image\nEach of the parameters could be either plain text or a link.",
"multimediaviewer-html-embed-credit-text-tbs": "Credit text, used when generating HTML to reuse an image.\nWhich one of the multimediaviewer-html-embed-credit-text-* messages is used will depend on what information about the image is available.\n* $1 - name of the work (typically the filename without an extension)\n* $2 - name of the author\n* $3 - name of the website/institution which was the direct source for this image\nEach of the parameters could be either plain text or a link.",
@ -114,5 +122,9 @@
"multimediaviewer-author-popup-text": "Tooltip that identifies the author of a file in the media viewer.\n{{Identical|Author}}",
"multimediaviewer-source-popup-text": "Tooltip that identifies the source of a file in the media viewer.\n{{Identical|Source}}",
"multimediaviewer-panel-open-popup-text": "Tooltip for a button that expands more metadata in the media viewer.\n\nSee also:\n* {{msg-mw|Multimediaviewer-panel-close-popup-text}}",
"multimediaviewer-panel-close-popup-text": "Tooltip that closes the extra metadata view in the media viewer.\n\nSee also:\n* {{msg-mw|Multimediaviewer-panel-open-popup-text}}"
"multimediaviewer-panel-close-popup-text": "Tooltip that closes the extra metadata view in the media viewer.\n\nSee also:\n* {{msg-mw|Multimediaviewer-panel-open-popup-text}}",
"multimediaviewer-download-attribution-cta-header": "Header for telling the user that the author of an image must be attributed, during a download action.",
"multimediaviewer-download-attribution-cta": "Call to action for a user to find out how to attribute the author of an image.",
"multimediaviewer-attr-plain": "Label for a button that lets the user pick plain text as an output format.",
"multimediaviewer-attr-html": "Label for a button that lets the user pick HTML as an output format."
}

View file

@ -78,13 +78,20 @@
* Byline construction
* @param {string} [author] author name (can contain HTML)
* @param {string} [source] source name (can contain HTML)
* @return {string} byline (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 ) {
author = author && this.htmlUtils.htmlToTextWithLinks( author );
source = source && this.htmlUtils.htmlToTextWithLinks( source );
EFFP.getByline = function ( author, source, formatterFunction ) {
var formatter = this;
if ( author && source) {
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,
@ -95,32 +102,71 @@
}
};
/**
* Generates the plain text embed code for the image credit line.
* @param {mw.mmv.model.EmbedFileInfo} info
* @return {string}
*/
EFFP.getCreditText = function ( info ) {
var creditText, creditParams,
formatter = this,
titleText = info.imageInfo.title.getNameText(),
titleUrl = this.getLinkUrl( info ),
byline = this.getByline( info.imageInfo.author, info.imageInfo.source, function ( txt ) {
return formatter.htmlUtils.htmlToText( txt );
} );
creditParams = [
'multimediaviewer-text-embed-credit-text-t',
titleText
];
if ( byline ) {
creditParams[0] += 'b';
creditParams.push( byline );
}
if ( info.imageInfo.license ) {
creditParams[0] += 'l';
creditParams.push( this.htmlUtils.htmlToText( info.imageInfo.license.longName ) );
}
creditParams[0] += 's';
creditParams.push( info.repoInfo.displayName + ' - ' + titleUrl );
creditText = mw.message.apply( mw, creditParams ).plain();
return creditText;
};
/**
* Generates the HTML embed code for the image credit line.
* @param {mw.mmv.model.EmbedFileInfo} info
* @return {string}
*/
EFFP.getCreditHtml = function ( info ) {
var creditText, creditFormat, creditParams,
var creditText, creditParams,
titleText = info.imageInfo.title.getNameText(),
titleUrl = this.getLinkUrl( info ),
$title = $( '<a>' ).text( titleText ).prop( 'href', titleUrl ),
byline = this.getByline( info.imageInfo.author, info.imageInfo.source );
creditFormat = 't';
creditParams = [ this.htmlUtils.jqueryToHtml( $title ) ];
creditParams = [
'multimediaviewer-html-embed-credit-text-t',
this.htmlUtils.jqueryToHtml( $title )
];
if ( byline ) {
creditFormat += 'b';
creditParams[0] += 'b';
creditParams.push( byline );
}
if ( info.imageInfo.license ) {
creditFormat += 'l';
creditParams[0] += 'l';
creditParams.push( info.imageInfo.license.getShortLink() );
}
creditFormat += 's';
creditParams[0] += 's';
creditParams.push( this.getSiteLink( info ) );
creditParams.unshift( 'multimediaviewer-html-embed-credit-text-' + creditFormat );
creditText = mw.message.apply( mw, creditParams ).plain();
return creditText;

View file

@ -230,15 +230,15 @@
* @param {mw.mmv.model.Repo} repo
* @param {string} caption
*/
DP.set = function ( image, repo, caption) {
DP.set = function ( image, repo, caption ) {
if ( this.tabs !== null ) {
this.tabs.share.set( image );
this.tabs.download.set( image );
this.tabs.download.set( image, repo );
this.tabs.embed.set( image, repo, caption );
} else {
this.tabsSetValues = {
share : [ image ],
download : [ image ],
download : [ image, repo ],
embed : [ image, repo, caption ]
};
}

View file

@ -40,6 +40,10 @@
this.createSizePulldownMenu( this.$pane );
this.createPreviewLink( this.$pane );
this.formatter = new mw.mmv.EmbedFileFormatter();
this.currentAttrView = 'plain';
this.createAttributionButton( this.$pane );
/**
* Default item for the size menu.
* @property {OO.ui.MenuItemWidget}
@ -116,6 +120,88 @@
.appendTo( $container );
};
DP.createAttributionButton = function ( $container ) {
var dl = this,
attributionInput = new oo.ui.TextInputWidget( {
classes: [ 'mw-mmv-download-attr-input' ],
readOnly: true
} ),
attributionSwitch = new oo.ui.ButtonSelectWidget( {
classes: [ 'mw-mmv-download-attr-select' ]
} ),
plainOption = new oo.ui.ButtonOptionWidget( 'plain', {
label: mw.message( 'multimediaviewer-attr-plain' ).text()
} ),
htmlOption = new oo.ui.ButtonOptionWidget( 'html', {
label: mw.message( 'multimediaviewer-attr-html' ).text()
} );
attributionSwitch.addItems( [
plainOption,
htmlOption
] );
attributionSwitch.selectItem( plainOption );
attributionSwitch.on( 'select', function ( selection ) {
dl.selectAttribution( selection.getData() );
dl.attributionInput.$element.find( 'input' ).focus();
} );
this.$attributionSection = $( '<div>' )
.addClass( 'mw-mmv-download-attribution mw-mmv-download-attribution-collapsed' )
.appendTo( $container );
this.$attributionCta = $( '<div>' )
.addClass( 'mw-mmv-download-attribution-cta' )
.append(
$( '<p>' )
.addClass( 'mw-mmv-download-attribution-cta-header' )
.text( mw.message( 'multimediaviewer-download-attribution-cta-header' ).text() ),
$( '<p>' )
.text( mw.message( 'multimediaviewer-download-attribution-cta' ).text() )
)
.click( function () {
dl.$attributionSection.removeClass( 'mw-mmv-download-attribution-collapsed' );
dl.attributionInput.$element.find( 'input' ).focus();
} )
.appendTo( this.$attributionSection );
this.$attributionHow = $( '<div>' )
.addClass( 'mw-mmv-download-attribution-how' )
.append(
$( '<p>' )
.addClass( 'mw-mmv-download-attribution-how-header' )
.text( mw.message( 'multimediaviewer-download-attribution-cta-header' ).text() ),
attributionInput.$element,
attributionSwitch.$element,
$( '<p>' )
.addClass( 'mw-mmv-download-attribution-close-button' )
.click( function () {
dl.$attributionSection.addClass( 'mw-mmv-download-attribution-collapsed' );
} )
.text( ' ' )
)
.appendTo( this.$attributionSection );
this.attributionInput = attributionInput;
};
/**
* Selects the specified attribution type.
* @param {'plain'|'html'} [name='plain'] The attribution type to use.
*/
DP.selectAttribution = function ( name ) {
this.currentAttrView = name;
if ( this.currentAttrView === 'html' ) {
this.attributionInput.setValue( this.htmlCredit );
} else {
this.attributionInput.setValue( this.textCredit );
}
};
/**
* Registers listeners.
*/
@ -127,6 +213,10 @@
this.$selectionArrow.on( 'click', function () {
download.downloadSizeMenu.$element.click();
} );
this.attributionInput.$element.find( 'input' )
.on( 'focus', this.selectAllOnEvent )
.on( 'mousedown click', this.onlyFocus );
};
/**
@ -137,6 +227,9 @@
this.downloadSizeMenu.getMenu().off( 'choose' );
this.$selectionArrow.off( 'click' );
this.attributionInput.$element.find( 'input' )
.off( 'focus mousedown click' );
};
/**
@ -200,6 +293,16 @@
);
};
/**
* Sets the text in the attribution input element.
* @param {mw.mmv.model.EmbedFileInfo} embed
*/
DP.setAttributionText = function ( embed ) {
this.htmlCredit = this.formatter.getCreditHtml( embed );
this.textCredit = this.formatter.getCreditText( embed );
this.selectAttribution( this.currentAttrView );
};
/**
* Chops off the extension part of an URL.
* @param {string} url
@ -213,8 +316,9 @@
* Sets the data on the element.
*
* @param {mw.mmv.model.Image} image
* @param {mw.mmv.model.Repo} repo
*/
DP.set = function ( image ) {
DP.set = function ( image, repo ) {
var sizeOptions = this.downloadSizeMenu.getMenu().getItems(),
sizes = this.utils.getPossibleImageSizesForHtml( image.width, image.height );
@ -229,6 +333,10 @@
// Reset size menu to default item and update download button label now that we have the info
this.downloadSizeMenu.getMenu().chooseItem( this.defaultItem );
if ( image && repo ) {
this.setAttributionText( new mw.mmv.model.EmbedFileInfo( image, repo ) );
}
};
/**
@ -245,6 +353,15 @@
this.image = null;
};
DP.show = function () {
mw.mmv.ui.reuse.Tab.prototype.show.call( this );
this.$container.addClass( 'mw-mmv-reuse-download-active' );
};
DP.hide = function () {
mw.mmv.ui.reuse.Tab.prototype.hide.call( this );
this.$container.removeClass( 'mw-mmv-reuse-download-active' );
};
mw.mmv.ui.reuse.Download = Download;
}( mediaWiki, jQuery, OO ) );

View file

@ -1,7 +1,12 @@
@mw-ui-constructive-button-color: #00af89;
@pane-padding: 10px;
@attribution-color: #f2f2f2;
@attribution-logo-size: 64px;
.mw-mlb-download-pane {
margin-left: 10px;
padding: 0 @pane-padding;
position: relative;
height: 280px;
/* Disable link clicks */
a.disabledLink {
@ -75,4 +80,62 @@
}
}
.mw-mmv-download-attribution {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 0 @pane-padding @pane-padding;
background-color: @attribution-color;
&-how {
position: relative;
display: block;
padding: 5px;
.mw-mmv-download-attribution-close-button {
cursor: pointer;
position: absolute;
top: 5px;
right: 0px;
width: 12px;
height: 12px;
/* @embed */
background-image: url(img/x_gray.svg);
}
}
&-how-header,
&-cta-header {
font-size: large;
font-weight: bold;
}
&-cta {
cursor: pointer;
display: none;
padding-left: @attribution-logo-size + 7px;
/* @embed */
background-image: url(img/user-ltr.svg);
background-repeat: no-repeat;
background-size: @attribution-logo-size;
background-position: left center;
}
&.mw-mmv-download-attribution-collapsed {
.mw-mmv-download-attribution-cta {
display: block;
}
.mw-mmv-download-attribution-how {
display: none;
}
}
}
}
.mw-mmv-reuse-dialog.mw-mmv-reuse-download-active .mw-mmv-reuse-down-arrow {
background-color: @attribution-color;
}

View file

@ -179,4 +179,44 @@
'Wikitext generated correctly.' );
} );
QUnit.test( 'getCreditText():', 2, function ( assert ) {
var txt, formatter = new mw.mmv.EmbedFileFormatter();
this.sandbox.stub( formatter, 'getLinkUrl' ).returns( 'quuuux' );
txt = formatter.getCreditText( {
repoInfo: {
displayName: 'Localcommons'
},
imageInfo: {
author: 'Author',
source: 'Source',
title: {
getNameText: function () { return 'Image Title'; }
}
}
} );
assert.strictEqual( txt, '"Image Title" by Author - Source. Via Localcommons - quuuux.', 'Sanity check' );
txt = formatter.getCreditText( {
repoInfo: {
displayName: 'Localcommons'
},
imageInfo: {
author: 'Author',
source: 'Source',
title: {
getNameText: function () { return 'Image Title'; }
},
license: {
longName: 'Do What the Fuck You Want Public License'
}
}
} );
assert.strictEqual( txt, '"Image Title" by Author - Source. Licensed under Do What the Fuck You Want Public License via Localcommons - quuuux.', 'License message works' );
} );
}( mediaWiki ) );

View file

@ -209,11 +209,11 @@
width: 100,
height: 80
},
embedFileInfo = new mw.mmv.model.EmbedFileInfo( title, src, url );
repoInfo = new mw.mmv.model.Repo( 'Wikipedia', '//wikipedia.org/favicon.ico', true );
reuseDialog.initTabs();
reuseDialog.set( image, embedFileInfo );
reuseDialog.set( image, repoInfo );
assert.ok( ! reuseDialog.isOpen, 'Dialog closed by default.' );