Есть ли способ определить собственные контексты для пункта контекстного меню (расширение Google Chrome) - PullRequest
0 голосов
/ 31 октября 2019

У меня есть простое расширение Chrome, моя цель - навести курсор на любые img, видео или аудио теги, получить контекстное меню с моим элементом расширения, щелкнув правой кнопкой мыши на img, video или audio.

Так чтопроблема в том, что когда некоторые img находятся внутри или позади div, я не могу получить свой пункт контекстного меню, потому что он не соответствует моим контекстам. То же самое иногда случается с видео и аудио. У меня вопрос, есть ли какой-нибудь подход к написанию собственного контекста, а не к использованию в Google "image", "video", "audio".

У меня уже есть иногда работающее расширение, поэтому мне нужно это исправитьпроблема с некоторыми изображениями.

var contextMenuItem = {
    "id": "printData",
    "title": "print",
    "contexts": ["image", "audio", "video"]
};

chrome.contextMenus.removeAll(function() {
    chrome.contextMenus.create(contextMenuItem)
});

chrome.contextMenus.onClicked.addListener(function(mediaData){
    if (mediaData.menuItemId == "printData") {
        console.log(mediaData)
    }
});

Так что я хочу, чтобы мой пункт контекстного меню отображался, когда я размещал любое изображение на странице. Потому что сейчас это работает, может быть, 50% времени. Спасибо

1 Ответ

0 голосов
/ 31 октября 2019

Нет, нет никакого способа добавить пользовательский контекст.

Что вы можете сделать, это зарегистрировать дополнительный элемент меню в "page" контексте с отдельным id и динамически показать / скрыть его с помощьюmousedown прослушиватель событий в скрипте содержимого. Слушатель будет запущен до события contextmenu и уведомит фоновый скрипт, если цель события включает в себя img / media. Фоновый сценарий будет использовать API-интерфейс chrome.contextMenus для переключения пункта меню.

сценарий содержимого :

// true means 'useCapture' mode (the first event phase)
window.addEventListener('mousedown', e => button === 2 && beforeContextMenu(e), true);
window.addEventListener('keydown', e => {
  if (e.key === 'ContextMenu' || 
      e.key === 'F10' && e.shiftKey && !e.altKey && !e.ctrlKey && !e.metaKey) {
    beforeContextMenu(e);
  }
}, true);

function beforeContextMenu(e) {
  const el = !e.target.matches('img, video, audio') &&
             e.target.querySelector('img, video, audio');
  chrome.runtime.sendMessage({
    contextMenu: el ? el.currentSrc || el.src : '',
  });
}

фоновый сценарий :

chrome.runtime.onMessage.addListener((message, sender) => {
  if (message.contextMenu) {
    chrome.contextMenus.create({
      id: 'printData:page',
      title: 'print',
      contexts: ['page'],
    }, ignoreChromeError);
  } else if (message.contextMenu === '') {
    chrome.contextMenus.remove('printData:page', ignoreChromeError);
  }
});

chrome.runtime.onInstalled.addListener(() => {
  chrome.contextMenus.create({
    id: 'printData',
    title: 'print',
    contexts: ['image', 'audio', 'video'],
  }, ignoreChromeError);
});

chrome.contextMenus.onClicked.addListener(e => {
  if (e.menuItemId.startsWith('printData')) {
    console.log(e);
  }
});

function ignoreChromeError() {
  return chrome.runtime.lastError;
}

Однако в этом упрощенном примере элемент меню будет переключаться глобально для всех вкладок. Chrome API не может переключать меню для каждой вкладки, поэтому вам может потребоваться использовать documentUrlPatterns для указания URL-адресов вкладок, но это крайний случай, который, вероятно, не стоит использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...