Allow more customization on the default toggle system
The naming convention remains unchainched. Default toggles are added if no mw-collapsible-toggle child element is present. Premade toggles have already one ore more mw-collapsible-toggle elements defined. Default and premade toggles (mw-collapsible-toggle) still cannot be mixed/combined with remote toggles (mw-customtoggle). * The default toggle got less rigid by removing dependency on <a> elements. * Support for multiple premade toggles was introduced. * The expand/collapse messages can be used by premade toggles via mw-collapsible-text. * Removed the linksPassthru option. This step allowed merging premadeToggleHandler into actionHandler. * The pass through functionality is now applied to all <a> elements since the default toggle does no longer depends on those. * Removed mw-collapsible-bracket because it was not used and is deprecated by mw-collapsible-text. * The test suite was adapted to reflect the latest changes. Change-Id: Ic8627c4c185e8e4175e6fef1c8e1c2190e54edaa
This commit is contained in:
parent
f375de9a3e
commit
2d95d36a8e
2 changed files with 51 additions and 45 deletions
|
|
@ -35,12 +35,6 @@
|
|||
if ( $defaultToggle === undefined ) {
|
||||
$defaultToggle = null;
|
||||
}
|
||||
if ( $defaultToggle !== null && !$defaultToggle.jquery ) {
|
||||
// is optional (may be undefined), but if defined it must be an instance of jQuery.
|
||||
// If it's not, abort right away.
|
||||
// After this $defaultToggle is either null or a valid jQuery instance.
|
||||
return;
|
||||
}
|
||||
|
||||
// Trigger a custom event to allow callers to hook to the collapsing/expanding,
|
||||
// allowing the module to be testable, and making it possible to
|
||||
|
|
@ -158,12 +152,9 @@
|
|||
if ( e ) {
|
||||
if (
|
||||
e.type === 'click' &&
|
||||
options.linksPassthru &&
|
||||
e.target.nodeName.toLowerCase() === 'a' &&
|
||||
$( e.target ).attr( 'href' ) &&
|
||||
$( e.target ).attr( 'href' ) !== '#'
|
||||
e.target.nodeName.toLowerCase() === 'a'
|
||||
) {
|
||||
// Don't fire if a link with href !== '#' was clicked, if requested (for premade togglers by default)
|
||||
// Don't fire if a link was clicked (for premade togglers)
|
||||
return;
|
||||
} else if ( e.type === 'keypress' && e.which !== 13 && e.which !== 32 ) {
|
||||
// Only handle keypresses on the "Enter" or "Space" keys
|
||||
|
|
@ -191,16 +182,15 @@
|
|||
.toggleClass( 'mw-collapsible-toggle-expanded', wasCollapsed );
|
||||
}
|
||||
|
||||
// Toggle the text ("Show"/"Hide"), if requested (for default togglers by default)
|
||||
// Toggle the text ("Show"/"Hide") within elements tagged with mw-collapsible-text
|
||||
if ( options.toggleText ) {
|
||||
collapseText = options.toggleText.collapseText;
|
||||
expandText = options.toggleText.expandText;
|
||||
|
||||
$textContainer = $toggle.find( '> a' );
|
||||
if ( !$textContainer.length ) {
|
||||
$textContainer = $toggle;
|
||||
$textContainer = $collapsible.find( '.mw-collapsible-text' );
|
||||
if ( $textContainer.length ) {
|
||||
$textContainer.text( wasCollapsed ? collapseText : expandText );
|
||||
}
|
||||
$textContainer.text( wasCollapsed ? collapseText : expandText );
|
||||
}
|
||||
|
||||
// And finally toggle the element state itself
|
||||
|
|
@ -242,7 +232,7 @@
|
|||
|
||||
this.each( function () {
|
||||
var $collapsible, collapseText, expandText, $caption, $toggle, actionHandler, buildDefaultToggleLink,
|
||||
premadeToggleHandler, $toggleLink, $firstItem, collapsibleId, $customTogglers, firstval;
|
||||
$toggleLink, $firstItem, collapsibleId, $customTogglers, firstval;
|
||||
|
||||
// Ensure class "mw-collapsible" is present in case .makeCollapsible()
|
||||
// is called on element(s) that don't have it yet.
|
||||
|
|
@ -268,28 +258,21 @@
|
|||
opts = $.extend( defaultOpts, options, opts );
|
||||
togglingHandler( $( this ), $collapsible, e, opts );
|
||||
};
|
||||
|
||||
// Default toggle link. Only build it when needed to avoid jQuery memory leaks (event data).
|
||||
buildDefaultToggleLink = function () {
|
||||
return $( '<a>' )
|
||||
.attr( {
|
||||
role: 'button',
|
||||
tabindex: 0
|
||||
} )
|
||||
return $( '<span class="mw-collapsible-text"></span>' )
|
||||
.text( collapseText )
|
||||
.wrap( '<span class="mw-collapsible-toggle"></span>' )
|
||||
.parent()
|
||||
.prepend( '<span class="mw-collapsible-bracket">[</span>' )
|
||||
.append( '<span class="mw-collapsible-bracket">]</span>' )
|
||||
.wrap( '<span class="mw-collapsible-toggle"></span>' ).parent()
|
||||
.attr( {
|
||||
role: 'button',
|
||||
tabindex: 0
|
||||
} )
|
||||
.prepend( '<span>[</span>' )
|
||||
.append( '<span>]</span>' )
|
||||
.on( 'click.mw-collapsible keypress.mw-collapsible', actionHandler );
|
||||
};
|
||||
|
||||
// Default handler for clicking on premade toggles
|
||||
premadeToggleHandler = function ( e, opts ) {
|
||||
var defaultOpts = { toggleClasses: true, linksPassthru: true };
|
||||
opts = $.extend( defaultOpts, options, opts );
|
||||
togglingHandler( $( this ), $collapsible, e, opts );
|
||||
};
|
||||
|
||||
// Check if this element has a custom position for the toggle link
|
||||
// (ie. outside the container or deeper inside the tree)
|
||||
if ( options.$customTogglers ) {
|
||||
|
|
@ -331,7 +314,6 @@
|
|||
if ( !$toggle.length ) {
|
||||
$toggleLink = buildDefaultToggleLink().appendTo( $caption );
|
||||
} else {
|
||||
actionHandler = premadeToggleHandler;
|
||||
$toggleLink = $toggle.on( 'click.mw-collapsible keypress.mw-collapsible', actionHandler )
|
||||
.prop( 'tabIndex', 0 );
|
||||
}
|
||||
|
|
@ -344,7 +326,6 @@
|
|||
if ( !$toggle.length ) {
|
||||
$toggleLink = buildDefaultToggleLink().prependTo( $firstItem.eq( -1 ) );
|
||||
} else {
|
||||
actionHandler = premadeToggleHandler;
|
||||
$toggleLink = $toggle.on( 'click.mw-collapsible keypress.mw-collapsible', actionHandler )
|
||||
.prop( 'tabIndex', 0 );
|
||||
}
|
||||
|
|
@ -374,7 +355,6 @@
|
|||
$toggleLink = buildDefaultToggleLink();
|
||||
$toggleLink.wrap( '<li class="mw-collapsible-toggle-li"></li>' ).parent().prependTo( $collapsible );
|
||||
} else {
|
||||
actionHandler = premadeToggleHandler;
|
||||
$toggleLink = $toggle.on( 'click.mw-collapsible keypress.mw-collapsible', actionHandler )
|
||||
.prop( 'tabIndex', 0 );
|
||||
}
|
||||
|
|
@ -393,7 +373,6 @@
|
|||
if ( !$toggle.length ) {
|
||||
$toggleLink = buildDefaultToggleLink().prependTo( $collapsible );
|
||||
} else {
|
||||
actionHandler = premadeToggleHandler;
|
||||
$toggleLink = $toggle.on( 'click.mw-collapsible keypress.mw-collapsible', actionHandler )
|
||||
.prop( 'tabIndex', 0 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -262,11 +262,11 @@
|
|||
$collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
|
||||
} );
|
||||
|
||||
QUnit.test( 'clicks on links inside toggler pass through (options.linksPassthru)', function ( assert ) {
|
||||
QUnit.test( 'clicks on links inside toggler pass through', function ( assert ) {
|
||||
var $collapsible = prepareCollapsible(
|
||||
'<div class="mw-collapsible">' +
|
||||
'<div class="mw-collapsible-toggle">' +
|
||||
'Toggle <a href="#top">toggle</a> toggle <b>toggle</b>' +
|
||||
'Toggle <a href="#">toggle</a> toggle <b>toggle</b>' +
|
||||
'</div>' +
|
||||
'<div class="mw-collapsible-content">' + loremIpsum + '</div>' +
|
||||
'</div>',
|
||||
|
|
@ -288,12 +288,12 @@
|
|||
loremIpsum +
|
||||
'</div>'
|
||||
),
|
||||
$toggleLink = $collapsible.find( '.mw-collapsible-toggle a' );
|
||||
$toggleText = $collapsible.find( '.mw-collapsible-text' );
|
||||
|
||||
assert.equal( $toggleLink.text(), 'Collapse me!', 'data-collapsetext is respected' );
|
||||
assert.equal( $toggleText.text(), 'Collapse me!', 'data-collapsetext is respected' );
|
||||
|
||||
$collapsible.on( 'afterCollapse.mw-collapsible', function () {
|
||||
assert.equal( $toggleLink.text(), 'Expand me!', 'data-expandtext is respected' );
|
||||
assert.equal( $toggleText.text(), 'Expand me!', 'data-expandtext is respected' );
|
||||
} );
|
||||
|
||||
$collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
|
||||
|
|
@ -304,12 +304,39 @@
|
|||
'<div class="mw-collapsible">' + loremIpsum + '</div>',
|
||||
{ collapseText: 'Collapse me!', expandText: 'Expand me!' }
|
||||
),
|
||||
$toggleLink = $collapsible.find( '.mw-collapsible-toggle a' );
|
||||
$toggleText = $collapsible.find( '.mw-collapsible-text' );
|
||||
|
||||
assert.equal( $toggleLink.text(), 'Collapse me!', 'options.collapseText is respected' );
|
||||
assert.equal( $toggleText.text(), 'Collapse me!', 'options.collapseText is respected' );
|
||||
|
||||
$collapsible.on( 'afterCollapse.mw-collapsible', function () {
|
||||
assert.equal( $toggleLink.text(), 'Expand me!', 'options.expandText is respected' );
|
||||
assert.equal( $toggleText.text(), 'Expand me!', 'options.expandText is respected' );
|
||||
} );
|
||||
|
||||
$collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
|
||||
} );
|
||||
|
||||
QUnit.test( 'predefined toggle button and text (.mw-collapsible-toggle/.mw-collapsible-text)', function ( assert ) {
|
||||
var $collapsible = prepareCollapsible(
|
||||
'<div class="mw-collapsible">' +
|
||||
'<div class="mw-collapsible-toggle">' +
|
||||
'<span>[</span><span class="mw-collapsible-text">Toggle</span><span>]</span>' +
|
||||
'</div>' +
|
||||
'<div class="mw-collapsible-content">' + loremIpsum + '</div>' +
|
||||
'</div>',
|
||||
{ collapseText: 'Hide', expandText: 'Show' }
|
||||
),
|
||||
$toggleText = $collapsible.find( '.mw-collapsible-text' );
|
||||
|
||||
assert.equal( $toggleText.text(), 'Toggle', 'predefined text remains' );
|
||||
|
||||
$collapsible.on( 'afterCollapse.mw-collapsible', function () {
|
||||
assert.equal( $toggleText.text(), 'Show', 'predefined text is toggled' );
|
||||
|
||||
$collapsible.on( 'afterExpand.mw-collapsible', function () {
|
||||
assert.equal( $toggleText.text(), 'Hide', 'predefined text is toggled back' );
|
||||
} );
|
||||
|
||||
$collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
|
||||
} );
|
||||
|
||||
$collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
|
||||
|
|
|
|||
Loading…
Reference in a new issue