2016-01-15 10:50:10 +00:00
( function ( Modules ) {
"use strict" ;
2016-01-19 09:55:13 +00:00
if ( ! document . queryCommandSupported ( 'copy' )) return ;
2016-01-15 10:50:10 +00:00
Modules . ApiKey = function () {
const states = {
2020-08-19 10:47:11 +01:00
'keyVisible' : ( options ) => `
<span class="api-key__key">
${ options . keyLabel ? '<span class="govuk-visually-hidden">' + options . thing + ': </span>' : '' }${ options . key }
</span>
<span class="api-key__notice govuk-visually-hidden" aria-live="assertive">
${ options . onload ? '' : options . thing + ' returned to page, press button to copy to clipboard' }
</span>
<button class="govuk-button govuk-button--secondary api-key__button--copy">
Copy ${ options . thing } to clipboard ${ options . name ? '<span class="govuk-visually-hidden"> for ' + options . name + '</span>' : '' }
</button>
2016-01-15 10:50:10 +00:00
` ,
2020-08-19 10:47:11 +01:00
'keyCopied' : ( options ) => `
<span class="api-key__notice" aria-live="assertive">
<span class="govuk-visually-hidden"> ${ options . thing } </span>Copied to clipboard<span class="govuk-visually-hidden">, press button to show in page</span>
</span>
<button class="govuk-button govuk-button--secondary api-key__button--show">
Show ${ options . thing }${ options . name ? '<span class="govuk-visually-hidden"> for ' + options . name + '</span>' : '' }
</button>
2016-01-15 10:50:10 +00:00
`
};
2020-09-15 12:53:58 +01:00
this . getRangeFromElement = function ( keyElement ) {
const range = document . createRange ();
2020-10-02 14:30:10 +01:00
const childNodes = Array . prototype . slice . call ( keyElement . childNodes );
2020-09-15 12:53:58 +01:00
let prefixIndex = - 1 ;
2020-10-02 14:30:10 +01:00
childNodes . forEach (( el , idx ) => {
2020-09-15 12:53:58 +01:00
if (( el . nodeType === 1 ) && el . classList . contains ( 'govuk-visually-hidden' )) {
prefixIndex = idx ;
}
});
range . selectNodeContents ( keyElement );
if ( prefixIndex !== - 1 ) { range . setStart ( keyElement , prefixIndex + 1 ); }
return range ;
};
2016-01-15 10:50:10 +00:00
this . copyKey = function ( keyElement , callback ) {
var selection = window . getSelection ? window . getSelection () : document . selection ,
2020-09-15 12:53:58 +01:00
range = this . getRangeFromElement ( keyElement );
2016-01-15 10:50:10 +00:00
selection . removeAllRanges ();
selection . addRange ( range );
document . execCommand ( 'copy' );
selection . removeAllRanges ();
callback ();
};
this . start = function ( component ) {
2016-01-19 09:55:13 +00:00
const $component = $ ( component ),
2020-08-19 10:47:11 +01:00
stateOptions = {
key : $component . data ( 'key' ),
thing : $component . data ( 'thing' )
},
name = $component . data ( 'name' );
// if the name is distinct from the thing:
// - it will be used in the rendering
// - the key won't be identified by a heading so needs its own label
if ( name !== stateOptions . thing ) {
stateOptions . name = name ;
stateOptions . keyLabel = true ;
}
2016-01-15 10:50:10 +00:00
$component
2018-10-30 13:03:44 +00:00
. addClass ( 'api-key' )
. css ( 'min-height' , $component . height ())
2020-08-19 10:47:11 +01:00
. html ( states . keyVisible ( $ . extend ({ 'onload' : true }, stateOptions )))
2016-01-15 10:50:10 +00:00
. on (
2020-02-06 14:47:47 +00:00
'click' , '.api-key__button--copy' , () =>
2016-01-15 10:50:10 +00:00
this . copyKey (
2020-02-06 14:47:47 +00:00
$ ( '.api-key__key' , component )[ 0 ], () =>
2020-08-19 10:47:11 +01:00
$component
. html ( states . keyCopied ( stateOptions ))
. find ( '.govuk-button' ). focus ()
2016-01-15 10:50:10 +00:00
)
2016-01-19 09:55:13 +00:00
)
. on (
2020-02-06 14:47:47 +00:00
'click' , '.api-key__button--show' , () =>
2020-08-19 10:47:11 +01:00
$component
. html ( states . keyVisible ( stateOptions ))
. find ( '.govuk-button' ). focus ()
2016-01-15 10:50:10 +00:00
);
2019-02-01 15:45:38 +00:00
if ( 'stickAtBottomWhenScrolling' in GOVUK ) {
GOVUK . stickAtBottomWhenScrolling . recalculate ();
}
2016-01-15 10:50:10 +00:00
};
};
})( window . GOVUK . Modules );