mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Popups
synced 2024-11-23 23:24:39 +00:00
Use href attribute to calculate titles
This is needed for wikis that use LanguageConverter, since the title attribute is converted to the user's variant, and the canonical title is needed for the API unless converttitles is specified. For filtering, instead of comparing linkHref and expectedHref, filter out links that have other query parameters or aren't in content namespaces. Bug: T93605 Change-Id: I5534753307ed5e1d4b27c52c616fd143b2a397e1
This commit is contained in:
parent
56453bc7b1
commit
642bdf013e
|
@ -52,11 +52,13 @@ class PopupsHooks {
|
||||||
public static function onResourceLoaderRegisterModules( ResourceLoader $rl ) {
|
public static function onResourceLoaderRegisterModules( ResourceLoader $rl ) {
|
||||||
$moduleDependencies = array(
|
$moduleDependencies = array(
|
||||||
'mediawiki.api',
|
'mediawiki.api',
|
||||||
|
'mediawiki.Title',
|
||||||
'mediawiki.jqueryMsg',
|
'mediawiki.jqueryMsg',
|
||||||
'mediawiki.Uri',
|
'mediawiki.Uri',
|
||||||
'moment',
|
'moment',
|
||||||
'jquery.jStorage',
|
'jquery.jStorage',
|
||||||
'jquery.client',
|
'jquery.client',
|
||||||
|
'jquery.mwExtension',
|
||||||
);
|
);
|
||||||
|
|
||||||
// If EventLogging is present, add the schema as a dependency.
|
// If EventLogging is present, add the schema as a dependency.
|
||||||
|
@ -121,7 +123,10 @@ class PopupsHooks {
|
||||||
*/
|
*/
|
||||||
public static function onResourceLoaderTestModules( array &$testModules, ResourceLoader &$resourceLoader ) {
|
public static function onResourceLoaderTestModules( array &$testModules, ResourceLoader &$resourceLoader ) {
|
||||||
$testModules['qunit']['ext.popups.tests'] = array(
|
$testModules['qunit']['ext.popups.tests'] = array(
|
||||||
'scripts' => array( 'tests/qunit/ext.popups.renderer.article.test.js' ),
|
'scripts' => array(
|
||||||
|
'tests/qunit/ext.popups.renderer.article.test.js',
|
||||||
|
'tests/qunit/ext.popups.core.test.js',
|
||||||
|
),
|
||||||
'dependencies' => array( 'ext.popups' ),
|
'dependencies' => array( 'ext.popups' ),
|
||||||
'localBasePath' => __DIR__,
|
'localBasePath' => __DIR__,
|
||||||
'remoteExtPath' => 'Popups',
|
'remoteExtPath' => 'Popups',
|
||||||
|
|
|
@ -145,21 +145,63 @@
|
||||||
} );
|
} );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an href string for the local wiki, return the title, or undefined if
|
||||||
|
* the link is external, has extra query parameters, or contains no title.
|
||||||
|
*
|
||||||
|
* Note that the returned title is not sanitized (may contain underscores).
|
||||||
|
*
|
||||||
|
* @param {string} href
|
||||||
|
* @return {string|undefined}
|
||||||
|
*/
|
||||||
|
mw.popups.getTitle = function ( href ) {
|
||||||
|
var title, titleRegex, matches,
|
||||||
|
linkHref = new mw.Uri( href );
|
||||||
|
|
||||||
|
// External links
|
||||||
|
if ( linkHref.host !== location.hostname ) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( linkHref.query.hasOwnProperty( 'title' ) ) {
|
||||||
|
// linkHref is not a pretty URL, e.g. /w/index.php?title=Foo
|
||||||
|
|
||||||
|
title = linkHref.query.title;
|
||||||
|
// Return undefined if there are query parameters other than title
|
||||||
|
delete linkHref.query.title;
|
||||||
|
return $.isEmptyObject( linkHref.query ) ? title : undefined;
|
||||||
|
} else {
|
||||||
|
// linkHref is a pretty URL, e.g. /wiki/Foo
|
||||||
|
|
||||||
|
// Return undefined if there are any query parameters
|
||||||
|
if ( !$.isEmptyObject( linkHref.query ) ) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
titleRegex = new RegExp( $.escapeRE( mw.config.get( 'wgArticlePath' ) )
|
||||||
|
.replace( '\\$1', '(.+)' ) );
|
||||||
|
matches = titleRegex.exec( linkHref.path );
|
||||||
|
return matches ? decodeURIComponent( matches[1] ) : undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns links that can have Popups
|
* Returns links that can have Popups
|
||||||
*
|
*
|
||||||
* @method selectPopupElements
|
* @method selectPopupElements
|
||||||
*/
|
*/
|
||||||
mw.popups.selectPopupElements = function () {
|
mw.popups.selectPopupElements = function () {
|
||||||
|
var contentNamespaces = mw.config.get( 'wgContentNamespaces' );
|
||||||
return mw.popups.$content
|
return mw.popups.$content
|
||||||
.find( 'a[href][title]:not(' + mw.popups.IGNORE_CLASSES.join(', ') + ')' )
|
.find( 'a[href][title]:not(' + mw.popups.IGNORE_CLASSES.join(', ') + ')' )
|
||||||
.filter( function () {
|
.filter( function () {
|
||||||
var linkHref = new mw.Uri( this.href ),
|
var title,
|
||||||
expectedHref = new mw.Uri( mw.util.getUrl( this.title ) );
|
titleText = mw.popups.getTitle( this.href );
|
||||||
|
if ( !titleText ) {
|
||||||
// don't compare fragment to display popups on anchored page links
|
return false;
|
||||||
linkHref.fragment = undefined;
|
}
|
||||||
return linkHref.toString() === expectedHref.toString();
|
// Is titleText in a content namespace?
|
||||||
|
title = mw.Title.newFromText( titleText );
|
||||||
|
return title && ( $.inArray( title.namespace, contentNamespaces ) >= 0 );
|
||||||
} );
|
} );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,8 @@
|
||||||
* @return {jQuery.Promise}
|
* @return {jQuery.Promise}
|
||||||
*/
|
*/
|
||||||
article.init = function ( link ) {
|
article.init = function ( link ) {
|
||||||
var
|
var href = link.attr( 'href' ),
|
||||||
href = link.attr( 'href' ),
|
title = mw.popups.getTitle( href ),
|
||||||
title = link.data( 'title' ),
|
|
||||||
deferred = $.Deferred();
|
deferred = $.Deferred();
|
||||||
|
|
||||||
if ( !title ) {
|
if ( !title ) {
|
||||||
|
|
33
tests/qunit/ext.popups.core.test.js
Normal file
33
tests/qunit/ext.popups.core.test.js
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
( function ( $, mw ) {
|
||||||
|
|
||||||
|
QUnit.module( 'ext.popups.core', QUnit.newMwEnvironment( {
|
||||||
|
config: {
|
||||||
|
wgArticlePath: '/wiki/$1'
|
||||||
|
}
|
||||||
|
} ) );
|
||||||
|
|
||||||
|
QUnit.test( 'getTitle', function ( assert ) {
|
||||||
|
var cases, i, expected, actual;
|
||||||
|
|
||||||
|
QUnit.expect( 10 );
|
||||||
|
cases = [
|
||||||
|
[ '/wiki/Foo', 'Foo' ],
|
||||||
|
[ '/wiki/Foo#Bar', 'Foo' ],
|
||||||
|
[ '/wiki/Foo?oldid=1', undefined ],
|
||||||
|
[ '/wiki/%E6%B8%AC%E8%A9%A6', '測試' ],
|
||||||
|
[ '/w/index.php?title=Foo', 'Foo' ],
|
||||||
|
[ '/w/index.php?title=Foo#Bar', 'Foo' ],
|
||||||
|
[ '/w/Foo?title=Foo&action=edit', undefined ],
|
||||||
|
[ '/w/index.php?title=%E6%B8%AC%E8%A9%A6', '測試' ],
|
||||||
|
[ '/w/index.php?oldid=1', undefined ],
|
||||||
|
[ '/Foo', undefined ]
|
||||||
|
];
|
||||||
|
|
||||||
|
for ( i = 0; i < cases.length; i++ ) {
|
||||||
|
expected = cases[i][1];
|
||||||
|
actual = mw.popups.getTitle( cases[i][0] );
|
||||||
|
assert.equal( actual, expected );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
} ) ( jQuery, mediaWiki );
|
|
@ -1,6 +1,7 @@
|
||||||
( function ( $, mw ) {
|
( function ( $, mw ) {
|
||||||
|
|
||||||
QUnit.module( 'ext.popups' );
|
QUnit.module( 'ext.popups.renderer.article', QUnit.newMwEnvironment() );
|
||||||
|
|
||||||
QUnit.test( 'render.article.getProcessedElements', function ( assert ) {
|
QUnit.test( 'render.article.getProcessedElements', function ( assert ) {
|
||||||
QUnit.expect( 13 );
|
QUnit.expect( 13 );
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue