Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F4064870
mmv.ui.download.pane.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
mmv.ui.download.pane.js
View Options
/*
* 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
EmbedFileFormatter
=
require
(
'./mmv.EmbedFileFormatter.js'
);
const
Utils
=
require
(
'./mmv.ui.utils.js'
);
const
{
UiElement
}
=
require
(
'mmv'
);
/**
* UI component that provides functionality to download the media asset displayed.
*/
class
DownloadPane
extends
UiElement
{
/**
* @param {jQuery} $container
*/
constructor
(
$container
)
{
super
(
$container
);
this
.
formatter
=
new
EmbedFileFormatter
();
this
.
createDownloadSection
(
this
.
$container
);
this
.
createAttributionButton
(
this
.
$container
);
/** @property {ImageModel|null} Image the download button currently points to. */
this
.
image
=
null
;
}
/**
* Creates dialog download section.
*
* @param {jQuery} $container
*/
createDownloadSection
(
$container
)
{
const
$header
=
$
(
'<div>'
)
.
addClass
(
'cdx-dialog__header'
)
.
appendTo
(
$container
);
$
(
'<div>'
)
.
addClass
(
'cdx-dialog__header__title'
)
.
text
(
mw
.
msg
(
'multimediaviewer-download-link'
)
)
.
appendTo
(
$header
);
const
$body
=
$
(
'<div>'
)
.
addClass
(
'cdx-dialog__body mw-mmv-pt-0'
)
.
appendTo
(
$container
);
this
.
$downloadArea
=
$
(
'<div>'
)
.
addClass
(
'mw-mmv-flex mw-mmv-gap-50'
)
.
appendTo
(
$body
);
this
.
createSizePulldownMenu
(
this
.
$downloadArea
);
this
.
createDownloadButton
(
this
.
$downloadArea
);
const
$p
=
$
(
'<p>'
).
addClass
(
'mw-mmv-mt-75'
).
appendTo
(
$body
);
this
.
createPreviewLink
(
$p
);
}
/**
* Creates download split button. It is a link with the "download" property set plus an
* arrow that allows the user to select the image size desired. The "download" property
* triggers native browser downloading in browsers that support it. The fallback is the
* 'download' parameter which instructs the server to send the right headers so the browser
* downloads the file instead of just displaying it. If all this fails, the image will appear
* in another window/tab.
*
* @param {jQuery} $container
*/
createDownloadButton
(
$container
)
{
this
.
$downloadButton
=
$
(
'<a>'
)
.
attr
(
'target'
,
'_blank'
)
.
attr
(
'download'
,
''
)
.
addClass
(
'cdx-button cdx-button--weight-primary cdx-button--action-progressive cdx-button--fake-button cdx-button--fake-button--enabled'
)
.
html
(
'<span class="cdx-button__icon cdx-button__icon--download" aria-hidden="true"></span>'
+
mw
.
msg
(
'multimediaviewer-download'
)
)
.
appendTo
(
$container
);
}
/**
* Creates pulldown menu to select image sizes.
*
* @param {jQuery} $container
*/
createSizePulldownMenu
(
$container
)
{
this
.
$downloadSizeMenu
=
Utils
.
createSelectMenu
(
[
'original'
,
'small'
,
'medium'
,
'large'
,
'xl'
],
'original'
).
appendTo
(
$container
);
}
/**
* Creates preview link.
*
* @param {jQuery} $container
*/
createPreviewLink
(
$container
)
{
this
.
$previewLink
=
$
(
'<a>'
)
.
attr
(
'target'
,
'_blank'
)
.
addClass
(
'cdx-docs-link'
)
.
html
(
mw
.
msg
(
'multimediaviewer-download-preview-link-title'
)
)
.
appendTo
(
$container
);
}
createAttributionButton
(
$container
)
{
[
this
.
$attributionInput
,
this
.
$attributionInputDiv
]
=
Utils
.
createInputWithCopy
(
mw
.
msg
(
'multimediaviewer-download-attribution-copy'
),
''
);
const
$header
=
$
(
'<div>'
)
.
addClass
(
'cdx-dialog__header'
)
.
appendTo
(
$container
);
$
(
'<p>'
)
.
addClass
(
'cdx-dialog__header__title'
)
.
text
(
mw
.
msg
(
'multimediaviewer-download-attribution'
)
)
.
appendTo
(
$header
);
this
.
$attributionHowHeader
=
$
(
'<p>'
)
.
addClass
(
'mw-mmv-mb-75'
)
.
text
(
mw
.
msg
(
'multimediaviewer-download-attribution-cta-header'
)
);
const
$attributionTabs
=
$
(
'<div>'
).
addClass
(
'cdx-tabs'
);
const
$attributionTabsHeader
=
$
(
'<div>'
).
addClass
(
'cdx-tabs__header'
).
appendTo
(
$attributionTabs
);
this
.
$attributionTabsList
=
$
(
'<div>'
).
addClass
(
'cdx-tabs__list'
).
attr
(
'role'
,
'tablist'
).
appendTo
(
$attributionTabsHeader
);
[
'plain'
,
'html'
].
forEach
(
(
name
)
=>
$
(
'<button>'
)
.
addClass
(
'cdx-tabs__list__item'
)
.
attr
(
'role'
,
'tab'
)
.
data
(
'name'
,
name
)
// The following messages are used here:
// * multimediaviewer-attr-plain
// * multimediaviewer-attr-html
.
text
(
mw
.
msg
(
'multimediaviewer-attr-'
+
name
)
)
.
on
(
'click'
,
()
=>
this
.
selectAttribution
(
name
)
)
.
appendTo
(
this
.
$attributionTabsList
)
);
this
.
selectAttribution
(
'plain'
);
$
(
'<div>'
)
.
addClass
(
'cdx-dialog__body mw-mmv-pt-0 mw-mmv-pb-150'
)
.
append
(
this
.
$attributionHowHeader
,
$attributionTabs
,
this
.
$attributionInputDiv
.
addClass
(
' mw-mmv-mt-75'
)
)
.
appendTo
(
$container
);
}
/**
* Selects the specified attribution type.
*
* @param {string} [name='plain'] The attribution type to use ('plain' or 'html')
*/
selectAttribution
(
name
)
{
this
.
currentAttrView
=
name
;
this
.
$attributionTabsList
.
children
().
each
(
(
_i
,
element
)
=>
{
const
$element
=
$
(
element
);
$element
.
attr
(
'aria-selected'
,
$element
.
data
(
'name'
)
===
name
);
}
);
if
(
this
.
currentAttrView
===
'html'
)
{
this
.
$attributionInput
.
val
(
this
.
htmlCredit
);
}
else
{
this
.
$attributionInput
.
val
(
this
.
textCredit
);
}
}
/**
* Registers listeners.
*/
attach
()
{
// Register handlers for switching between file sizes
this
.
$downloadSizeMenu
.
on
(
'change'
,
()
=>
this
.
handleSizeSwitch
()
);
}
/**
* Clears listeners.
*/
unattach
()
{
super
.
unattach
();
this
.
$downloadSizeMenu
.
off
(
'change'
);
}
/**
* Handles size menu change events.
*/
handleSizeSwitch
()
{
// eslint-disable-next-line no-jquery/no-sizzle
const
$option
=
this
.
$downloadSizeMenu
.
find
(
':selected'
);
const
value
=
{
name
:
$option
.
data
(
'name'
),
width
:
$option
.
data
(
'width'
),
height
:
$option
.
data
(
'height'
)
};
if
(
value
.
name
===
'original'
&&
this
.
image
!==
null
)
{
this
.
setDownloadUrl
(
this
.
image
.
url
);
}
else
{
// Disable download while we get the image
this
.
$downloadButton
.
addClass
(
'disabledLink'
);
Utils
.
getThumbnailUrlPromise
(
value
.
width
).
done
(
(
thumbnail
)
=>
{
this
.
setDownloadUrl
(
thumbnail
.
url
);
}
);
}
}
/**
* Sets the URL on the download button.
*
* @param {string} url
*/
setDownloadUrl
(
url
)
{
this
.
$downloadButton
.
attr
(
'href'
,
`
${
url
}
?download`
);
this
.
$previewLink
.
attr
(
'href'
,
url
);
// Re-enable download
this
.
$downloadButton
.
removeClass
(
'disabledLink'
);
}
/**
* Sets the text in the attribution input element.
*
* @param {ImageModel} imageInfo
*/
setAttributionText
(
imageInfo
)
{
this
.
htmlCredit
=
this
.
formatter
.
getCreditHtml
(
imageInfo
);
this
.
textCredit
=
this
.
formatter
.
getCreditText
(
imageInfo
);
this
.
selectAttribution
(
this
.
currentAttrView
);
}
/**
* Chops off the extension part of an URL.
*
* @param {string} url URL
* @return {string} Extension
*/
getExtensionFromUrl
(
url
)
{
const
urlParts
=
url
.
split
(
'.'
);
return
urlParts
[
urlParts
.
length
-
1
];
}
/**
* Sets the data on the element.
*
* @param {ImageModel} image
*/
set
(
image
)
{
const
license
=
image
&&
image
.
license
;
const
sizes
=
Utils
.
getPossibleImageSizesForHtml
(
image
.
width
,
image
.
height
);
this
.
image
=
image
;
Utils
.
updateSelectOptions
(
sizes
,
this
.
$downloadSizeMenu
.
children
()
);
// Note: This extension will not be the real one for file types other than: png/gif/jpg/jpeg
this
.
imageExtension
=
image
.
title
.
getExtension
().
toLowerCase
();
// Reset size menu to default item and update download button label now that we have the info
this
.
$downloadSizeMenu
.
val
(
'original'
);
this
.
handleSizeSwitch
();
if
(
image
)
{
this
.
setAttributionText
(
image
);
}
const
attributionCtaMessage
=
(
license
&&
license
.
needsAttribution
()
)
?
'multimediaviewer-download-attribution-cta-header'
:
'multimediaviewer-download-optional-attribution-cta-header'
;
// Message defined above
// eslint-disable-next-line mediawiki/msg-doc
this
.
$attributionHowHeader
.
text
(
mw
.
msg
(
attributionCtaMessage
)
);
}
/**
* @inheritdoc
*/
empty
()
{
this
.
$downloadButton
.
attr
(
'href'
,
''
);
this
.
$previewLink
.
attr
(
'href'
,
''
);
this
.
imageExtension
=
undefined
;
this
.
image
=
null
;
}
}
module
.
exports
=
DownloadPane
;
File Metadata
Details
Attached
Mime Type
text/x-asm
Expires
Aug 16 2026, 14:30 (11 w, 6 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
b8/7b/076f20b31ace5d89135e7f351748
Default Alt Text
mmv.ui.download.pane.js (8 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment