mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Popups
synced 2024-09-23 10:21:11 +00:00
Child elements also trigger previews
Follow up to Iefe98c1f0422dbf034e385b1a41a859d030a2cf4 where we switched from the jquery event delegation pattern to native methods. One thing that we overlooked was that we also need to consider the case where the selector matches the parent of an element, for example a span nested inside an eligible link. I've rethought this logic, to first find the closest eligible element to normalize the element passed to model methods before running matchesSelector. Bug: T325007 Change-Id: I4133751dc900a51829173e9c0d965cbb18e6a33e
This commit is contained in:
parent
f642345625
commit
01e3ddcda5
|
@ -13,7 +13,7 @@
|
|||
"include": [ "src/**/*.js" ],
|
||||
|
||||
"//": "Set the coverage percentage by category thresholds.",
|
||||
"statements": 84,
|
||||
"statements": 83,
|
||||
"branches": 70,
|
||||
"functions": 82,
|
||||
"lines": 90,
|
||||
|
|
BIN
resources/dist/index.js
vendored
BIN
resources/dist/index.js
vendored
Binary file not shown.
BIN
resources/dist/index.js.map.json
vendored
BIN
resources/dist/index.js.map.json
vendored
Binary file not shown.
|
@ -25,8 +25,7 @@ import reducers from './reducers';
|
|||
import createMediaWikiPopupsObject from './integrations/mwpopups';
|
||||
import { previewTypes, getPreviewType,
|
||||
registerModel,
|
||||
isAnythingEligible,
|
||||
isEligible } from './preview/model';
|
||||
isAnythingEligible, findNearestEligibleTarget } from './preview/model';
|
||||
import isReferencePreviewsEnabled from './isReferencePreviewsEnabled';
|
||||
import setUserConfigFlags from './setUserConfigFlags';
|
||||
import { registerGatewayForPreviewType, getGatewayForPreviewType } from './gateway';
|
||||
|
@ -129,8 +128,8 @@ function registerChangeListeners(
|
|||
*/
|
||||
function handleDOMEventIfEligible( handler ) {
|
||||
return function ( event ) {
|
||||
const target = event.target;
|
||||
if ( !isEligible( target ) ) {
|
||||
const target = findNearestEligibleTarget( event.target );
|
||||
if ( target === null ) {
|
||||
return;
|
||||
}
|
||||
const mwTitle = titleFromElement( target, mw.config );
|
||||
|
|
|
@ -124,6 +124,39 @@ const elementMatchesSelector = ( element, selector ) => {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Emulates closest method for browsers that do not
|
||||
* support it. e.g. IE11.
|
||||
*
|
||||
* @param {Element} element
|
||||
* @param {string} selector
|
||||
* @return {Element|null}
|
||||
*/
|
||||
function legacyClosest( element, selector ) {
|
||||
const parentNode = element.parentNode;
|
||||
if ( elementMatchesSelector( element, selector ) ) {
|
||||
return element;
|
||||
} else if ( !parentNode || parentNode === document.body ) {
|
||||
// The `body` cannot be used as a preview selector.
|
||||
return null;
|
||||
}
|
||||
return legacyClosest( parentNode, selector );
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively checks the element and its parents.
|
||||
* @param {Element} element
|
||||
* @return {Element|null}
|
||||
*/
|
||||
export function findNearestEligibleTarget( element ) {
|
||||
const selector = selectors.join( ', ' );
|
||||
if ( element.closest ) {
|
||||
return element.closest( selector );
|
||||
} else {
|
||||
return legacyClosest( element, selector );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} PreviewType
|
||||
* @property {string} name identifier for preview type
|
||||
|
@ -217,17 +250,6 @@ export function registerModel( type, selector ) {
|
|||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the element is eligible for previews.
|
||||
*
|
||||
* @param {Element} element
|
||||
* @return {boolean}
|
||||
*/
|
||||
export function isEligible( element ) {
|
||||
const validLinkSelector = selectors.join( ', ' );
|
||||
return elementMatchesSelector( element, validLinkSelector );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether any kind of preview is enabled.
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue