mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Cite
synced 2024-11-11 16:49:26 +00:00
Merge "Switch reuse dialog to use shared numbering mechanism"
This commit is contained in:
commit
c50282b381
|
@ -140,54 +140,48 @@ ve.ui.MWReferenceSearchWidget.prototype.buildIndex = function () {
|
|||
* @return {Object[]}
|
||||
*/
|
||||
ve.ui.MWReferenceSearchWidget.prototype.buildSearchIndex = function () {
|
||||
const docRefs = ve.dm.MWDocumentReferences.static.refsForDoc( this.internalList.getDocument() );
|
||||
const groups = this.internalList.getNodeGroups();
|
||||
const index = [];
|
||||
const groupNames = Object.keys( groups ).sort();
|
||||
|
||||
// FIXME: Temporary hack, to be removed soon
|
||||
// eslint-disable-next-line no-jquery/no-class-state
|
||||
const filterExtends = this.$element.hasClass( 've-ui-citoidInspector-extends' );
|
||||
|
||||
let index = [];
|
||||
for ( let i = 0; i < groupNames.length; i++ ) {
|
||||
const groupName = groupNames[ i ];
|
||||
if ( groupName.indexOf( 'mwReference/' ) !== 0 ) {
|
||||
// FIXME: Should be impossible to reach
|
||||
continue;
|
||||
}
|
||||
const group = groups[ groupName ];
|
||||
const firstNodes = group.firstNodes;
|
||||
const indexOrder = group.indexOrder;
|
||||
const groupedByParent = docRefs.getGroupRefsByParents( groupName );
|
||||
let flatNodes = [];
|
||||
if ( filterExtends ) {
|
||||
flatNodes = ( groupedByParent[ '' ] || [] );
|
||||
} else {
|
||||
// flatMap
|
||||
( groupedByParent[ '' ] || [] ).forEach( ( parentNode ) => {
|
||||
flatNodes.push( parentNode );
|
||||
flatNodes = flatNodes.concat( groupedByParent[ parentNode.getAttribute( 'listKey' ) ] || [] );
|
||||
} );
|
||||
}
|
||||
|
||||
let n = 0;
|
||||
for ( let j = 0; j < indexOrder.length; j++ ) {
|
||||
const refNode = firstNodes[ indexOrder[ j ] ];
|
||||
// Exclude placeholder references
|
||||
if ( !refNode || refNode.getAttribute( 'placeholder' ) ) {
|
||||
continue;
|
||||
}
|
||||
// FIXME: This might miss subrefs that are reused without repeating the extends attribute
|
||||
if ( filterExtends && refNode.getAttribute( 'extendsRef' ) ) {
|
||||
continue;
|
||||
}
|
||||
// Only increment counter for real references
|
||||
n++;
|
||||
const refModel = ve.dm.MWReferenceModel.static.newFromReferenceNode( refNode );
|
||||
const itemNode = this.internalList.getItemNode( refModel.getListIndex() );
|
||||
index = index.concat( flatNodes.map( ( node ) => {
|
||||
const listKey = node.getAttribute( 'listKey' );
|
||||
// remove `mwReference/` prefix
|
||||
const group = groupName.slice( 12 );
|
||||
const footnoteNumber = docRefs.getIndexNumber( group, listKey );
|
||||
const citation = ( group ? group + ' ' : '' ) + footnoteNumber;
|
||||
|
||||
const refGroup = refModel.getGroup();
|
||||
const citation = ( refGroup ? refGroup + ' ' : '' ) + n;
|
||||
// Use [\s\S]* instead of .* to catch esoteric whitespace (T263698)
|
||||
const matches = refModel.getListKey().match( /^literal\/([\s\S]*)$/ );
|
||||
const matches = listKey.match( /^literal\/([\s\S]*)$/ );
|
||||
const name = matches && matches[ 1 ] || '';
|
||||
|
||||
// TODO: At some point we need to make sure this text is updated in
|
||||
// case the view node is still rendering. This shouldn't happen because
|
||||
// all references are supposed to be in the store and therefore are
|
||||
// immediately rendered, but we shouldn't trust that on principle to
|
||||
// account for edge cases.
|
||||
|
||||
let $element;
|
||||
// Make visible text, citation and reference name searchable
|
||||
let text = ( citation + ' ' + name ).toLowerCase();
|
||||
const itemNode = this.internalList.getItemNode( node.getAttribute( 'listIndex' ) );
|
||||
if ( itemNode.length ) {
|
||||
$element = new ve.ui.MWPreviewElement( itemNode, { useView: true } ).$element;
|
||||
text = $element.text().toLowerCase() + ' ' + text;
|
||||
|
@ -201,14 +195,15 @@ ve.ui.MWReferenceSearchWidget.prototype.buildSearchIndex = function () {
|
|||
.text( ve.msg( 'cite-ve-referenceslist-missingref-in-list' ) );
|
||||
}
|
||||
|
||||
index.push( {
|
||||
return {
|
||||
$element: $element,
|
||||
text: text,
|
||||
reference: refModel,
|
||||
// TODO: return a simple node
|
||||
reference: ve.dm.MWReferenceModel.static.newFromReferenceNode( node ),
|
||||
citation: citation,
|
||||
name: name
|
||||
} );
|
||||
}
|
||||
};
|
||||
} ) );
|
||||
}
|
||||
|
||||
return index;
|
||||
|
|
|
@ -2,11 +2,35 @@
|
|||
|
||||
QUnit.module( 've.ui.MWReferenceSearchWidget (Cite)', ve.test.utils.newMwEnvironment() );
|
||||
|
||||
function getInternalListMock( groups, mockWithNode ) {
|
||||
const node = mockWithNode ? {
|
||||
getAttribute: () => ( 'literal/foo' ),
|
||||
getAttributes: () => ( {} )
|
||||
} : {};
|
||||
const refDocMock = {
|
||||
getGroupRefsByParents: () => ( { '': [ node ] } ),
|
||||
getIndexNumber: () => ( 1 ),
|
||||
getItemNode: () => ( node )
|
||||
};
|
||||
const docMock = {
|
||||
getStorage: () => ( refDocMock )
|
||||
};
|
||||
const mockInternalList = {
|
||||
getDocument: () => ( docMock ),
|
||||
getNodeGroups: () => ( groups || {} ),
|
||||
getItemNode: () => ( node )
|
||||
};
|
||||
docMock.getInternalList = () => ( mockInternalList );
|
||||
node.getDocument = () => ( docMock );
|
||||
|
||||
return mockInternalList;
|
||||
}
|
||||
|
||||
QUnit.test( 'buildIndex', ( assert ) => {
|
||||
const widget = new ve.ui.MWReferenceSearchWidget();
|
||||
widget.internalList = { getNodeGroups: () => ( {} ) };
|
||||
assert.strictEqual( widget.index, null );
|
||||
widget.internalList = getInternalListMock();
|
||||
|
||||
assert.strictEqual( widget.index, null );
|
||||
widget.buildIndex();
|
||||
assert.deepEqual( widget.index, [] );
|
||||
|
||||
|
@ -22,18 +46,7 @@ QUnit.test( 'buildIndex', ( assert ) => {
|
|||
|
||||
QUnit.test( 'buildSearchIndex when empty', ( assert ) => {
|
||||
const widget = new ve.ui.MWReferenceSearchWidget();
|
||||
widget.internalList = { getNodeGroups: () => ( {} ) };
|
||||
|
||||
const index = widget.buildSearchIndex();
|
||||
assert.deepEqual( index, [] );
|
||||
} );
|
||||
|
||||
QUnit.test( 'buildSearchIndex with a placeholder', ( assert ) => {
|
||||
const widget = new ve.ui.MWReferenceSearchWidget();
|
||||
const placeholder = true;
|
||||
const node = { getAttribute: () => placeholder };
|
||||
const groups = { 'mwReference/': { indexOrder: [ 0 ], firstNodes: [ node ] } };
|
||||
widget.internalList = { getNodeGroups: () => groups, getItemNode: () => [] };
|
||||
widget.internalList = getInternalListMock();
|
||||
|
||||
const index = widget.buildSearchIndex();
|
||||
assert.deepEqual( index, [] );
|
||||
|
@ -41,19 +54,8 @@ QUnit.test( 'buildSearchIndex with a placeholder', ( assert ) => {
|
|||
|
||||
QUnit.test( 'buildSearchIndex', ( assert ) => {
|
||||
const widget = new ve.ui.MWReferenceSearchWidget();
|
||||
|
||||
// XXX: This is a regression test with a fragile setup. Please feel free to delete this test
|
||||
// when you feel like it doesn't make sense to update it.
|
||||
const placeholder = false;
|
||||
const node = {
|
||||
getDocument: () => ( {
|
||||
getInternalList: () => null
|
||||
} ),
|
||||
getAttributes: () => ( { listKey: 'literal/foo' } ),
|
||||
getAttribute: () => placeholder
|
||||
};
|
||||
const groups = { 'mwReference/': { indexOrder: [ 0 ], firstNodes: [ node ] } };
|
||||
widget.internalList = { getNodeGroups: () => groups, getItemNode: () => [] };
|
||||
const groups = { 'mwReference/': {} };
|
||||
widget.internalList = getInternalListMock( groups, true );
|
||||
|
||||
const index = widget.buildSearchIndex();
|
||||
assert.deepEqual( index.length, 1 );
|
||||
|
|
Loading…
Reference in a new issue