Fix regression showing page previews on ^ jump mark links

This happened one time before and was fixed via T212419. It now came
back after I2670331, a patch for T214861 that made the title parser
accept more links than before.

This patch implements a decision tree that goes as follows:
1. If it's a link to another page, it can't be anything but a page
   preview, as having a peek into another page is effectively the
   definition of a page preview.
2. Otherwise it's probably a reference preview, but only if:
   * It's a link with a jump mark.
   * The link is actually marked as being a "reference".
   * Reference previews are enabled.
3. If neither of these definitions fit, do nothing. Note this is not
   "hiding errors" we would be able to fix in this code. There are many
   ways to manually arrange wikitext in a way that it looks like one or
   the other, without fulfilling all requirements. Unfortunately the
   user who would see error message or dysfunctional popups would not
   be the same as the user who wrote such wikitext.

Bug: T216683
Change-Id: I8d021f19ddc73a261e6a0c62959ddd0cb1d3182d
This commit is contained in:
Thiemo Kreuz 2019-02-21 13:34:16 +01:00 committed by Stephen Niedzielski
parent 06d348041e
commit d1c0613186
4 changed files with 36 additions and 23 deletions

Binary file not shown.

Binary file not shown.

View file

@ -43,19 +43,21 @@ const $ = jQuery;
* @param {Element} el * @param {Element} el
* @param {mw.Map} config * @param {mw.Map} config
* @param {mw.Title} title * @param {mw.Title} title
* @return {string} * @return {string|null}
*/ */
export default function selectGatewayType( el, config, title ) { export default function selectGatewayType( el, config, title ) {
if ( config.get( 'wgPopupsReferencePreviews' ) ) { if ( title.getPrefixedDb() !== config.get( 'wgPageName' ) ) {
// The other selector can potentially pick up self-links with a class="reference" return previewTypes.TYPE_PAGE;
// parent, but no fragment
if ( title.getFragment() &&
title.getPrefixedDb() === config.get( 'wgPageName' ) &&
$( el ).parent().hasClass( 'reference' )
) {
return previewTypes.TYPE_REFERENCE;
}
} }
return previewTypes.TYPE_PAGE; // The other selector can potentially pick up self-links with a class="reference"
// parent, but no fragment
if ( title.getFragment() &&
config.get( 'wgPopupsReferencePreviews' ) &&
$( el ).parent().hasClass( 'reference' )
) {
return previewTypes.TYPE_REFERENCE;
}
return null;
} }

View file

@ -7,52 +7,63 @@ QUnit.module( 'gateway/index.js', {
this.config = new Map(); /* global Map */ this.config = new Map(); /* global Map */
this.config.set( 'wgPopupsReferencePreviews', true ); this.config.set( 'wgPopupsReferencePreviews', true );
this.config.set( 'wgPageName', 'Foo' ); this.config.set( 'wgPageName', 'Foo' );
this.fragmentLink = createStubTitle( 1, 'Foo', 'Bar' ); this.referenceLink = createStubTitle( 1, 'Foo', 'ref-fragment' );
this.validEl = $( '<a>' ).appendTo( $( '<span>' ).addClass( 'reference' ) ); this.validEl = $( '<a>' ).appendTo( $( '<span>' ).addClass( 'reference' ) );
} }
} ); } );
QUnit.test( 'it uses the reference gateway with wgPopupsReferencePreviews == true and valid element', function ( assert ) { QUnit.test( 'it uses the reference gateway with wgPopupsReferencePreviews == true and valid element', function ( assert ) {
assert.strictEqual( assert.strictEqual(
selectInitialGateway( this.validEl, this.config, this.fragmentLink ), selectInitialGateway( this.validEl, this.config, this.referenceLink ),
previewTypes.TYPE_REFERENCE previewTypes.TYPE_REFERENCE
); );
} ); } );
QUnit.test( 'it uses the page gateway with wgPopupsReferencePreviews == false', function ( assert ) { QUnit.test( 'it does not suggest page previews on reference links when reference previews are disabled', function ( assert ) {
this.config.set( 'wgPopupsReferencePreviews', false ); this.config.set( 'wgPopupsReferencePreviews', false );
assert.strictEqual( assert.strictEqual(
selectInitialGateway( this.validEl, this.config, this.fragmentLink ), selectInitialGateway( this.validEl, this.config, this.referenceLink ),
previewTypes.TYPE_PAGE null
); );
} ); } );
QUnit.test( 'it uses the page gateway when on links to a different page', function ( assert ) { QUnit.test( 'it uses the page gateway when on links to a different page', function ( assert ) {
this.config.set( 'wgPageName', 'NotFoo' ); assert.strictEqual(
selectInitialGateway(
this.validEl,
this.config,
createStubTitle( 1, 'NotFoo' )
),
previewTypes.TYPE_PAGE
);
assert.strictEqual( assert.strictEqual(
selectInitialGateway( this.validEl, this.config, this.fragmentLink ), selectInitialGateway(
this.validEl,
this.config,
createStubTitle( 1, 'NotFoo', 'fragment' )
),
previewTypes.TYPE_PAGE previewTypes.TYPE_PAGE
); );
} ); } );
QUnit.test( 'it uses the page gateway when there is no fragment', function ( assert ) { QUnit.test( 'it does not use the reference gateway when there is no fragment', function ( assert ) {
assert.strictEqual( assert.strictEqual(
selectInitialGateway( selectInitialGateway(
this.validEl, this.validEl,
this.config, this.config,
createStubTitle( 1, 'Foo' ) createStubTitle( 1, 'Foo' )
), ),
previewTypes.TYPE_PAGE null
); );
} ); } );
QUnit.test( 'it uses the page gateway for links not having a parent with reference class', function ( assert ) { QUnit.test( 'it does not suggest page previews on reference links not having a parent with reference class', function ( assert ) {
const el = $( '<a>' ).appendTo( $( '<span>' ) ); const el = $( '<a>' ).appendTo( $( '<span>' ) );
assert.strictEqual( assert.strictEqual(
selectInitialGateway( el, this.config, this.fragmentLink ), selectInitialGateway( el, this.config, this.referenceLink ),
previewTypes.TYPE_PAGE null
); );
} ); } );