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

时间:2015-03-28 05:54:30

标签: javascript firefox-addon bookmarks seamonkey

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

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

SeaMonkey具有与Firefox不同的结构,因此以下示例为     var sidebarPanels = window.document.getElementById('sidebar');
在文档中,对SeaMonkey不起作用。

我可以在Dom Inspector中看到bm-panel.xul窗口,但我无法使用Javascript实现它。

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

如何访问bookmarksPanel页面本身?

2 个答案:

答案 0 :(得分:0)

如果您的问题仅限于找到bookmarksPanel,我不能100%确定。因此,此答案包含有关访问bookmarksPanel,查看DOM,从叠加层或无重启扩展程序访问侧栏以及获取window引用的一般信息。

访问bookmarksPanel

以下内容可为您提供<page id="bookmarksPanel">

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

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

查看DOM

如果您在了解特定元素的DOM结构时遇到问题,我建议您安装DOM Inspectorfor SeaMonkey)(以查看DOM)和Element Inspector (允许您右键单击元素并在该元素上打开DOM Inspector)。

这是在VMware中查看书签边栏的DOM Inspector的示例: DOM Inspector viewing a Bookmark Sidebar in Firefox

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

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

  

从browser.xul脚本访问侧栏
  侧边栏内容始终位于与主浏览器文档分开的文档中(侧边栏实际上是作为XUL浏览器元素实现的)。这意味着您无法直接从browser.xul overlay中引用的脚本访问侧边栏内容。

     

要访问侧边栏的窗口或文档对象,您需要分别使用contentWindow的{​​{1}}或contentDocument属性。例如,下面的代码调用侧边栏上下文中定义的函数:

document.getElementById("sidebar")

根据您当前运行的代码的启动方式(例如UI按钮),您可能需要获取当前浏览器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); }

another answer of mine显着复制,您可以通过以下方式获取:

获取对最新window

的引用

Firefox附加组件通常在未定义全局window对象的范围内运行(如果已定义,则取决于当前运行的代码部分是如何输入的)。即使已定义,也通常不会将其定义为您期望的window(当前选项卡的window)。您可能需要获取最近访问的窗口/选项卡的window对象的引用。

如果存在浏览器窗口(在某些情况下,您可以在没有浏览器窗口的情况下运行,例如在启动时),您可以获得对最新浏览器window的引用,{{1 }和window与:

document

如果您正在运行代码以响应某个事件(例如按钮gBrowser事件),则可以使用以下内容获取当前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对象,或者引用了除您期望之外的其他内容,这是许多人在编写Firefox附加组件时遇到的问题。

注意:如果您希望与multi-process Firefox(电解或e10s)本机兼容,那么获取对当前文档内容的访问权限会更复杂。有一些垫片可以使你的代码继续使用多进程Firefox一段时间,但它们可能最终消失。

参考文献:

  1. nsIWindowMediator
  2. Working with windows in chrome code
  3. SDK:window/utils
  4. SDK:windows
  5. Multiprocess Firefox
  6. Working with multiprocess Firefox
  7. 大部分内容都是从我之前的答案中复制过来的,包括this link

答案 1 :(得分:0)

这可能不是唯一的方式或最好的方式,但这就是我正在做的事情:

  1. 找到侧边栏元素(侧边栏面板)
  2. 在侧边栏的childNodes中搜索属性为src = chrome://communicator/content/bookmarks/bm-panel.xul
  3. 的元素

    必须延迟搜索childNodes,直到加载相关的帧,并且搜索本身是对所有元素的递归迭代。

    以下是最小的剥离代码:

        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