Make backlink highlighting robust for community customized HTML

This change makes the code much, much more robust. See, almost all HTML
relevant for this feature is encoded in messages. This allows unexpected
customizations that add additional HTML elements, change the order of DOM
elements, even remove class names and elements.

The <ol class="references"> is the only HTML snippet generated via code,
guaranteed to be there, and used as an entry point because of this.

Instead of the selector utilizing a "*" to detect references with "one"
vs. "many" backlinks, we check if a second backlink exists.

The .first() copies the browsers behavior to only respect the first anchor
in case an id="…" appears multiple times on a page.

The additional .length check further down is a missing sanity check,
currently relevant on frwiki where the expected class="mw-cite-backlink"
got localized.

Bug: T205270
Bug: T210520
Change-Id: Iba9aebfd01508b283933964cfb986d7239d4cf38
This commit is contained in:
Thiemo Kreuz 2018-11-28 11:56:27 +01:00
parent 6dda36a1e7
commit d7c1943b04

View file

@ -13,8 +13,16 @@
accessibilityLabel;
$content.find( '.' + className ).removeClass( className );
// The additional "*" avoids the "↑" (when there is only one backlink) becoming bold.
$backlink = $content.find( '.mw-cite-backlink * a[href="#' + id + '"]' )
// Bail out if there is not at least a second backlink ("cite_references_link_many").
if ( id.slice( -2 ) === '-0' &&
!$content.find( '.references a[href="#' + id.slice( 0, -1 ) + '1"]' ).length
) {
return;
}
// The :not() skips the duplicate link created below. Relevant when double clicking.
$backlink = $content.find( '.references a[href="#' + id + '"]:not(.mw-cite-up-arrow-backlink)' )
.first()
.addClass( className );
if ( !$backlink.length ) {
@ -24,7 +32,7 @@
$backlinkWrapper = $backlink.closest( '.mw-cite-backlink' );
$upArrowLink = $backlinkWrapper.find( '.mw-cite-up-arrow-backlink' );
if ( !$upArrowLink.length ) {
if ( !$upArrowLink.length && $backlinkWrapper.length ) {
textNode = $backlinkWrapper[ 0 ].firstChild;
if ( textNode &&