2018-12-12 18:37:19 +00:00
|
|
|
/**
|
|
|
|
* @module gateway/reference
|
|
|
|
*/
|
|
|
|
|
2019-01-24 15:33:29 +00:00
|
|
|
import { previewTypes } from '../preview/model';
|
|
|
|
|
2018-12-12 18:37:19 +00:00
|
|
|
/**
|
|
|
|
* @return {Gateway}
|
|
|
|
*/
|
|
|
|
export default function createReferenceGateway() {
|
2019-02-20 10:35:34 +00:00
|
|
|
|
|
|
|
function scrapeReferenceText( id ) {
|
2019-08-05 12:42:21 +00:00
|
|
|
const idSelector = `#${$.escapeSelector( id )}`;
|
2019-02-20 10:35:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Same alternative selectors with and without mw-… as in the RESTbased endpoint.
|
|
|
|
* @see https://phabricator.wikimedia.org/diffusion/GMOA/browse/master/lib/transformations/references/structureReferenceListContent.js$138
|
|
|
|
*/
|
2019-08-05 12:42:21 +00:00
|
|
|
return $( `${idSelector} .mw-reference-text, ${idSelector} .reference-text` );
|
2019-02-20 10:35:34 +00:00
|
|
|
}
|
|
|
|
|
2019-02-19 16:01:16 +00:00
|
|
|
/**
|
2019-02-20 16:15:34 +00:00
|
|
|
* This extracts the type (e.g. "web") from one or more <cite> elements class name lists, as
|
|
|
|
* long as these don't conflict. A "citation" class is always ignored. <cite> elements without
|
|
|
|
* another class (other than "citation") are ignored as well.
|
|
|
|
*
|
|
|
|
* Note this might return multiple types, e.g. <cite class="web citation paywalled"> will be
|
|
|
|
* returned as "web paywalled". Validation must be done in the code consuming this.
|
|
|
|
*
|
2019-02-19 16:01:16 +00:00
|
|
|
* This duplicates the strict type detection from
|
|
|
|
* @see https://phabricator.wikimedia.org/diffusion/GMOA/browse/master/lib/transformations/references/structureReferenceListContent.js$93
|
|
|
|
*
|
|
|
|
* @param {JQuery} $referenceText
|
2019-08-05 12:35:21 +00:00
|
|
|
* @return {string|null}
|
2019-02-19 16:01:16 +00:00
|
|
|
*/
|
|
|
|
function scrapeReferenceType( $referenceText ) {
|
2019-02-20 16:15:34 +00:00
|
|
|
let type = null;
|
|
|
|
|
|
|
|
$referenceText.find( 'cite[class]' ).each( function ( index, el ) {
|
|
|
|
const nextType = el.className.replace( /\bcitation\b\s*/g, '' ).trim();
|
|
|
|
|
|
|
|
if ( !type ) {
|
|
|
|
type = nextType;
|
|
|
|
} else if ( nextType && nextType !== type ) {
|
|
|
|
type = null;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} );
|
2019-02-19 16:01:16 +00:00
|
|
|
|
2019-02-20 16:15:34 +00:00
|
|
|
return type;
|
2019-02-19 16:01:16 +00:00
|
|
|
}
|
|
|
|
|
2018-12-12 18:37:19 +00:00
|
|
|
/**
|
|
|
|
* @param {mw.Title} title
|
2019-02-04 12:08:36 +00:00
|
|
|
* @param {Element} el
|
2019-08-05 12:35:21 +00:00
|
|
|
* @return {AbortPromise<ReferencePreviewModel>}
|
2018-12-12 18:37:19 +00:00
|
|
|
*/
|
2019-02-04 12:08:36 +00:00
|
|
|
function fetchPreviewForTitle( title, el ) {
|
2019-01-24 10:37:30 +00:00
|
|
|
// Need to encode the fragment again as mw.Title returns it as decoded text
|
2019-01-25 19:44:48 +00:00
|
|
|
const id = title.getFragment().replace( / /g, '_' ),
|
2019-02-20 10:35:34 +00:00
|
|
|
$referenceText = scrapeReferenceText( id );
|
2019-01-25 19:44:48 +00:00
|
|
|
|
|
|
|
if ( !$referenceText.length ) {
|
|
|
|
return $.Deferred().reject(
|
|
|
|
'Footnote not found',
|
|
|
|
// Required to set `showNullPreview` to false and not open an error popup
|
|
|
|
{ textStatus: 'abort', xhr: { readyState: 0 } }
|
|
|
|
).promise( { abort() {} } );
|
|
|
|
}
|
2018-12-12 18:37:19 +00:00
|
|
|
|
2019-02-16 09:13:23 +00:00
|
|
|
const model = {
|
2019-08-05 12:42:21 +00:00
|
|
|
url: `#${id}`,
|
2019-01-25 19:44:48 +00:00
|
|
|
extract: $referenceText.html(),
|
2019-02-04 12:08:36 +00:00
|
|
|
type: previewTypes.TYPE_REFERENCE,
|
2019-02-19 16:01:16 +00:00
|
|
|
referenceType: scrapeReferenceType( $referenceText ),
|
2019-02-04 12:08:36 +00:00
|
|
|
sourceElementId: el && el.parentNode && el.parentNode.id
|
2019-02-16 09:13:23 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
return $.Deferred().resolve( model ).promise( { abort() {} } );
|
2018-12-12 18:37:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
2019-01-23 16:50:19 +00:00
|
|
|
fetchPreviewForTitle
|
2018-12-12 18:37:19 +00:00
|
|
|
};
|
|
|
|
}
|