草庐IT

javascript - Firefox 插件面板可以确定何时显示和隐藏吗?

coder 2024-07-26 原文

我正在使用 Tool API将面板添加到 Firefox DevTools。
我可以定义 setup()dispose() 方法来处理初始化和拆卸。

但是我不知道如何确定面板当前是否可见,或者何时更改可见性。这个事件是否暴露在某处?

明确地说,我只想知道我的面板。所以我想知道我的面板何时可见,或者用户何时切换到例如元素选项卡。

最佳答案

dev/panel API当面板的可见性发生变化时,不会公开通知您的方法。但是,您可以绕过 API 并获悉可见性已更改。

当扩展程序在开发人员工具箱中创建的面板的可见性发生变化时,下面的代码将调用函数 panelVisibilityChangedState。根据要求,这只是扩展添加的面板的状态。此附加组件在运行多进程 Firefox Developer Edition 版本 50.0a2 时进行了测试。

此代码基于 MDN repl-panel example available on GitHub .

main.js:

//This code is based on the MDN Dev Tools panel example available at:
//    https://github.com/mdn/repl-panel

//Require the needed SDK modules
const { Panel } = require("dev/panel");
const { Tool } = require("dev/toolbox");
const { Class } = require("sdk/core/heritage");
const self = require("sdk/self");
var myRadio;
var devToolsToolbar;
var devToolsToolboxTabs;
var pickerContainer;
var panelIsVisible=false;

function panelVisibilityChangedState(isVisible){
    //This function may be called slightly before the state change actually occurs.
    panelIsVisible=isVisible;
    console.log('Dev Tools Panel Changed State: visibility is now: ' + isVisible );
}

function devToolsClickHandler(event){
    //The event fires before the value of the 'selected' attribute changes in response to
    //  this click, except when the event fires on the pick element. In that case, the
    //  'selected' attribute  is accurately 'false'.
    let isSelected = myRadio.getAttribute('selected') === 'true';
    let pickElementContains = pickerContainer.contains(event.target);
    if(!devToolsToolboxTabs.contains(event.target) && !pickElementContains){
        //Of the controls not in the devToolsToolboxTabs, only the pickElement changes
        //  the state of this panel being shown. The exception to this is the close
        //  button, but closing is detected via the panel's dispose method.
        return;
    }//else
    let doesContain = myRadio.contains(event.target);
    if((pickElementContains && panelIsVisible)
        || (doesContain && !isSelected) || (!doesContain && isSelected)) {
        panelVisibilityChangedState(doesContain);
    }
}

//Define a REPLPanel class that inherits from dev/panel
const REPLPanel = Class({
  extends: Panel,
  label: "Visi",
  tooltip: "Demo Dev Tool Panel Visibility Notification",
  icon: self.data.url("noIcon.png"),
  url: self.data.url("blank-panel.html"),
  setup: function(options) {
    //Remember the button which was clicked to open this panel (actually a <radio>)
    myRadio = require("sdk/window/utils").getFocusedElement()
    //For convenience and to speed up the event handler, remember three elements.
    //  Obtain these elements using IDs, or unique class when no ID is available.
    //  This should be a bit more stable than using the location in the DOM
    //  relative to myRadio.
    devToolsToolbar = myRadio.ownerDocument.querySelector('.devtools-tabbar');
    //An alternate method of finding the Dev Tools toolbar:
    //devToolsToolbar = myRadio.ownerDocument.getElementById('toolbox-tabs').parentNode;
    //Another alternate method of finding the Dev Tools toolbar:
    //devToolsToolbar = myRadio.parentNode.parentNode;
    devToolsToolboxTabs = devToolsToolbar.querySelector('#toolbox-tabs');
    pickerContainer = devToolsToolbar.querySelector('#toolbox-picker-container');
    devToolsToolbar.addEventListener('click',devToolsClickHandler,false);
  },
  dispose: function() {
    //Dev Tools panel is destroyed. Visibility is, obviously, false
    if(panelIsVisible){
        panelVisibilityChangedState(false);
    }
  },
  onReady: function() {
    //The panel is now visible and ready.  If desired, this call to
    //  panelVisibilityChangedState could be placed in the 'setup' function.
    panelVisibilityChangedState(true);
  }
});
exports.REPLPanel = REPLPanel;

//Create a new tool, initialized with the REPLPanel's constructor
const replTool = new Tool({
  panels: { repl: REPLPanel }
});

data/blank-panel.html:

<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    This is a blank panel
  </body>
</html>

package.json:

{
  "name": "dev-panel-visibility-notification",
  "title": "dev-panel-visibility-notification",
  "id": "dev-panel-visibility-notification@example",
  "description": "Demonstrates calling a function when the visibillity of the add-on's Dev Tools panel changes.",
  "author": "Makyen",
  "license": "MPL 2.0",
  "version": "0.1.0",
  "main": "main.js"
}

关于javascript - Firefox 插件面板可以确定何时显示和隐藏吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39172877/

有关javascript - Firefox 插件面板可以确定何时显示和隐藏吗?的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  3. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  4. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

    查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

  5. ruby-on-rails - 无法使用 Rails 3.2 创建插件? - 2

    我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby​​1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在

  6. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  7. ruby - 即时确定方法的可见性 - 2

    我正在编写一个方法,它将在一个类中定义一个实例方法;类似于attr_accessor:classFoocustom_method(:foo)end我通过将custom_method函数添加到Module模块并使用define_method定义方法来实现它,效果很好。但我无法弄清楚如何考虑类(class)的可见性属性。例如,在下面的类中classFoocustom_method(:foo)privatecustom_method(:bar)end第一个生成的方法(foo)必须是公共(public)的,第二个(bar)必须是私有(private)的。我怎么做?或者,如何找到调用我的cust

  8. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

  9. ruby - 有人可以帮助解释类创建的 post_initialize 回调吗 (Sandi Metz) - 2

    我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法

  10. ruby - 是否可以覆盖 gemfile 进行本地开发? - 2

    我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI

随机推荐