验证每个选项卡的上下文菜单项

Validate context menu item for each tab

本文关键字:上下文 菜单项 选项 验证      更新时间:2023-09-26

我正在开发一个简单的Safari扩展,它添加了一个上下文菜单项,当单击该项时,我可以使用当前页面上的数据执行特定任务。在我的injected-scripts.js中,我有一个函数validForContextMenu,它决定是否应该为单击的选项卡显示上下文菜单。除了这个函数之外,我还将以下消息发送到global.html,让它知道选项卡是否应该显示我的上下文菜单项。

safari.self.tab.dispatchMessage("validate", validForContextMenu());

global.html中,我正在执行以下操作来侦听消息,存储injected-scripts.js返回的数据,并执行实际验证:

var contextMenuDisabled = true;
function respondToMessage(theMessageEvent) {
    if (theMessageEvent.name === "validate") {
        contextMenuDisabled = theMessageEvent.message;
    }
}
safari.application.activeBrowserWindow.activeTab.addEventListener("message", respondToMessage, false);
function validateCommand(event) {
    event.target.disabled = contextMenuDisabled;
}
safari.application.addEventListener("validate", validateCommand, false);

除了验证只执行一次,而且在加载扩展时只对最前面的选项卡/页面进行验证之外,这一切都很好。如果该页面对上下文菜单有效,那么所有其他页面也有效,反之亦然。我希望每个Safaris标签都能单独进行验证。

可以这样做吗?在注入的脚本或发送的消息工作的过程中,我是否遗漏了什么?

global.html是单例的,因此所有选项卡只有一个变量contextMenuDisabled。Safari为此任务提供了特殊的API-Safari.self.tab.setContextMenuEventUserInfo.

我在扩展中使用下一个代码。在inject.js:中

document.addEventListener('contextmenu', onContextMenu, false);
function onContextMenu(ev) {
  var UserInfo = {
    pageId: pageId
  };
  var sel = document.getSelection();
  if (sel && !sel.isCollapsed)
    UserInfo.isSel = true;
  safari.self.tab.setContextMenuEventUserInfo(ev, UserInfo);
};

在global.js:中

safari.application.addEventListener('validate', onValidate, false);
function onValidate(ev) {
  switch (ev.command) {
  case 'DownloadSel':
    if (!ev.userInfo || !ev.userInfo.isSel)
      ev.target.disabled = true;
    break;
  };
};