@@ -13,7 +13,7 @@ import hljs from './highlight-config';
1313import daisyuiThemes from 'daisyui/src/theming/themes' ;
1414
1515// ponyfill for missing ReadableStream asyncIterator on Safari
16- import { asyncIterator } from " @sec-ant/readable-stream/ponyfill/asyncIterator" ;
16+ import { asyncIterator } from ' @sec-ant/readable-stream/ponyfill/asyncIterator' ;
1717
1818const isDev = import . meta. env . MODE === 'development' ;
1919
@@ -22,7 +22,22 @@ const isString = (x) => !!x.toLowerCase;
2222const isBoolean = ( x ) => x === true || x === false ;
2323const isNumeric = ( n ) => ! isString ( n ) && ! isNaN ( n ) && ! isBoolean ( n ) ;
2424const escapeAttr = ( str ) => str . replace ( / > / g, '>' ) . replace ( / " / g, '"' ) ;
25- const copyStr = ( str ) => navigator . clipboard . writeText ( str ) ;
25+ const copyStr = ( textToCopy ) => {
26+ // Navigator clipboard api needs a secure context (https)
27+ if ( navigator . clipboard && window . isSecureContext ) {
28+ navigator . clipboard . writeText ( textToCopy ) ;
29+ } else {
30+ // Use the 'out of viewport hidden text area' trick
31+ const textArea = document . createElement ( 'textarea' ) ;
32+ textArea . value = textToCopy ;
33+ // Move textarea out of the viewport so it's not visible
34+ textArea . style . position = 'absolute' ;
35+ textArea . style . left = '-999999px' ;
36+ document . body . prepend ( textArea ) ;
37+ textArea . select ( ) ;
38+ document . execCommand ( 'copy' ) ;
39+ }
40+ } ;
2641
2742// constants
2843const BASE_URL = isDev
@@ -130,9 +145,9 @@ const VueMarkdown = defineComponent(
130145 } ;
131146 window . copyStr = copyStr ;
132147 const content = computed ( ( ) => md . value . render ( props . source ) ) ;
133- return ( ) => h ( " div" , { innerHTML : content . value } ) ;
148+ return ( ) => h ( ' div' , { innerHTML : content . value } ) ;
134149 } ,
135- { props : [ " source" ] }
150+ { props : [ ' source' ] }
136151) ;
137152
138153// input field to be used by settings modal
0 commit comments