Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F4123713
rest.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
rest.js
View Options
import
{
createModel
}
from
'../preview/model'
;
import
{
abortablePromise
}
from
'./index.js'
;
/**
* @module gateway/rest
* @private
*/
const
RESTBASE_PROFILE
=
'https://www.mediawiki.org/wiki/Specs/Summary/1.2.0'
;
/** @typedef {function(JQuery.AjaxSettings=): JQuery.jqXHR} Ajax */
/**
* Creates an instance of the RESTBase gateway.
*
* This gateway differs from the {@link MediaWikiGateway MediaWiki gateway} in
* that it fetches page data from [the RESTBase page summary endpoint][0].
*
* [0]: https://en.wikipedia.org/api/rest_v1/#!/Page_content/get_page_summary_title
*
* @private
* @ignore
* @param {Ajax} ajax A function with the same signature as `jQuery.ajax`
* @param {Object} config Configuration that affects the major behavior of the
* gateway.
* @param {Function} extractParser A function that takes response and returns
* parsed extract
* @return {Gateway}
*/
export
default
function
createRESTBaseGateway
(
ajax
,
config
,
extractParser
)
{
/**
* Fetches page data from [the RESTBase page summary endpoint][0].
*
* [0]: https://en.wikipedia.org/api/rest_v1/#!/Page_content/get_page_summary_title
*
* @method
* @name RESTBaseGateway#fetch
* @param {string} title
* @return {jQuery.jqXHR}
*/
function
fetch
(
title
)
{
const
endpoint
=
config
.
endpoint
;
return
ajax
(
{
url
:
endpoint
+
encodeURIComponent
(
title
),
headers
:
{
Accept
:
`application/json; charset=utf-8; profile="
${
RESTBASE_PROFILE
}
"`
,
'Accept-Language'
:
config
.
acceptLanguage
}
}
);
}
/**
* @param {mw.Title} title
* @return {AbortPromise<PagePreviewModel>}
*/
function
fetchPreviewForTitle
(
title
)
{
const
titleText
=
title
.
getPrefixedDb
(),
xhr
=
fetch
(
titleText
);
return
abortablePromise
(
xhr
.
then
(
(
page
)
=>
{
// Endpoint response may be empty or simply missing a title.
page
=
page
||
{};
page
.
title
=
page
.
title
||
titleText
;
// And extract may be omitted if empty string
page
.
extract
=
page
.
extract
||
''
;
return
convertPageToModel
(
page
,
config
.
THUMBNAIL_SIZE
,
extractParser
);
}
).
catch
(
(
jqXHR
,
textStatus
,
errorThrown
)
=>
{
// The client will choose how to handle these errors which may include
// those due to HTTP 4xx and 5xx status. The rejection typing matches
// fetch failures.
return
Promise
.
reject
(
'http'
,
{
xhr
:
jqXHR
,
textStatus
,
exception
:
errorThrown
}
);
}
),
()
=>
xhr
.
abort
()
);
}
return
{
fetch
,
convertPageToModel
,
fetchPreviewForTitle
};
}
/**
* Checks whether the `originalImage` property contains an image
* format that's safe to render.
* https://www.mediawiki.org/wiki/Help:Images#Supported_media_types_for_images
*
* @param {string} filename
* @ignore
* @return {boolean}
*/
function
isSafeImgFormat
(
filename
)
{
const
safeImage
=
new
RegExp
(
/\.(jpg|jpeg|png|gif)$/i
);
return
safeImage
.
test
(
filename
);
}
/**
* Resizes the thumbnail to the requested width, preserving its aspect ratio.
*
* The requested width is limited to that of the original image unless the image
* is an SVG, which can be scaled infinitely.
*
* This function is only intended to mangle the pretty thumbnail URLs used on
* Wikimedia Commons. Once [an official thumb API](https://phabricator.wikimedia.org/T66214)
* is fully specified and implemented, this function can be made more general.
*
* @param {Object} thumbnail The thumbnail image
* @param {Object} original The original image
* @param {number} thumbSize The requested size
* @return {{source: string, width: number, height: number}|undefined}
*/
function
generateThumbnailData
(
thumbnail
,
original
,
thumbSize
)
{
const
parts
=
thumbnail
.
source
.
split
(
'/'
),
lastPart
=
parts
[
parts
.
length
-
1
],
originalIsSafe
=
isSafeImgFormat
(
original
.
source
)
||
undefined
;
// The last part, the thumbnail's full filename, is in the following form:
// ${width}px-${filename}.${extension}. Splitting the thumbnail's filename
// makes this function resilient to the thumbnail not having the same
// extension as the original image, which is definitely the case for SVG's
// where the thumbnail's extension is .svg.png.
const
filenamePxIndex
=
lastPart
.
indexOf
(
'px-'
);
if
(
filenamePxIndex
===
-
1
)
{
// The thumbnail size is not customizable. Presumably, RESTBase requested a
// width greater than the original and so MediaWiki returned the original's
// URL instead of a thumbnail compatible URL. An original URL does not have
// a "thumb" path, e.g.:
//
// https://upload.wikimedia.org/wikipedia/commons/a/aa/Red_Giant_Earth_warm.jpg
//
// Instead of:
//
// https://upload.wikimedia.org/wikipedia/commons/thumb/a/aa/Red_Giant_Earth_warm.jpg/512px-Red_Giant_Earth_warm.jpg
//
// Use the original if it's a supported image format.
return
originalIsSafe
&&
original
;
}
const
filename
=
lastPart
.
slice
(
filenamePxIndex
+
3
);
// Scale the thumbnail's largest dimension.
let
width
,
height
;
if
(
thumbnail
.
width
>
thumbnail
.
height
)
{
width
=
thumbSize
;
height
=
Math
.
floor
(
(
thumbSize
/
thumbnail
.
width
)
*
thumbnail
.
height
);
}
else
{
width
=
Math
.
floor
(
(
thumbSize
/
thumbnail
.
height
)
*
thumbnail
.
width
);
height
=
thumbSize
;
}
// If the image isn't an SVG, then it shouldn't be scaled past its original
// dimensions.
if
(
width
>=
original
.
width
&&
filename
.
indexOf
(
'.svg'
)
===
-
1
)
{
// if the image format is not supported, it shouldn't be rendered.
return
originalIsSafe
&&
original
;
}
parts
[
parts
.
length
-
1
]
=
`
${
width
}
px-
${
filename
}
`
;
return
{
source
:
parts
.
join
(
'/'
),
width
,
height
};
}
/**
* Converts the API response to a preview model.
*
* @method
* @ignore
* @name RESTBaseGateway#convertPageToModel
* @param {Object} page
* @param {number} thumbSize
* @param {Function} extractParser
* @return {PagePreviewModel}
*/
export
function
convertPageToModel
(
page
,
thumbSize
,
extractParser
)
{
return
createModel
(
page
.
title
,
new
mw
.
Title
(
page
.
title
).
getUrl
(),
page
.
lang
,
page
.
dir
,
extractParser
(
page
),
page
.
type
,
page
.
thumbnail
?
generateThumbnailData
(
page
.
thumbnail
,
page
.
originalimage
,
thumbSize
)
:
undefined
,
page
.
pageid
);
}
File Metadata
Details
Attached
Mime Type
text/x-java
Expires
Wed, Aug 19, 06:18 (5 d, 5 h ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
5a/54/ba7295a147646bf996f1fb96e5bd
Default Alt Text
rest.js (6 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment