如何在 Firefox WebExtensions 中获取 openerTabId?

2024-02-09

我开发了一个 Chrome 扩展,并尝试使用 Firefox WebExtensions 将其移植到 Firefox。

这是我面临的问题。在我的扩展中,我需要使用chrome.tabs.Tab.openerTabId,Firefox WebExtensions 不支持(请参阅文档 https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs/Tab#Firefox).

我想出了一个解决方法openerTabId我自己,通过查询当前窗口中的活动选项卡:

chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
    // tabs has only one element, which is the one I just opened
});

但这不起作用,因为这个查询的结果是我刚刚打开的选项卡,而不是单击“新选项卡”按钮之前的选项卡.

现在我想在单击“新选项卡”按钮之前查询活动选项卡,但我没有看到任何参数chrome.tabs.query() like lastFocusedTab.

这可以通过以下方式完成吗chrome.tabs.query()?或者还有其他方法可以做到这一点吗?

可能的重复:tab.openerTabId 在 Firefox WebExtension 中未定义 https://stackoverflow.com/questions/41315422/tab-openertabid-undefined-in-firefox-webextension。不幸的是,这个问题没有解决:-(。


自 Firefox 57 起在桌面版 Firefox 中受支持

As of 火狐57 https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/Tab#Browser_compatibility,桌面版Firefox支持tabs.Tab.openerTabId https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs/Tab#Type.

Android 版 Firefox 不支持

安卓版火狐浏览器不支持 https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs/Tab#Browser_compatibility tabs.Tab.openerTabId

如果您希望您的扩展程序与 Android 版 Firefox 兼容,您必须自己跟踪此信息。您可以跟踪用户通过单击链接打开的选项卡的打开选项卡 ID。当 JavaScript 创建新选项卡时,您可以猜测它是由活动选项卡中的 JavaScript 完成的,但您无法知道。您可以通过组合跟踪当前活动的选项卡、侦听要创建的新选项卡以及侦听创建新选项卡的原因是因为用户单击了链接来实现此目的。这可以通过聆听以下内容来完成:

  • tabs.onActivated https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/onActivated跟踪当前活动的选项卡
    这是在之前被解雇的tabs.onCreated,因此您需要保留先前活动选项卡的记录。这对于立即激活新打开的选项卡的情况是必需的。显然,您还需要考虑新选项卡未立即激活的情况。
  • tabs.onCreated https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/onCreated确定何时创建新选项卡。
  • webNavigation.onCommitted https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/webNavigation/onCommitted看看transitionType https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation/transitionType看看新选项卡实际上是从link,而不是当用户从书签等打开新选项卡时恰好成为活动选项卡。

作为参考,这些是当用户单击链接时触发的事件(<a href="http://www.example.com" target="_blank">):

