如何在 SeaMonkey 中访问侧边栏书签面板页面

How to access sidebar Bookmarks Panel page in SeaMonkey

我正在尝试将我的覆盖加载项转换为无需重新启动。
我无法访问 SeaMonkey 中的书签面板(在边栏上),无法加载我的叠加层 UI.
具体来说,我需要将叠加层加载到 bm-panel.xul,类似于以下内容: myListener.document.loadOverlay("chrome://myBookmarksPanelOverlay.xul");

为此,我需要 bm-panel.xul 的 window,但我只有浏览器的主要 window。

SeaMonkey 与 Firefox 的结构不同,所以下面的例子
var sidebarPanels = window.document.getElementById('sidebar');
在文档中,不适用于 SeaMonkey。

我可以在 Dom Inspector 中看到 bm-panel.xul window,但我无法使用 Javascript。

我只能访问侧边栏面板,但我只能访问这些面板了:
var sidebarPanels = window.document.getElementById('sidebar-panels');

如何访问书签面板页面本身?

我不能 100% 确定您的问题是否真的仅限于找到 bookmarksPanel。因此,此答案包含有关访问 bookmarksPanel、查看 DOM、从覆盖或无重启扩展访问侧边栏以及获取 window 参考的一般信息。

正在访问 bookmarksPanel

以下内容应该能让您参考 <page id="bookmarksPanel">:

var sidebarDocument = document.getElementById("sidebar").contentDocument;
var bookmarksPanelElement = sidebarDocument.getElementById("bookmarksPanel")

请注意,您需要使用 sidebarDocument 中的 getElementById(),而不是不会在边栏中搜索的主要 window.document.getElementById()

正在查看 DOM

如果您在了解特定元素的 DOM 结构时遇到问题,我建议您安装 DOM Inspector (for SeaMonkey) (to view the DOM) and Element Inspector(它允许您通过 shift-right-click 元素并在该元素上打开 DOM 检查器。

这是 DOM 检查器在 Firefox 中查看书签边栏的示例:

从覆盖或无重启扩展访问边栏

引自 MDN:“Sidebar: Accessing the sidebar from a browser.xul script”:

Accessing the sidebar from a browser.xul script
The sidebar content is always in a document separate from the main browser document (the sidebar is actually implemented as a XUL browser element). This means you can't directly access the sidebar content from a script referenced from a browser.xul overlay.

To access your sidebar's window or document objects, you need to use the contentWindow or contentDocument properties of document.getElementById("sidebar") respectively. For example the code below calls a function defined in the sidebar's context:

var sidebarWindow = document.getElementById("sidebar").contentWindow;
// Verify that our sidebar is open at this moment:
if (sidebarWindow.location.href ==
      "chrome://yourextension/content/whatever.xul") {
  // call "yourNotificationFunction" in the sidebar's context:
  sidebarWindow.yourNotificationFunction(anyArguments);
}

根据您当前代码 运行ning 的启动方式(例如 UI 按钮),您可能需要获取当前浏览器 window.

大量复制自,您可以通过以下方式获得:

正在获取对最近 window:

的引用

Firefox 附加组件通常 运行 在未定义全局 window 对象的范围内(是否已定义取决于您的代码部分当前 运行ning 被输入)。即使定义了,也往往没有定义成你期望的window(当前选项卡的window)。您可能需要为最近访问的 window/tab.

获取对 window 对象的引用

如果浏览器 window 存在(在某些情况下,您可能 运行ning 而浏览器 window 不存在,例如在启动时),您可以获得一个引用最新的浏览器 windowdocumentgBrowser

if (window === null || typeof window !== "object") {
    //If you do not already have a window reference, you need to obtain one:
    //  Add/remove a "/" to comment/un-comment the code appropriate for your add-on type.
    /* Add-on SDK:
    var window = require('sdk/window/utils').getMostRecentBrowserWindow();
    //*/
    //* Overlay and bootstrap (from almost any context/scope):
    var window=Components.classes["@mozilla.org/appshell/window-mediator;1"]
                         .getService(Components.interfaces.nsIWindowMediator)
                         .getMostRecentWindow("navigator:browser");        
    //*/
}
if (typeof document === "undefined") {
    //If there is no document defined, get it
    var document = window.content.document;
}
if (typeof gBrowser === "undefined") {
    //If there is no gBrowser defined, get it
    var gBrowser = window.gBrowser;
}

如果您运行正在编写代码以响应事件(例如按钮 command 事件),您可以通过以下方式获取当前 window

var window = event.view

缺少可用的全局 window 对象,或者它引用了您所期望的以外的东西,这是许多人在编写 Firefox 附加组件时遇到的问题。

注意:如果您希望与 multi-process Firefox(Electrolysis,或 e10s)原生兼容,那么访问当前文档的内容会更加复杂。有一些垫片可以让您的代码在多进程 Firefox 中继续工作一段时间,但它们 may/will 最终 消失了。

参考文献:

  1. nsIWindowMediator
  2. Working with windows in chrome code
  3. SDK:window/utils
  4. SDK:windows
  5. Multiprocess Firefox
  6. Working with multiprocess Firefox

大部分内容是从我之前的回答中复制的,包括 this link

这可能不是唯一的方法或最好的方法,但这是我正在做的:

  1. 找到侧边栏元素 (sidebar-panels)
  2. 在侧边栏子节点中搜索具有属性 src=chrome://communicator/content/bookmarks/bm-panel.xul
  3. 的元素

搜索子节点必须延迟到相关帧加载完毕,搜索本身是对所有元素的递归迭代。

以下是最小的剥离代码:

    var sidebarE =  domWindow.document.getElementById('sidebar-panels');
    setTimeout(function() {
        var sbPanelE = searchChildNodes(sidebarE);
    }, 350);

    function searchChildNodes (aElement) {
        var stackNew = [];
        var current;
        var i, lenArr;

        iterate(aElement); 
        function iterate(current) { 
            var childrenE = current.childNodes;
            for (var i = 0, lenArr = childrenE.length; i < lenArr; i++) {
                iterate(childrenE[i]);
                foundE = checkElement(childrenE[i]);
                if (e.nodeType == 1){ // Element node
                    if (e.getAttribute('src') == loc){
                        stackNew.push({ //pass args via object or array
                            element: childrenE[i],
                        });
                        return;
                    }
                }
            }
        }

        for (i=0;i<stackNew.length ;i++ ){
            var itm = stackNew[i].element;
            return itm;
        }
    } // searchChildNodes