11// (C) 2023 GoodData Corporation
22
33( function ( $ ) {
4- $ ( document ) . ready ( function ( ) {
5- // Set initial ARIA attributes and variables
6- var $codeBlock = $ ( '.code-toolbar' ) ;
7- var $codeBlockToolBar = $ ( '.toolbar' ) ;
8- var $codeBlockContent = $ ( 'pre' ) ;
9- var $accordionOptions = $ ( '.accordion-options' ) ;
10- var $defaultThreshold = 200 ;
11-
12- $codeBlock . attr ( 'aria-expanded' , 'false' ) ;
13-
14- // Find all copy buttons
15- $ ( '.copy-to-clipboard-button' ) . each ( function ( ) {
16- var button = $ ( this ) ;
17-
18- // Add ARIA attributes for better accessibility
19- button . attr ( 'aria-label' , 'Copy code to clipboard' ) ;
20- } ) ;
21-
22- // Expand buttons and expand code block options
23- $codeBlockToolBar . each ( function ( ) {
24- var nearestCodeBlock = $ ( this ) . closest ( $codeBlock ) ;
25- var nearestCodeBlockContent = nearestCodeBlock . find ( $codeBlockContent ) ;
26- var nearestAccordionOptions = nearestCodeBlock . closest ( $accordionOptions ) ;
27- var threshold = nearestAccordionOptions . data ( 'threshold' ) ? nearestAccordionOptions . data ( 'threshold' ) : $defaultThreshold ;
28-
29- var expandButton = $ ( '<button class="expand-button">Expand</button>' ) ;
30- if ( nearestCodeBlockContent . outerHeight ( true ) > threshold && ! nearestAccordionOptions . hasClass ( 'accordion-options--not-collapsible' ) ) {
31- $ ( this ) . prepend ( expandButton ) ;
32- nearestCodeBlock . css ( 'max-height' , threshold + 'px' ) ;
33- nearestCodeBlock . addClass ( 'overflowing' ) ;
34- expandButton . attr ( 'aria-label' , 'Expand code block' ) ;
35- expandButton . wrap ( '<div class="toolbar-item"></div>' ) ;
36- }
37- } ) ;
38-
39- var $expandButton = $ ( '.expand-button' ) ;
40-
41- $expandButton . on ( 'click' , function ( ) {
42- var nearestCodeBlock = $ ( this ) . closest ( $codeBlock ) ;
43- var nearestCodeBlockContent = $ ( this ) . closest ( $codeBlock ) . find ( $codeBlockContent ) ;
44- var nearestAccordionOptions = nearestCodeBlock . closest ( $accordionOptions ) ;
45- var threshold = nearestAccordionOptions . data ( 'threshold' ) ? nearestAccordionOptions . data ( 'threshold' ) : $defaultThreshold ;
46-
47- // Toggle expanded state
48- nearestCodeBlock . toggleClass ( 'expanded' ) ;
49- nearestCodeBlock . attr ( 'aria-expanded' , nearestCodeBlock . hasClass ( 'expanded' ) ) ;
50- $ ( this ) . attr ( 'aria-expanded' , nearestCodeBlock . hasClass ( 'expanded' ) ) ;
51- $ ( this ) . attr ( 'aria-label' , nearestCodeBlock . hasClass ( 'expanded' ) ? 'Collapse code block' : 'Expand code block' ) ;
52- $ ( this ) . text ( nearestCodeBlock . hasClass ( 'expanded' ) ? 'Collapse' : 'Expand' ) ;
53- $ ( this ) . toggleClass ( 'expand-button--expanded' ) ;
54-
55- // Adjust max-height based on expanded state
56- if ( nearestCodeBlock . hasClass ( 'expanded' ) ) {
57- nearestCodeBlock . css ( 'max-height' , nearestCodeBlockContent . outerHeight ( true ) + 'px' ) ;
58- } else {
59- nearestCodeBlock . css ( 'max-height' , threshold + 'px' ) ;
60- $ ( 'html, body' ) . animate ( {
61- scrollTop : nearestCodeBlock . offset ( ) . top - 300
62- } , 300 ) ;
63- nearestCodeBlockContent . animate ( {
64- scrollLeft : 0
65- } , 300 ) ;
66- }
67- } ) ;
68-
69- // Add global escape key handler for code blocks
70- $ ( document ) . on ( 'keydown' , function ( e ) {
71- if ( e . key === 'Escape' ) {
72- // Find any focused copy buttons and blur them
73- $ ( '.copy-to-clipboard-button:focus' ) . blur ( ) ;
74- }
75- } ) ;
76-
77- // Accessibility for buttons
78- $codeBlockToolBar . find ( 'button' ) . each ( function ( ) {
79- var button = $ ( this ) ;
80-
81- button . attr ( 'tabindex' , '0' ) ;
82-
83- button . on ( 'keydown' , function ( e ) {
84- // Allow Escape key to dismiss the button
85- if ( e . key === 'Escape' ) {
86- button . blur ( ) ;
87- e . preventDefault ( ) ;
88- }
89-
90- // Allow Enter or Space to activate the button
91- if ( e . key === 'Enter' || e . key === ' ' ) {
92- button . click ( ) ;
93- e . preventDefault ( ) ;
94- }
95- } ) ;
96- } ) ;
97-
98- // Make the toolbar stay visible when tabbing into it
99- $ ( 'div.code-toolbar > .toolbar' ) . each ( function ( ) {
100- var toolbar = $ ( this ) ;
101-
102- toolbar . on ( 'focusin' , function ( ) {
103- toolbar . css ( 'opacity' , '1' ) ;
104- } ) ;
105-
106- toolbar . on ( 'focusout' , function ( e ) {
107- // Only hide if focus moved outside the toolbar
108- if ( ! $ . contains ( toolbar [ 0 ] , e . relatedTarget ) ) {
109- toolbar . css ( 'opacity' , '' ) ;
110- }
111- } ) ;
112- } ) ;
4+ $ ( document ) . ready ( function ( ) {
5+ // Set initial ARIA attributes and variables
6+ var $codeBlock = $ ( ".code-toolbar" ) ;
7+ var $codeBlockToolBar = $ ( ".toolbar" ) ;
8+ var $codeBlockContent = $ ( "pre" ) ;
9+ var $accordionOptions = $ ( ".accordion-options" ) ;
10+ var $defaultThreshold = 200 ;
11+
12+ $codeBlock . attr ( "aria-expanded" , "false" ) ;
13+
14+ // Expand buttons and expand code block options
15+ $codeBlockToolBar . each ( function ( ) {
16+ var nearestCodeBlock = $ ( this ) . closest ( $codeBlock ) ;
17+ var nearestCodeBlockContent = nearestCodeBlock . find ( $codeBlockContent ) ;
18+ var nearestAccordionOptions = nearestCodeBlock . closest ( $accordionOptions ) ;
19+ var threshold = nearestAccordionOptions . data ( "threshold" )
20+ ? nearestAccordionOptions . data ( "threshold" )
21+ : $defaultThreshold ;
22+
23+ var expandButton = $ ( '<button class="expand-button">Expand</button>' ) ;
24+ if (
25+ nearestCodeBlockContent . outerHeight ( true ) > threshold &&
26+ ! nearestAccordionOptions . hasClass ( "accordion-options--not-collapsible" )
27+ ) {
28+ $ ( this ) . prepend ( expandButton ) ;
29+ nearestCodeBlock . css ( "max-height" , threshold + "px" ) ;
30+ nearestCodeBlock . addClass ( "overflowing" ) ;
31+ expandButton . attr ( "aria-label" , "Expand code block" ) ;
32+ expandButton . wrap ( '<div class="toolbar-item"></div>' ) ;
33+ }
34+ } ) ;
35+
36+ var $expandButton = $ ( ".expand-button" ) ;
37+
38+ $expandButton . on ( "click" , function ( ) {
39+ var nearestCodeBlock = $ ( this ) . closest ( $codeBlock ) ;
40+ var nearestCodeBlockContent = $ ( this )
41+ . closest ( $codeBlock )
42+ . find ( $codeBlockContent ) ;
43+ var nearestAccordionOptions = nearestCodeBlock . closest ( $accordionOptions ) ;
44+ var threshold = nearestAccordionOptions . data ( "threshold" )
45+ ? nearestAccordionOptions . data ( "threshold" )
46+ : $defaultThreshold ;
47+
48+ // Toggle expanded state
49+ nearestCodeBlock . toggleClass ( "expanded" ) ;
50+ nearestCodeBlock . attr (
51+ "aria-expanded" ,
52+ nearestCodeBlock . hasClass ( "expanded" ) ,
53+ ) ;
54+ $ ( this ) . attr ( "aria-expanded" , nearestCodeBlock . hasClass ( "expanded" ) ) ;
55+ $ ( this ) . attr (
56+ "aria-label" ,
57+ nearestCodeBlock . hasClass ( "expanded" )
58+ ? "Collapse code block"
59+ : "Expand code block" ,
60+ ) ;
61+ $ ( this ) . text (
62+ nearestCodeBlock . hasClass ( "expanded" ) ? "Collapse" : "Expand" ,
63+ ) ;
64+ $ ( this ) . toggleClass ( "expand-button--expanded" ) ;
65+
66+ // Adjust max-height based on expanded state
67+ if ( nearestCodeBlock . hasClass ( "expanded" ) ) {
68+ nearestCodeBlock . css (
69+ "max-height" ,
70+ nearestCodeBlockContent . outerHeight ( true ) + "px" ,
71+ ) ;
72+ } else {
73+ nearestCodeBlock . css ( "max-height" , threshold + "px" ) ;
74+ $ ( "html, body" ) . animate (
75+ {
76+ scrollTop : nearestCodeBlock . offset ( ) . top - 300 ,
77+ } ,
78+ 300 ,
79+ ) ;
80+ nearestCodeBlockContent . animate (
81+ {
82+ scrollLeft : 0 ,
83+ } ,
84+ 300 ,
85+ ) ;
86+ }
87+ } ) ;
88+
89+ // Add global escape key handler for code blocks
90+ $ ( document ) . on ( "keydown" , function ( e ) {
91+ if ( e . key === "Escape" ) {
92+ // Find any focused copy buttons and blur them
93+ $ ( ".copy-to-clipboard-button:focus" ) . blur ( ) ;
94+ }
95+ } ) ;
96+
97+ // Accessibility for buttons
98+ $codeBlockToolBar . find ( "button" ) . each ( function ( ) {
99+ var button = $ ( this ) ;
100+
101+ button . attr ( "tabindex" , "0" ) ;
102+
103+ button . on ( "keydown" , function ( e ) {
104+ // Allow Escape key to dismiss the button
105+ if ( e . key === "Escape" ) {
106+ button . blur ( ) ;
107+ e . preventDefault ( ) ;
108+ }
109+
110+ // Allow Enter or Space to activate the button
111+ if ( e . key === "Enter" || e . key === " " ) {
112+ button . click ( ) ;
113+ e . preventDefault ( ) ;
114+ }
115+ } ) ;
116+ } ) ;
117+
118+ // Make the toolbar stay visible when tabbing into it
119+ $ ( "div.code-toolbar > .toolbar" ) . each ( function ( ) {
120+ var toolbar = $ ( this ) ;
121+
122+ toolbar . on ( "focusin" , function ( ) {
123+ toolbar . css ( "opacity" , "1" ) ;
124+ } ) ;
125+
126+ toolbar . on ( "focusout" , function ( e ) {
127+ // Only hide if focus moved outside the toolbar
128+ if ( ! $ . contains ( toolbar [ 0 ] , e . relatedTarget ) ) {
129+ toolbar . css ( "opacity" , "" ) ;
130+ }
131+ } ) ;
113132 } ) ;
114- } ) ( jQuery ) ;
133+ } ) ;
134+ } ) ( jQuery ) ;
0 commit comments