From de7f294f91abb2087b4479eabe6454e22e0f812f Mon Sep 17 00:00:00 2001 From: Adam Wight Date: Tue, 2 Jul 2024 10:39:35 +0200 Subject: [PATCH] Promote orphaned subrefs to the top level This isn't the ideal solution since it doesn't exactly match the rendered reader view, but it's a reasonable workaround and an improvement on "undefined" numbering. Bug: T247921 Change-Id: Ic0d88123d50e2fcb7f25e897280dbfdb6d494501 --- modules/ve-cite/ve.dm.MWDocumentReferences.js | 39 ++++++++++++++----- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/modules/ve-cite/ve.dm.MWDocumentReferences.js b/modules/ve-cite/ve.dm.MWDocumentReferences.js index db62bcaa5..c8fb6ffed 100644 --- a/modules/ve-cite/ve.dm.MWDocumentReferences.js +++ b/modules/ve-cite/ve.dm.MWDocumentReferences.js @@ -55,14 +55,33 @@ ve.dm.MWDocumentReferences.static.refsForDoc = function ( doc ) { */ ve.dm.MWDocumentReferences.prototype.getGroupRefsByParents = function ( groupName ) { const nodeGroup = this.doc.getInternalList().getNodeGroup( groupName ); - return ( nodeGroup ? nodeGroup.indexOrder : [] ) - .reduce( ( acc, index ) => { - const node = nodeGroup.firstNodes[ index ]; - const extendsRef = node.element.attributes.extendsRef || ''; - if ( acc[ extendsRef ] === undefined ) { - acc[ extendsRef ] = []; - } - acc[ extendsRef ].push( node ); - return acc; - }, {} ); + const indexOrder = ( nodeGroup ? nodeGroup.indexOrder : [] ); + // Compile a list of all top-level node names so that we can handle orphans + // while keeping them in document order. + const seenTopLevelNames = new Set( + indexOrder + .map( ( index ) => nodeGroup.firstNodes[ index ] ) + .filter( ( node ) => !node.element.attributes.extendsRef ) + .map( ( node ) => node.element.attributes.listKey ) + .filter( ( listKey ) => listKey ) + ); + // Group nodes by parent ref, while iterating in order of document appearance. + return indexOrder.reduce( ( acc, index ) => { + const node = nodeGroup.firstNodes[ index ]; + let extendsRef = node.element.attributes.extendsRef || ''; + + if ( !seenTopLevelNames.has( extendsRef ) ) { + // Promote orphaned subrefs to become top-level refs. + // TODO: Ideally this would be handled by creating placeholder error + // nodes as is done by the renderer. + extendsRef = ''; + } + + if ( acc[ extendsRef ] === undefined ) { + acc[ extendsRef ] = []; + } + acc[ extendsRef ].push( node ); + + return acc; + }, {} ); };