从扩展上下文菜单中复制到剪贴板而不使用“scripting”或“content_scripts”?

huangapple go评论55阅读模式
英文:

Copy to the clipboard from extension context menu without using `scripting` or `content_scripts`?

问题

背景: 我想编写一个扩展程序,其中右键单击扩展图标并单击上下文菜单项会将某些内容复制到剪贴板。

但我还想避免在manifest.json中使用scripting权限或注入content_scripts,因为一些企业环境不允许这样做(有充分理由)。

但如果我不使用scriptingcontent_scripts,我怎么从chrome.contextMenus.onClicked处理程序中复制到剪贴板?既不可以使用document.execCommand,也不能使用navigator.clipboard.write在后台脚本中使用(其中documentnavigator.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();
  }
}

huangapple
  • 本文由 发表于 2023年4月10日 22:03:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/75977797.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定