Content event: mousedown  on: <a href="http://www.example.com" target="_blank">  contentMessageUI.js:16:9
Content event: mouseup    on: <a href="http://www.example.com" target="_blank">  contentMessageUI.js:16:9
Content event: click      on: <a href="http://www.example.com" target="_blank">  contentMessageUI.js:16:9
tabs.onActivated                  ->  arg[0]= Object { tabId: 8, windowId: 0 }
tabs.onHighlighted                ->  arg[0]= Object { tabIds: Array[1], windowId: 0 }
tabs.onUpdated                    ->  arg[0]= 8 :: arg[1]= Object { status: "complete" } :: arg[2]= Object { id: 8, index: 2, windowId: 0, selected: true, highlighted: true, active: true, pinned: false, status: "complete", incognito: false, width: 1100, 5 more… }
tabs.onUpdated                    ->  arg[0]= 8 :: arg[1]= Object { status: undefined } :: arg[2]= Object { id: 8, index: 2, windowId: 0, selected: true, highlighted: true, active: true, pinned: false, status: "complete", incognito: false, width: 1100, 5 more… }
tabs.onZoomChange                 ->  arg[0]= Object { tabId: 8, oldZoomFactor: undefined, newZoomFactor: 1, zoomSettings: Object }
tabs.onUpdated                    ->  arg[0]= 8 :: arg[1]= Object { status: "complete", url: "about:blank" } :: arg[2]= Object { id: 8, index: 2, windowId: 0, selected: true, highlighted: true, active: true, pinned: false, status: "complete", incognito: false, width: 1100, 5 more… }
tabs.onUpdated                    ->  arg[0]= 8 :: arg[1]= Object { status: undefined } :: arg[2]= Object { id: 8, index: 2, windowId: 0, selected: true, highlighted: true, active: true, pinned: false, status: "complete", incognito: false, width: 1100, 5 more… }
tabs.onUpdated                    ->  arg[0]= 8 :: arg[1]= Object { status: "loading" } :: arg[2]= Object { id: 8, index: 2, windowId: 0, selected: true, highlighted: true, active: true, pinned: false, status: "loading", incognito: false, width: 1100, 5 more… }
tabs.onCreated                    ->  arg[0]= Object { id: 8, index: 2, windowId: 0, selected: true, highlighted: true, active: true, pinned: false, status: "loading", incognito: false, width: 1100, 5 more… }
webNavigation.onBeforeNavigate    ->  arg[0]= Object { url: "about:blank", timeStamp: 1487869034364, frameId: 0, parentFrameId: -1, tabId: 8 }
webNavigation.onErrorOccurred     ->  arg[0]= Object { url: "about:blank", timeStamp: 1487869034368, frameId: 0, parentFrameId: -1, error: "Error code 2152398850", tabId: 8 }
webNavigation.onCommitted         ->  arg[0]= Object { url: "about:blank", timeStamp: 1487869034377, frameId: 0, parentFrameId: -1, tabId: 8, transitionType: "link", transitionQualifiers: Array[0] }
webNavigation.onBeforeNavigate    ->  arg[0]= Object { url: "http://www.example.com/", timeStamp: 1487869034380, frameId: 0, parentFrameId: -1, tabId: 8 }
webRequest.onBeforeRequest        ->  arg[0]= Object { requestId: "150", url: "http://www.example.com/", originUrl: "http://www.example.com/", method: "GET", type: "main_frame", timeStamp: 1487869034382, frameId: 0, parentFrameId: -1, tabId: 8 }
webRequest.onBeforeSendHeaders    ->  arg[0]= Object { requestId: "150", url: "http://www.example.com/", originUrl: "http://www.example.com/", method: "GET", type: "main_frame", timeStamp: 1487869034384, frameId: 0, parentFrameId: -1, tabId: 8, requestHeaders: Array[6] }
webRequest.onSendHeaders          ->  arg[0]= Object { requestId: "150", url: "http://www.example.com/", originUrl: "http://www.example.com/", method: "GET", type: "main_frame", timeStamp: 1487869034387, frameId: 0, parentFrameId: -1, tabId: 8, requestHeaders: Array[6] }
webRequest.onHeadersReceived      ->  arg[0]= Object { requestId: "150", url: "http://www.example.com/", originUrl: "http://www.example.com/", method: "GET", type: "main_frame", timeStamp: 1487869034416, frameId: 0, parentFrameId: -1, tabId: 8, responseHeaders: Array[11], 2 more… }
webRequest.onResponseStarted      ->  arg[0]= Object { requestId: "150", url: "http://www.example.com/", originUrl: "http://www.example.com/", method: "GET", type: "main_frame", timeStamp: 1487869034420, frameId: 0, parentFrameId: -1, tabId: 8, responseHeaders: Array[11], 2 more… }
webRequest.onCompleted            ->  arg[0]= Object { requestId: "150", url: "http://www.example.com/", originUrl: "http://www.example.com/", method: "GET", type: "main_frame", timeStamp: 1487869034429, frameId: 0, parentFrameId: -1, tabId: 8, responseHeaders: Array[11], 2 more… }
tabs.onUpdated                    ->  arg[0]= 8 :: arg[1]= Object { status: "loading", url: "http://www.example.com/" } :: arg[2]= Object { id: 8, index: 2, windowId: 0, selected: true, highlighted: true, active: true, pinned: false, status: "loading", incognito: false, width: 1100, 5 more… }
webNavigation.onCommitted         ->  arg[0]= Object { url: "http://www.example.com/", timeStamp: 1487869034538, frameId: 0, parentFrameId: -1, tabId: 8, transitionType: "link", transitionQualifiers: Array[0] }
tabs.onUpdated                    ->  arg[0]= 8 :: arg[1]= Object { status: "complete" } :: arg[2]= Object { id: 8, index: 2, windowId: 0, selected: true, highlighted: true, active: true, pinned: false, status: "complete", incognito: false, width: 1100, 5 more… }
webNavigation.onDOMContentLoaded  ->  arg[0]= Object { url: "http://www.example.com/", timeStamp: 1487869034710, frameId: 0, parentFrameId: -1, tabId: 8 }
webNavigation.onCompleted         ->  arg[0]= Object { url: "http://www.example.com/", timeStamp: 1487869034715, frameId: 0, parentFrameId: -1, tabId: 8 }

