diff --git a/src/ReferenceListFormatter.php b/src/ReferenceListFormatter.php index e07cfba89..3591fe5ec 100644 --- a/src/ReferenceListFormatter.php +++ b/src/ReferenceListFormatter.php @@ -147,15 +147,7 @@ class ReferenceListFormatter { private function formatListItem( Parser $parser, $key, ReferenceStackItem $ref, bool $isSectionPreview ): string { - $text = $this->referenceText( $parser, $key, $ref, $isSectionPreview ); - $extraAttributes = ''; - - if ( isset( $ref->dir ) ) { - // The following classes are generated here: - // * mw-cite-dir-ltr - // * mw-cite-dir-rtl - $extraAttributes = Html::expandAttributes( [ 'class' => 'mw-cite-dir-' . $ref->dir ] ); - } + $text = $this->renderTextAndWarnings( $parser, $key, $ref, $isSectionPreview ); // Special case for an incomplete follow="…". This is valid e.g. in the Page:… namespace on // Wikisource. Note this returns a
, not an
' . $text . '
'; } + // Parameter $4 in the cite_references_link_one and cite_references_link_many messages + $extraAttributes = ''; + if ( isset( $ref->dir ) ) { + // The following classes are generated here: + // * mw-cite-dir-ltr + // * mw-cite-dir-rtl + $extraAttributes = Html::expandAttributes( [ 'class' => 'mw-cite-dir-' . $ref->dir ] ); + } + if ( $ref->count === 1 ) { if ( !isset( $ref->name ) ) { $id = $ref->key; @@ -181,7 +182,6 @@ class ReferenceListFormatter { )->plain(); } - // Named references with >1 occurrences $backlinks = []; for ( $i = 0; $i < $ref->count; $i++ ) { $backlinks[] = $this->messageLocalizer->msg( @@ -196,6 +196,8 @@ class ReferenceListFormatter { $this->referencesFormatEntryAlternateBacklinkLabel( $parser, $i ) )->plain(); } + + // The parent of a subref might actually be unused and therefor have zero backlinks $linkTargetId = $ref->count > 0 ? $this->anchorFormatter->jumpLinkTarget( $key . '-' . $ref->key ) : ''; return $this->messageLocalizer->msg( @@ -215,17 +217,17 @@ class ReferenceListFormatter { * * @return string Wikitext */ - private function referenceText( + private function renderTextAndWarnings( Parser $parser, $key, ReferenceStackItem $ref, bool $isSectionPreview ): string { - $text = $ref->text ?? null; - if ( $text === null ) { + if ( !isset( $ref->text ) ) { return $this->errorReporter->plain( $parser, $isSectionPreview ? 'cite_warning_sectionpreview_no_text' : 'cite_error_references_no_text', $key ); } + $text = $ref->text ?? ''; foreach ( $ref->warnings as $warning ) { // @phan-suppress-next-line PhanParamTooFewUnpack $text .= ' ' . $this->errorReporter->plain( $parser, ...$warning ); diff --git a/tests/phpunit/unit/ReferenceListFormatterTest.php b/tests/phpunit/unit/ReferenceListFormatterTest.php index 765d88fb2..9b03ac1ab 100644 --- a/tests/phpunit/unit/ReferenceListFormatterTest.php +++ b/tests/phpunit/unit/ReferenceListFormatterTest.php @@ -318,7 +318,7 @@ class ReferenceListFormatterTest extends \MediaWikiUnitTestCase { $parser = $this->createNoOpMock( Parser::class ); $ref = TestUtils::refFromArray( [ 'text' => $text ] ); - $output = $formatter->referenceText( $parser, 1, $ref, $isSectionPreview ); + $output = $formatter->renderTextAndWarnings( $parser, 1, $ref, $isSectionPreview ); $this->assertSame( $expectedOutput, $output ); }