diff --git a/index.jsx b/index.jsx index 692f0e2..2083dd9 100644 --- a/index.jsx +++ b/index.jsx @@ -1,4 +1,4 @@ -import React, { useCallback } from 'react'; +import React, { useCallback, useState } from 'react'; import ReactDOM from 'react-dom'; const MDN_BASE = `https://developer.mozilla.org/en-US/docs/Web/API`; @@ -26,6 +26,64 @@ const MDN_URLS = { } }; +const TEXT_COPY_MIME_OPTIONS = [ + { value: 'text/plain', label: 'Plain text' }, + { value: 'text/html', label: 'HTML' } +]; + +function CopyAsMime({ text }) { + const [mimeType, setMimeType] = useState('text/plain'); + + const writeAsMime = useCallback(async () => { + if (!navigator.clipboard) { + return; + } + + if (navigator.clipboard.write && window.ClipboardItem) { + try { + const items = { + 'text/plain': new Blob([text], { + type: 'text/plain' + }) + }; + + if (mimeType !== 'text/plain') { + items[mimeType] = new Blob([text], { + type: mimeType + }); + } + + await navigator.clipboard.write([new ClipboardItem(items)]); + } catch (error) { + console.warn( + 'ClipboardItem write failed, falling back to writeText', + error + ); + } + } else if (navigator.clipboard.writeText) { + await navigator.clipboard.writeText(text); + } + }, [mimeType, text]); + + return ( +
+ + +
+ ); +} + async function extractData(data) { if (!data) { return undefined; @@ -230,22 +288,13 @@ function ClipboardInspector(props) { navigator.clipboard && navigator.clipboard .writeText && ( -
- -
+ )} -
+													
 														
 															{typeof obj.data ===
 															'object'
@@ -326,7 +375,7 @@ function ClipboardInspector(props) {
 														
 															{item.kind ===
 															'string' ? (
-																
+																
 																	
 																		{item.as_string_or_file || (
 																			
diff --git a/style.css b/style.css
index bbe434d..5311a93 100644
--- a/style.css
+++ b/style.css
@@ -178,8 +178,42 @@ h1 + p {
 	margin: -0.5em 0;
 }
 
-.cb-copy {
-	padding: 0.5em 0.5em 0.5em 0;
+.cb-copy-as-dropdown {
+	margin-top: 0.75em;
+	display: inline-flex;
+	align-items: stretch;
+	border: 0.1em solid;
+	background: #f3f3f3;
+	box-shadow: 0.1em 0.1em currentColor;
+}
+
+.cb-copy-as-dropdown button {
+	appearance: none;
+	border: none;
+	background: transparent;
+	padding: 0.5em 0.75em;
+	font: inherit;
+	cursor: pointer;
+}
+
+.cb-copy-as-dropdown select {
+	border: none;
+	background: #fff;
+	padding: 0.5em 0.6em;
+	font: inherit;
+	color: inherit;
+	outline: none;
+	width: 7em;
+}
+
+.cb-copy-as-dropdown button:hover,
+.cb-copy-as-dropdown select:hover {
+	background: #fafafa;
+}
+
+.cb-copy-as-dropdown button:focus,
+.cb-copy-as-dropdown select:focus {
+	outline: 2px solid #006be4;
 }
 
 @media (max-width: 60ch) {