英文:
Copy to the clipboard from extension context menu without using `scripting` or `content_scripts`?
问题
背景: 我想编写一个扩展程序,其中右键单击扩展图标并单击上下文菜单项会将某些内容复制到剪贴板。
但我还想避免在manifest.json中使用scripting
权限或注入content_scripts
,因为一些企业环境不允许这样做(有充分理由)。
但如果我不使用scripting
或content_scripts
,我怎么从chrome.contextMenus.onClicked
处理程序中复制到剪贴板?既不可以使用document.execCommand
,也不能使用navigator.clipboard.write
在后台脚本中使用(其中document
和navigator.clipboard
都未定义),也没有页面可以发送消息给,因为action.default_popup
页面无法从后台脚本中打开,而我不想使用内容注入。
有什么想法?
英文:
Background: I would like to write an extension, where right-clicking on the extension icon and clicking on a context menu item copies something to the clipboard.
But I also want to avoid using the scripting
permission or injecting content_scripts
in the manifest.json
, because some corporate environments don't allow it (for good reason).
But how can I copy to the clipboard from a chrome.contextMenus.onClicked
handler if I don't use scripting
or content_scripts
? Neither document.execCommand
nor navigator.clipboard.write
are available in background scripts (where both document
and navigator.clipboard
are undefined) and there is no page to send a message to, since the action.default_popup
pages cannot be opened from background scripts and I don't want to use content injection.
Any ideas?
答案1
得分: 0
以下是您要翻译的内容:
"The cookbook.offscreen-clipboard-write example is a working full example of using chrome.offscreen. The essense is that offscreen was created for exactly this kind of purpose.
Here is a summary, but do see the two above links for more details:
First you add "offscreen"
to the permissions in manifest.json
.
Then in background.js
:
// This could also be chrome.contextMenus.onClicked.addListener()
chrome.action.onClicked.addListener(async () => {
await chrome.offscreen.createDocument({
url: chrome.runtime.getURL('offscreen.html'),
reasons: [chrome.offscreen.Reason.CLIPBOARD],
justification: 'Need to copy data to the clipboard',
});
chrome.runtime.sendMessage({
type: 'copy-data-to-clipboard',
target: 'offscreen-doc',
data: 'put this string on the clipboard'
});
});
offscreen.html
has:
<!DOCTYPE html>
<textarea id="text"></textarea>
<script src="offscreen.js"></script>
And offscreen.js
:
chrome.runtime.onMessage.addListener(handleMessages);
async function handleMessages(message) {
if (message.target !== 'offscreen-doc') {
return;
}
switch (message.type) {
case 'copy-data-to-clipboard':
handleClipboardWrite(message.data);
break;
default:
console.warn(`Unexpected message type received: '${message.type}'.`);
}
}
const textEl = document.querySelector('#text');
async function handleClipboardWrite(data) {
try {
if typeof data !== 'string') {
throw new TypeError(
`Value provided must be a 'string', got '${typeof data}'.`;
);
}
textEl.value = data;
textEl.select();
document.execCommand('copy');
} finally {
window.close();
}
}
英文:
The cookbook.offscreen-clipboard-write example is a working full example of using chrome.offscreen. The essense is that offscreen was created for exactly this kind of purpose.
Here is a summary, but do see the two above links for more details:
First you add "offscreen"
to the permissions in manifest.json
.
Then in background.js
:
// This could also be chrome.contextMenus.onClicked.addListener()
chrome.action.onClicked.addListener(async () => {
await chrome.offscreen.createDocument({
url: chrome.runtime.getURL('offscreen.html'),
reasons: [chrome.offscreen.Reason.CLIPBOARD],
justification: 'Need to copy data to the clipboard',
});
chrome.runtime.sendMessage({
type: 'copy-data-to-clipboard',
target: 'offscreen-doc',
data: 'put this string on the clipboard'
});
});
offscreen.html
has:
<!DOCTYPE html>
<textarea id="text"></textarea>
<script src="offscreen.js"></script>
And offscreen.js
:
chrome.runtime.onMessage.addListener(handleMessages);
async function handleMessages(message) {
if (message.target !== 'offscreen-doc') {
return;
}
switch (message.type) {
case 'copy-data-to-clipboard':
handleClipboardWrite(message.data);
break;
default:
console.warn(`Unexpected message type received: '${message.type}'.`);
}
}
const textEl = document.querySelector('#text');
async function handleClipboardWrite(data) {
try {
if (typeof data !== 'string') {
throw new TypeError(
`Value provided must be a 'string', got '${typeof data}'.`
);
}
textEl.value = data;
textEl.select();
document.execCommand('copy');
} finally {
window.close();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论