diff --git a/examples/server/public/index.html.gz b/examples/server/public/index.html.gz
index 6a6491557..36f9c9fe9 100644
Binary files a/examples/server/public/index.html.gz and b/examples/server/public/index.html.gz differ
diff --git a/examples/server/webui/src/main.js b/examples/server/webui/src/main.js
index 997ab0ff5..358a40628 100644
--- a/examples/server/webui/src/main.js
+++ b/examples/server/webui/src/main.js
@@ -13,7 +13,7 @@ import hljs from './highlight-config';
import daisyuiThemes from 'daisyui/src/theming/themes';
// ponyfill for missing ReadableStream asyncIterator on Safari
-import { asyncIterator } from "@sec-ant/readable-stream/ponyfill/asyncIterator";
+import { asyncIterator } from '@sec-ant/readable-stream/ponyfill/asyncIterator';
const isDev = import.meta.env.MODE === 'development';
@@ -22,7 +22,22 @@ const isString = (x) => !!x.toLowerCase;
const isBoolean = (x) => x === true || x === false;
const isNumeric = (n) => !isString(n) && !isNaN(n) && !isBoolean(n);
const escapeAttr = (str) => str.replace(/>/g, '>').replace(/"/g, '"');
-const copyStr = (str) => navigator.clipboard.writeText(str);
+const copyStr = (textToCopy) => {
+ // Navigator clipboard api needs a secure context (https)
+ if (navigator.clipboard && window.isSecureContext) {
+ navigator.clipboard.writeText(textToCopy);
+ } else {
+ // Use the 'out of viewport hidden text area' trick
+ const textArea = document.createElement('textarea');
+ textArea.value = textToCopy;
+ // Move textarea out of the viewport so it's not visible
+ textArea.style.position = 'absolute';
+ textArea.style.left = '-999999px';
+ document.body.prepend(textArea);
+ textArea.select();
+ document.execCommand('copy');
+ }
+};
// constants
const BASE_URL = isDev
@@ -130,9 +145,9 @@ const VueMarkdown = defineComponent(
};
window.copyStr = copyStr;
const content = computed(() => md.value.render(props.source));
- return () => h("div", { innerHTML: content.value });
+ return () => h('div', { innerHTML: content.value });
},
- { props: ["source"] }
+ { props: ['source'] }
);
// input field to be used by settings modal