@@ -92,20 +92,47 @@ function createPopupProBlocker( $ , e ) {
9292 $ ( document ) . on ( 'click' , '.viz-shortcode-display' , function ( ) {
9393 var text = $ ( this ) . text ( ) ;
9494 var el = this ;
95- if ( navigator . clipboard ) {
96- navigator . clipboard . writeText ( text ) ;
97- } else {
95+
96+ // Fallback copy method using a temporary textarea. Returns true on success.
97+ var fallbackCopy = function ( value ) {
9898 var ta = document . createElement ( 'textarea' ) ;
99- ta . value = text ;
99+ ta . value = value ;
100100 document . body . appendChild ( ta ) ;
101101 ta . select ( ) ;
102- document . execCommand ( 'copy' ) ;
102+ var succeeded = false ;
103+ try {
104+ succeeded = document . execCommand ( 'copy' ) ;
105+ } catch ( e ) {
106+ succeeded = false ;
107+ }
103108 document . body . removeChild ( ta ) ;
109+ return succeeded ;
110+ } ;
111+
112+ // Apply temporary "copied" feedback.
113+ var showCopiedFeedback = function ( ) {
114+ $ ( el ) . addClass ( 'viz-shortcode-copied' ) ;
115+ setTimeout ( function ( ) {
116+ $ ( el ) . removeClass ( 'viz-shortcode-copied' ) ;
117+ } , 1200 ) ;
118+ } ;
119+
120+ if ( navigator . clipboard && navigator . clipboard . writeText ) {
121+ navigator . clipboard . writeText ( text ) . then ( function ( ) {
122+ // Clipboard API succeeded.
123+ showCopiedFeedback ( ) ;
124+ } ) . catch ( function ( ) {
125+ // Clipboard API failed; fall back to textarea method.
126+ if ( fallbackCopy ( text ) ) {
127+ showCopiedFeedback ( ) ;
128+ }
129+ } ) ;
130+ } else {
131+ // No Clipboard API; use fallback directly.
132+ if ( fallbackCopy ( text ) ) {
133+ showCopiedFeedback ( ) ;
134+ }
104135 }
105- $ ( el ) . addClass ( 'viz-shortcode-copied' ) ;
106- setTimeout ( function ( ) {
107- $ ( el ) . removeClass ( 'viz-shortcode-copied' ) ;
108- } , 1200 ) ;
109136 } ) ;
110137
111138 $ ( '.visualizer-chart-shortcode' ) . click ( function ( event ) {
0 commit comments