看来transitionType也将是link当通过 JavaScript 打开选项卡时(假设用户已允许)。以下是打开新选项卡时的事件window.open('http://www.example.com');(在允许来自该域的弹出窗口后,通过在内容页面的 DevTools 控制台中执行该操作进行模拟):

tabs.onActivated                  ->  arg[0]= Object { tabId: 11, windowId: 0 }
tabs.onHighlighted                ->  arg[0]= Object { tabIds: Array[1], windowId: 0 }
tabs.onUpdated                    ->  arg[0]= 11 :: arg[1]= Object { status: "complete" } :: arg[2]= Object { id: 11, index: 2, windowId: 0, selected: true, highlighted: true, active: true, pinned: false, status: "complete", incognito: false, width: 1100, 5 more… }
tabs.onUpdated                    ->  arg[0]= 11 :: arg[1]= Object { status: undefined } :: arg[2]= Object { id: 11, index: 2, windowId: 0, selected: true, highlighted: true, active: true, pinned: false, status: "complete", incognito: false, width: 1100, 5 more… }
tabs.onZoomChange                 ->  arg[0]= Object { tabId: 11, oldZoomFactor: undefined, newZoomFactor: 1, zoomSettings: Object }
tabs.onUpdated                    ->  arg[0]= 11 :: arg[1]= Object { status: "complete", url: "about:blank" } :: arg[2]= Object { id: 11, index: 2, windowId: 0, selected: true, highlighted: true, active: true, pinned: false, status: "complete", incognito: false, width: 1100, 5 more… }
tabs.onUpdated                    ->  arg[0]= 11 :: arg[1]= Object { status: undefined } :: arg[2]= Object { id: 11, index: 2, windowId: 0, selected: true, highlighted: true, active: true, pinned: false, status: "complete", incognito: false, width: 1100, 5 more… }
tabs.onUpdated                    ->  arg[0]= 11 :: arg[1]= Object { status: "loading" } :: arg[2]= Object { id: 11, index: 2, windowId: 0, selected: true, highlighted: true, active: true, pinned: false, status: "loading", incognito: false, width: 1100, 5 more… }
tabs.onCreated                    ->  arg[0]= Object { id: 11, index: 2, windowId: 0, selected: true, highlighted: true, active: true, pinned: false, status: "loading", incognito: false, width: 1100, 5 more… }
webNavigation.onBeforeNavigate    ->  arg[0]= Object { url: "about:blank", timeStamp: 1487871931270, frameId: 0, parentFrameId: -1, tabId: 11 }
webNavigation.onErrorOccurred     ->  arg[0]= Object { url: "about:blank", timeStamp: 1487871931274, frameId: 0, parentFrameId: -1, error: "Error code 2152398850", tabId: 11 }
webNavigation.onCommitted         ->  arg[0]= Object { url: "about:blank", timeStamp: 1487871931289, frameId: 0, parentFrameId: -1, tabId: 11, transitionType: "link", transitionQualifiers: Array[0] }
webNavigation.onBeforeNavigate    ->  arg[0]= Object { url: "http://www.example.com/", timeStamp: 1487871931292, frameId: 0, parentFrameId: -1, tabId: 11 }
webRequest.onBeforeRequest        ->  arg[0]= Object { requestId: "159", url: "http://www.example.com/", originUrl: "http://www.example.com/", method: "GET", type: "main_frame", timeStamp: 1487871931294, frameId: 0, parentFrameId: -1, tabId: 11 }
webRequest.onBeforeSendHeaders    ->  arg[0]= Object { requestId: "159", url: "http://www.example.com/", originUrl: "http://www.example.com/", method: "GET", type: "main_frame", timeStamp: 1487871931297, frameId: 0, parentFrameId: -1, tabId: 11, requestHeaders: Array[6] }
webRequest.onSendHeaders          ->  arg[0]= Object { requestId: "159", url: "http://www.example.com/", originUrl: "http://www.example.com/", method: "GET", type: "main_frame", timeStamp: 1487871931299, frameId: 0, parentFrameId: -1, tabId: 11, requestHeaders: Array[6] }
webRequest.onHeadersReceived      ->  arg[0]= Object { requestId: "159", url: "http://www.example.com/", originUrl: "http://www.example.com/", method: "GET", type: "main_frame", timeStamp: 1487871931312, frameId: 0, parentFrameId: -1, tabId: 11, responseHeaders: Array[11], 2 more… }
webRequest.onResponseStarted      ->  arg[0]= Object { requestId: "159", url: "http://www.example.com/", originUrl: "http://www.example.com/", method: "GET", type: "main_frame", timeStamp: 1487871931317, frameId: 0, parentFrameId: -1, tabId: 11, responseHeaders: Array[11], 2 more… }
webRequest.onCompleted            ->  arg[0]= Object { requestId: "159", url: "http://www.example.com/", originUrl: "http://www.example.com/", method: "GET", type: "main_frame", timeStamp: 1487871931329, frameId: 0, parentFrameId: -1, tabId: 11, responseHeaders: Array[11], 2 more… }
tabs.onUpdated                    ->  arg[0]= 11 :: arg[1]= Object { status: "loading", url: "http://www.example.com/" } :: arg[2]= Object { id: 11, index: 2, windowId: 0, selected: true, highlighted: true, active: true, pinned: false, status: "loading", incognito: false, width: 1100, 5 more… }
history.onVisited                 ->  arg[0]= Object { id: "fGv8w_MX50EI", url: "http://www.example.com/", title: "", lastVisitTime: 1487871931320, visitCount: 4, typedCount: 1 }
webNavigation.onCommitted         ->  arg[0]= Object { url: "http://www.example.com/", timeStamp: 1487871931480, frameId: 0, parentFrameId: -1, tabId: 11, transitionType: "link", transitionQualifiers: Array[0] }
tabs.onUpdated                    ->  arg[0]= 11 :: arg[1]= Object { status: "complete" } :: arg[2]= Object { id: 11, index: 2, windowId: 0, selected: true, highlighted: true, active: true, pinned: false, status: "complete", incognito: false, width: 1100, 5 more… }
webNavigation.onDOMContentLoaded  ->  arg[0]= Object { url: "http://www.example.com/", timeStamp: 1487871931652, frameId: 0, parentFrameId: -1, tabId: 11 }
webNavigation.onCompleted         ->  arg[0]= Object { url: "http://www.example.com/", timeStamp: 1487871931657, frameId: 0, parentFrameId: -1, tabId: 11 }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Firefox WebExtensions 中获取 openerTabId? 的相关文章

  • 将 HTML 表格结构复制到剪贴板

    我只是在寻找这方面的建议 我一直在互联网上寻找可能的解决方案 了解如何将 HTML 表格结构及其文本复制到剪贴板 但到目前为止还没有那么幸运 我现在拥有的是一个包含数据的简单表格 用户需要在复制 粘贴时使用 Outlook 将其复制到电子邮
  • AngularJS 仅在解析时返回两个 http get 请求

    我有一个 Angular 应用程序 在控制器中我需要调用一个发出两个 http get 请求的函数 并且我需要这个函数在解析这些值时返回这些值 我无法在 routeProvider 中解析它们 因为此函数需要在同一控制器中获取值 我展示了控
  • Canvas drawImage 内联 svg 在 Firefox 上不起作用

    这是一个例子 它采用 svg 并将其转换为画布 http jsfiddle net Na6X5 944 http jsfiddle net Na6X5 944 var can document getElementById canvas1
  • Firefox 中的 jQuery 表单提交

    请帮我解决一个问题 我有这个代码 用于通过锚点提交表单
  • 将浮点值转换为灰度十六进制颜色值

    这个问题又快又简单 我有一个二维浮点数组 0 0000000 到 1 0000000 我想将这些数字转换为颜色值 000000 到 ffffff 请注意 我所说的只是灰度值 0 黑色 0 5 中灰色 1 白色 有谁知道如何用 javascr
  • jQuery 插件与小部件

    几个月前 我开始使用 jQuery 插件进行一些实验 我在互联网上找到了一些教程 然后开始整理一些东西 几天前 我需要构建自己的 插件 并回到我的旧项目 当我试图在互联网上找到更多信息时 我偶然发现了这些称为小部件的新 东西 据我了解 我应
  • jQuery Mobile:$(...).listview 不是函数

    我正在尝试在 UL 中动态插入 LI 元素后刷新 jQuery Mobile 中的列表视图 每当我尝试 myUL listview refresh 在控制台上我收到错误 未捕获的类型错误 listview 不是函数 我该如何解决这个问题 确
  • DOM 元素宽度可以是非整数吗?

    我有一个页面 其 div 元素由 JavaScript 对齐 JavaScript 只是检查一组 div 元素来查找最大值偏移宽度 然后设置所有 div 元素 width成为最大偏移宽度 它在大多数浏览器和区域设置中都能完美运行 但在 Ma
  • 等待两个异步函数完成,然后在 Node.js 中继续

    我正在 Node js 中开发一个应用程序 其中调用异步函数两次 并将值分配给全局变量 问题是我想使用这两个调用的结果来做其他事情 但是这个其他事情不会等待结果被分配 这是我的代码 var a var b let x abcd foo x
  • 查找第一个可滚动父级

    我遇到这种情况 需要将元素滚动到视口中 问题是我不知道哪个元素是可滚动的 例如 在纵向中 主体是可滚动的 而在横向中 它是另一个元素 还有更多情况会更改可滚动元素 现在的问题是 给定一个需要滚动到视口中的元素 找到其第一个可滚动父元素的最佳
  • Elasticsearch 前缀匹配消失且未添加 (QueryString)

    结转自Elasticsearch QueryStrings 部分匹配 NOT 查询 https stackoverflow com questions 40100006 elasticsearch querystrings partiall
  • 过滤文件上传仅用于文本文件

    我使用的是 Firefox 版本 14 0 1 我需要过滤上传文件窗口以仅显示 txt files 我的浏览器不仅仅支持文本文件 text plain 我可以通过指定此格式来限制图像文件 image 但我只需要过滤文本文件在文件选择器窗口中
  • 如何在 blob 类型中使用 UTF-8?

    我必须通过 csv 文件导出表 csv 文件数据来自服务器 按 Blob 类型 Blob size 2067 type text csv async exportDocumentsByCsv this commonStore setLoad
  • IE7 真的不支持indexOf javascript 吗? [复制]

    这个问题在这里已经有答案了 可能的重复 数组上的 indexOf 函数在使用 JavaScript 的 IE7 8 中不起作用 https stackoverflow com questions 11544983 indexof funct
  • 在单页应用程序上重用 Google Maps API 实例

    假设我有一个单页应用程序 Angular JS 应用程序 并且我在元素 id 上绘制一个 Google 地图实例googleMap var mapInstance new google maps Map document getElemen
  • 返回不在函数中

    Firebug 报告 返回不在函数中 错误 没有位置 好吧 第 1 行什么都没有 我怎样才能找到这个错误的根源 return not in function Break on this error return 0 javascript r
  • 当来自 Mozilla Firefox 和 MS Edge 上的剪贴板时 Alpha 会变成黑色

    我正在使用代码从这里 https stackoverflow com a 15369753 5875416将剪贴板中的图像粘贴到页面上 它在所有浏览器 Chrome Firefox Edge 和 Opera 中都能正常工作 问题是 当图像是
  • 如何将所有后代节点和链接设置为与 2 级祖先相同的颜色?

    我有一个 d3 js 树 其后代节点接收其 2 级祖先的节点颜色 这在级别 2 到级别 3 之间有效 但在级别 4 及以上级别停止工作 相关代码 var colourScale d3 scale ordinal domain MD Prof
  • 在 JSON 对象中存储和发送原始文件数据

    我正在寻找一种方法来传输任何文件类型的原始文件数据和任何可能的内容 我的意思是文件和文件内容都是用户生成的 在 Backbone 前端中使用 xhr ajax 调用两种方式针对 Django 后端 编辑 也许问题仍然不清楚 如果您在 IDE
  • 网站可以检测您何时将 Selenium 与 chromedriver 结合使用吗?

    我一直在使用 Chromedriver 测试 Selenium 我注意到有些页面可以检测到您正在使用 Selenium 即使根本没有自动化 即使我只是通过 Selenium 使用 Chrome 手动浏览 Xephyr https en wi

随机推荐