我正在尝试将我的叠加插件转换为无重启。
我无法访问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页面本身?
答案 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 Inspector(for SeaMonkey)(以查看DOM)和Element Inspector (允许您右键单击元素并在该元素上打开DOM Inspector)。
这是在VMware中查看书签边栏的DOM Inspector的示例:
从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一段时间,但它们可能最终消失。
参考文献:
nsIWindowMediator
大部分内容都是从我之前的答案中复制过来的,包括this link。
答案 1 :(得分:0)
这可能不是唯一的方式或最好的方式,但这就是我正在做的事情:
必须延迟搜索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