Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
182 views
in Technique[技术] by (71.8m points)

javascript - 如何在Firefox中使用XUL创建底端面板?(How to create a bottom-docked panel with XUL in Firefox?)

For my addon, I would like to create a bottom-docked "panel" that will display information.(对于我的插件,我想创建一个显示信息的底端“面板”。)

An example of something like this would be Firefox's own Web Console panel that can be toggled under Web Developer Tools.(Firefox的Web控制台面板就是此类示例,可以在Web Developer Tools下进行切换。) I tried to dig through the code, but couldn't figure out how this was implemented.(我试图深入研究代码,但无法弄清楚它是如何实现的。) Could someone give me aa basic explanation of how to create this with XUL, or point me in the right direction?(有人可以给我一个基本的解释,说明如何使用XUL进行创建,或者为我指明正确的方向吗?)   ask by user2089518 translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The Web Console is not a sidebar .(Web控制台不是侧边栏 。)

In Fireox there is only one sidebar, it can be on the left or right of the browser content.(在Fireox中,只有一个侧边栏,它可以位于浏览器内容的左侧或右侧。) The sidebar is a constant part of the UI, even if you change tabs.(即使更改选项卡,侧边栏也是UI的恒定部分。) It is generally used for content, History, Bookmarks, or other such information that does not change depending on the tab you are viewing.(它通常用于内容,历史记录,书签或其他此类信息,这些信息不会随所查看的选项卡而改变。) For investigating stuff like this, I would suggest the DOM Inspector add-on, if you do not already have it installed.(为了调查此类内容,如果您尚未安装DOM Inspector插件,则建议使用它。) The Web Console is contained in an <iframe> within the <tabbrowser> under the tab in which it is located.(Web控制台包含在<tabbrowser>在的选项卡下的<tabbrowser>中的<iframe>中。) The XUL for the iframe is: <iframe xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" class="devtools-toolbox-bottom-iframe" height="436" tooltip="aHTMLTooltip" src="chrome://browser/content/devtools/framework/toolbox.xul"/>(iframe的XUL是: <iframe xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" class="devtools-toolbox-bottom-iframe" height="436" tooltip="aHTMLTooltip" src="chrome://browser/content/devtools/framework/toolbox.xul"/>) First a <splitter> then the <iframe> are inserted after the <hbox class="browserSidebarContainer"> for the tab in which it is contained.(首先将<splitter>然后将<iframe>插入其中包含标签的<hbox class="browserSidebarContainer"> 。) The web console is opened by a call to gDevToolsBrowser.selectToolCommand(gBrowser, "webconsole");(通过调用gDevToolsBrowser.selectToolCommand(gBrowser, "webconsole");打开Web控制台gDevToolsBrowser.selectToolCommand(gBrowser, "webconsole");) gDevToolsBrowser is defined in chrome://browser/content/browser.js from the contents of resource:///modules/devtools/gDevTools.jsm(gDevToolsBrowserchrome://browser/content/browser.jsresource:///modules/devtools/gDevTools.jsm的内容resource:///modules/devtools/gDevTools.jsm) They are actually created in the function SH_create within resource:///modules/devtools/framework/toolbox-hosts.js(它们在功能实际创建SH_createresource:///modules/devtools/framework/toolbox-hosts.js) All of these chrome:// and resource:/// URLs should work from within Firefox.(所有这些chrome://resource:///网址都应在Firefox中运行。) Firefox installs have a large number of files packed in three files cales omni.ja .(在Firefox安装中,大量文件打包在三个文件中,即omn??i.ja。) The files are located in <install directory>/omni.ja , <install directory>/browser/omni.ja , and <install directory>/webart/omni.ja .(这些文件位于<安装目录> /omni.ja<安装目录> /browser/omni.ja<安装目录> /webart/omni.ja中 。) The omni.ja files are just zip format files with the extension renamed.(omn??i.ja文件只是扩展名为zip的文件。) In order to have easy access to these files I routinely unpack them into directories (outside of the Firefox install directory tree).(为了方便地访问这些文件,我通常将它们解压缩到目录中(在Firefox安装目录树的外部)。) I find that this makes it easier to do searches and manipulate the files when I desire to figure out how something was done.(我发现当我想弄清楚如何做时,这使搜索和操作文件变得更加容易。) If you were just looking for code that will create a box like is used for the web console, the complexity depends on the context in which you are operating.(如果您只是在寻找将创建用于Web控制台的框的代码,那么复杂性取决于您所操作的上下文。) The following should work from almost anywhere:(以下内容几乎可以在任何地方工作:) /** * Creates an <iframe> based panel within the current tab, * or opens a window, for use as an user interface box. * If it is not a window, it is associated with the current * browser tab. * @param location * Placement of the panel [right|left|top|bottom|window] * The default location is "right". * @param size * Width if on left or right. Height if top or bottom. * Both width and height if location="window" unless * features is a string. * Default is 400. * @param id * The ID to assign to the iframe. Default is * "makyen-interface-panel" * The <splitter> will be assigned the * ID = id + "-splitter" * @param chromeUrl * This is the chrome:// URL to use for the contents * of the iframe or the window. * the default is: * "chrome://browser/content/devtools/framework/toolbox.xul" * @param features * The features string for the window. See: * https://developer.mozilla.org/en-US/docs/Web/API/Window.open * returns [splitterEl, iframeEl] * The elements for the <splitter> and <iframe> * * Copyright 2014 by Makyen. * Released under the MPL 2.0. http://mozilla.org/MPL/2.0/. **/ function createInterfacePanelIframe(location,size,id,chromeUrl,features) { //defaults size = ( (typeof size !== "number") || size<1) ? 400 : size; id = typeof id !== "string" ? "makyen-interface-panel" : id; chromeUrl = typeof chromeUrl !== "string" ? "chrome://browser/content/devtools/framework/toolbox.xul" : chromeUrl; //Create some common variables if they do not exist. // This should work from any Firefox context. // Depending on the context in which the function is being run, // this could be simplified. if (typeof window === "undefined") { //If there is no window defined, get the most recent. 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; } //Get the current tab & notification box (container for tab UI). let tab = gBrowser.selectedTab; let browserForTab = gBrowser.getBrowserForTab( tab ); let notificationBox = gBrowser.getNotificationBox( browserForTab ); let ownerDocument = gBrowser.ownerDocument; //Create the <iframe> use //ownerDocument for the XUL namespace. let iframeEl = ownerDocument.createElement("iframe"); iframeEl.id = id; iframeEl.setAttribute("src",chromeUrl); iframeEl.setAttribute("height", size.toString()); iframeEl.setAttribute("width", size.toString()); //Call createInterfacePanel, pass the size if it is to be a window. let splitterEl; if(location == "window" ) { splitterEl = createInterfacePanel(location, size, size ,id + "-splitter", chromeUrl, features); return [splitterEl, null]; } else { splitterEl = createInterfacePanel(location, iframeEl, iframeEl ,id + "-splitter", chromeUrl, features); } return [splitterEl, iframeEl]; } /** * Creates a panel within the current tab, or opens a window, for use as a * user interface box. If not a window, it is associated with the current * browser tab. * @param location * Placement of the panel [right|left|top|bottom|window] * The default location is "right". * @param objectEl * The element of an XUL object that will be inserted into * the DOM such that it is within the current tab. * Some examples of possible objects are <iframe>, * <browser>, <box>, <hbox>, <vbox>, etc. * If the location="window" and features is not a string * and this is a number then it is used as the width of the * window. * If features is a string, it is assumed the width is * set in that, or elsewhere (e.g. in the XUL). * @param sizeEl * The element that contains attributes of "width" and * "height". If location=="left"|"right" then the * "height" attribute is removed prior to the objectEl * being inserted into the DOM. * A spearate reference for the size element in case the * objectEl is a documentFragment containing multiple elements. * However, normal usage is for objectEl === sizeEl when * location != "window". * When location == "window" and features is not a string, * and sizeEl is a number then it is used as the height * of the window. * If features is a string, it is assumed the height is * set in that, or elsewhere (e.g. in the XUL). * @param id * The ID to assign to the <splitter>. The default is: * "makyen-interface-panel-splitter". * @param chromeUrl * This is the chrome:// URL to use for the contents * of the window. * the default is: * "chrome://browser/content/devtools/framework/toolbox.xul" * @param features * The features string for the window. See: * https://developer.mozilla.org/en-US/docs/Web/API/Window.open * returns * if location != "window": * splitterEl, The element for the <splitter>. * if location == "window": * The windowObjectReference returned by window.open(). * * Copyright 2014 by Makyen. * Released under the MPL 2.0. http://mozilla.org/MPL/2.0/. **/ function createInterfacePanel(location,objectEl,sizeEl,id,chromeUrl,features) { //Set location default: location = typeof location !== "string" ? "right" : location; if(location == "window") { if(typeof features !== "string") { let width = ""; let height = ""; if(typeof objectEl == "number") { width = "width=" + objectEl.toString() + ","; } if(typeof sizeEl == "number") { height = "height=" + sizeEl.toString() + ","; } features = width + height + "menubar=no,toolbar=no,location=no,personalbar=no" + ",status=no,chrome=yes,resizable,centerscreen"; } } id = typeof id !== "string" ? "makyen-interface-panel-splitt

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...