2024-06-28 09:54:20 +00:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* @copyright 2024 VisualEditor Team's Cite sub-team and others; see AUTHORS.txt
|
|
|
|
* @license MIT
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A facade providing a simplified and safe interface to Cite `ref` and
|
|
|
|
* `references` tags in a document.
|
|
|
|
*
|
|
|
|
* @constructor
|
|
|
|
* @mixes OO.EventEmitter
|
|
|
|
* @param {ve.dm.Document} doc The document that reference tags will be embedded in.
|
|
|
|
*/
|
|
|
|
ve.dm.MWDocumentReferences = function VeDmMWDocumentReferences( doc ) {
|
|
|
|
// Mixin constructors
|
|
|
|
OO.EventEmitter.call( this );
|
|
|
|
|
|
|
|
// Properties
|
|
|
|
this.doc = doc;
|
2024-08-02 09:57:08 +00:00
|
|
|
/**
|
|
|
|
* Holds the information calculated for each group.
|
|
|
|
*
|
|
|
|
* @member {Object.<string, ve.dm.MWGroupReferences>}
|
|
|
|
*/
|
2024-06-28 10:12:37 +00:00
|
|
|
this.cachedByGroup = {};
|
|
|
|
|
|
|
|
doc.getInternalList().connect( this, { update: 'updateGroups' } );
|
|
|
|
this.updateAllGroups();
|
2024-06-28 09:54:20 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Inheritance */
|
|
|
|
|
|
|
|
OO.mixinClass( ve.dm.MWDocumentReferences, OO.EventEmitter );
|
|
|
|
|
|
|
|
/* Methods */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Singleton MWDocumentReferences for a document.
|
|
|
|
*
|
2024-09-10 09:50:27 +00:00
|
|
|
* @param {ve.dm.Document} doc Source document associated with the
|
|
|
|
* singleton. May be a fragment in which case we only look at refs included in
|
|
|
|
* the fragment.
|
|
|
|
*
|
2024-06-28 09:54:20 +00:00
|
|
|
* @return {ve.dm.MWDocumentReferences} Singleton docRefs
|
|
|
|
*/
|
2024-09-10 09:50:27 +00:00
|
|
|
ve.dm.MWDocumentReferences.static.refsForDoc = function ( doc ) {
|
|
|
|
let docRefs;
|
2024-10-20 08:44:03 +00:00
|
|
|
// Only use cache if we're working with the full document.
|
2024-09-10 09:50:27 +00:00
|
|
|
if ( !doc.getOriginalDocument() ) {
|
2024-10-20 08:44:03 +00:00
|
|
|
docRefs = doc.extCiteDocumentReferences;
|
2024-09-10 09:50:27 +00:00
|
|
|
}
|
2024-06-28 09:54:20 +00:00
|
|
|
if ( docRefs === undefined ) {
|
|
|
|
docRefs = new ve.dm.MWDocumentReferences( doc );
|
2024-09-10 09:50:27 +00:00
|
|
|
}
|
|
|
|
if ( !doc.getOriginalDocument() ) {
|
2024-10-20 08:44:03 +00:00
|
|
|
doc.extCiteDocumentReferences = docRefs;
|
2024-06-28 09:54:20 +00:00
|
|
|
}
|
|
|
|
return docRefs;
|
|
|
|
};
|
|
|
|
|
2024-06-28 10:12:37 +00:00
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
ve.dm.MWDocumentReferences.prototype.updateAllGroups = function () {
|
2024-07-27 16:57:24 +00:00
|
|
|
this.updateGroups( this.getAllGroupNames() );
|
2024-06-28 10:12:37 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
* @param {string[]} groupsChanged A list of group names which have changed in
|
|
|
|
* this transaction
|
|
|
|
*/
|
|
|
|
ve.dm.MWDocumentReferences.prototype.updateGroups = function ( groupsChanged ) {
|
|
|
|
groupsChanged.forEach( ( groupName ) => this.updateGroup( groupName ) );
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
* @param {string[]} groupName Name of the reference group which needs to be
|
2024-08-02 09:57:08 +00:00
|
|
|
* updated, with prefix
|
2024-06-28 10:12:37 +00:00
|
|
|
*/
|
|
|
|
ve.dm.MWDocumentReferences.prototype.updateGroup = function ( groupName ) {
|
2024-08-02 09:57:08 +00:00
|
|
|
const nodeGroup = this.doc.getInternalList().getNodeGroup( groupName );
|
|
|
|
this.cachedByGroup[ groupName ] = ve.dm.MWGroupReferences.static.makeGroupRefs( nodeGroup );
|
|
|
|
};
|
2024-06-28 10:12:37 +00:00
|
|
|
|
2024-08-02 09:57:08 +00:00
|
|
|
/**
|
|
|
|
* @param {string} groupName with or without prefix
|
|
|
|
* @return {ve.dm.MWGroupReferences}
|
|
|
|
*/
|
|
|
|
ve.dm.MWDocumentReferences.prototype.getGroupRefs = function ( groupName ) {
|
2024-08-23 14:25:51 +00:00
|
|
|
return this.cachedByGroup[ groupName.startsWith( 'mwReference/' ) ? groupName : 'mwReference/' + groupName ] ||
|
|
|
|
new ve.dm.MWGroupReferences();
|
2024-06-28 10:12:37 +00:00
|
|
|
};
|
|
|
|
|
2024-07-27 16:57:24 +00:00
|
|
|
ve.dm.MWDocumentReferences.prototype.getAllGroupNames = function () {
|
|
|
|
return Object.keys( this.doc.getInternalList().getNodeGroups() );
|
|
|
|
};
|
|
|
|
|
2024-08-30 10:40:27 +00:00
|
|
|
ve.dm.MWDocumentReferences.prototype.hasRefs = function () {
|
|
|
|
return this.getAllGroupNames().some( ( groupName ) => !this.getGroupRefs( groupName ).isEmpty() );
|
|
|
|
};
|
|
|
|
|
2024-06-28 10:12:37 +00:00
|
|
|
/**
|
|
|
|
* Return a formatted number, in the content script, with no separators.
|
|
|
|
*
|
|
|
|
* Partial clone of mw.language.convertNumber .
|
|
|
|
*
|
|
|
|
* @param {number} num
|
|
|
|
* @return {string}
|
|
|
|
*/
|
|
|
|
ve.dm.MWDocumentReferences.static.contentLangDigits = function ( num ) {
|
|
|
|
const contentLang = mw.config.get( 'wgContentLanguage' );
|
2024-07-23 13:07:35 +00:00
|
|
|
const digitLookup = mw.config.get( 'wgTranslateNumerals' ) &&
|
|
|
|
mw.language.getData( contentLang, 'digitTransformTable' );
|
2024-06-28 10:12:37 +00:00
|
|
|
const numString = String( num );
|
|
|
|
if ( !digitLookup ) {
|
|
|
|
return numString;
|
|
|
|
}
|
|
|
|
return numString.split( '' ).map( ( numChar ) => digitLookup[ numChar ] ).join( '' );
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2024-07-27 17:04:33 +00:00
|
|
|
* @deprecated Should be refactored to store formatted index numbers as a simple
|
|
|
|
* property on each CE ref node after document transaction.
|
2024-06-28 10:12:37 +00:00
|
|
|
* @param {string} groupName Ref group without prefix
|
|
|
|
* @param {string} listKey Ref key with prefix
|
|
|
|
* @return {string} Rendered index number string which can be used as a footnote
|
|
|
|
* marker or reflist item number.
|
|
|
|
*/
|
2024-07-27 17:04:33 +00:00
|
|
|
ve.dm.MWDocumentReferences.prototype.getIndexLabel = function ( groupName, listKey ) {
|
2024-08-02 09:57:08 +00:00
|
|
|
return this.getGroupRefs( groupName ).getIndexLabel( listKey );
|
2024-06-28 09:54:20 +00:00
|
|
|
};
|