2015-08-17 17:00:26 -07:00
/ * *
* @ file
* Dropbutton feature .
* /
( function ( $ , Drupal ) {
2015-10-21 21:44:50 -07:00
'use strict' ;
2015-08-17 17:00:26 -07:00
/ * *
* Process elements with the . dropbutton class on page load .
*
* @ type { Drupal ~ behavior }
* /
Drupal . behaviors . dropButton = {
attach : function ( context , settings ) {
var $dropbuttons = $ ( context ) . find ( '.dropbutton-wrapper' ) . once ( 'dropbutton' ) ;
if ( $dropbuttons . length ) {
// Adds the delegated handler that will toggle dropdowns on click.
var $body = $ ( 'body' ) . once ( 'dropbutton-click' ) ;
if ( $body . length ) {
$body . on ( 'click' , '.dropbutton-toggle' , dropbuttonClickHandler ) ;
}
// Initialize all buttons.
var il = $dropbuttons . length ;
for ( var i = 0 ; i < il ; i ++ ) {
DropButton . dropbuttons . push ( new DropButton ( $dropbuttons [ i ] , settings . dropbutton ) ) ;
}
}
}
} ;
/ * *
* Delegated callback for opening and closing dropbutton secondary actions .
*
* @ function Drupal . DropButton ~ dropbuttonClickHandler
*
* @ param { jQuery . Event } e
* /
function dropbuttonClickHandler ( e ) {
e . preventDefault ( ) ;
$ ( e . target ) . closest ( '.dropbutton-wrapper' ) . toggleClass ( 'open' ) ;
}
/ * *
* A DropButton presents an HTML list as a button with a primary action .
*
* All secondary actions beyond the first in the list are presented in a
* dropdown list accessible through a toggle arrow associated with the button .
*
* @ constructor Drupal . DropButton
*
* @ param { HTMLElement } dropbutton
* A DOM element .
* @ param { object } settings
* A list of options including :
* @ param { string } settings . title
* The text inside the toggle link element . This text is hidden
* from visual UAs .
* /
function DropButton ( dropbutton , settings ) {
// Merge defaults with settings.
2015-09-04 13:20:09 -07:00
var options = $ . extend ( { title : Drupal . t ( 'List additional actions' ) } , settings ) ;
2015-08-17 17:00:26 -07:00
var $dropbutton = $ ( dropbutton ) ;
/ * *
* @ type { jQuery }
* /
this . $dropbutton = $dropbutton ;
/ * *
* @ type { jQuery }
* /
this . $list = $dropbutton . find ( '.dropbutton' ) ;
/ * *
* Find actions and mark them .
*
* @ type { jQuery }
* /
this . $actions = this . $list . find ( 'li' ) . addClass ( 'dropbutton-action' ) ;
// Add the special dropdown only if there are hidden actions.
if ( this . $actions . length > 1 ) {
// Identify the first element of the collection.
var $primary = this . $actions . slice ( 0 , 1 ) ;
// Identify the secondary actions.
var $secondary = this . $actions . slice ( 1 ) ;
$secondary . addClass ( 'secondary-action' ) ;
// Add toggle link.
$primary . after ( Drupal . theme ( 'dropbuttonToggle' , options ) ) ;
// Bind mouse events.
this . $dropbutton
. addClass ( 'dropbutton-multiple' )
. on ( {
/ * *
* Adds a timeout to close the dropdown on mouseleave .
*
* @ ignore
* /
'mouseleave.dropbutton' : $ . proxy ( this . hoverOut , this ) ,
/ * *
* Clears timeout when mouseout of the dropdown .
*
* @ ignore
* /
'mouseenter.dropbutton' : $ . proxy ( this . hoverIn , this ) ,
/ * *
* Similar to mouseleave / mouseenter , but for keyboard navigation .
*
* @ ignore
* /
'focusout.dropbutton' : $ . proxy ( this . focusOut , this ) ,
/ * *
* @ ignore
* /
'focusin.dropbutton' : $ . proxy ( this . focusIn , this )
} ) ;
}
else {
this . $dropbutton . addClass ( 'dropbutton-single' ) ;
}
}
/ * *
* Extend the DropButton constructor .
* /
$ . extend ( DropButton , /** @lends Drupal.DropButton */ {
/ * *
* Store all processed DropButtons .
*
* @ type { Array . < Drupal . DropButton > }
* /
dropbuttons : [ ]
} ) ;
/ * *
* Extend the DropButton prototype .
* /
$ . extend ( DropButton . prototype , /** @lends Drupal.DropButton# */ {
/ * *
* Toggle the dropbutton open and closed .
*
* @ param { bool } [ show ]
* Force the dropbutton to open by passing true or to close by
* passing false .
* /
toggle : function ( show ) {
var isBool = typeof show === 'boolean' ;
show = isBool ? show : ! this . $dropbutton . hasClass ( 'open' ) ;
this . $dropbutton . toggleClass ( 'open' , show ) ;
} ,
/ * *
* @ method
* /
hoverIn : function ( ) {
// Clear any previous timer we were using.
if ( this . timerID ) {
window . clearTimeout ( this . timerID ) ;
}
} ,
/ * *
* @ method
* /
hoverOut : function ( ) {
// Wait half a second before closing.
this . timerID = window . setTimeout ( $ . proxy ( this , 'close' ) , 500 ) ;
} ,
/ * *
* @ method
* /
open : function ( ) {
this . toggle ( true ) ;
} ,
/ * *
* @ method
* /
close : function ( ) {
this . toggle ( false ) ;
} ,
/ * *
* @ param { jQuery . Event } e
* /
focusOut : function ( e ) {
this . hoverOut . call ( this , e ) ;
} ,
/ * *
* @ param { jQuery . Event } e
* /
focusIn : function ( e ) {
this . hoverIn . call ( this , e ) ;
}
} ) ;
$ . extend ( Drupal . theme , /** @lends Drupal.theme */ {
/ * *
* A toggle is an interactive element often bound to a click handler .
*
* @ param { object } options
* @ param { string } [ options . title ]
* The HTML anchor title attribute and text for the inner span element .
*
* @ return { string }
* A string representing a DOM fragment .
* /
dropbuttonToggle : function ( options ) {
return '<li class="dropbutton-toggle"><button type="button"><span class="dropbutton-arrow"><span class="visually-hidden">' + options . title + '</span></span></button></li>' ;
}
} ) ;
// Expose constructor in the public space.
Drupal . DropButton = DropButton ;
} ) ( jQuery , Drupal ) ;