mozilla

XUL 覆盖

这篇翻译不完整。请帮忙从英语翻译这篇文章

XUL 文件与 XUL 覆盖

覆盖(overlays)是 XUL 文件用来描述额外用户界面(UI)的方式。覆盖通常会被用来通过增加用户界面元素以实现更新或增强。但覆盖提供了通用的机制以:

  • 向用户界面中添加元件(如上所述)
  • 覆盖一小段 XUL 文件,而无需提供整个用户界面
  • 重用特别的用户界面

主文档(master document)是由 XUL 文件和覆盖协作产生的。尽管对于哪些内容应当出现在“基本”(base)的 XUL 上,哪些应该出现在覆盖中没有正式的限制,但是覆盖通常来说会定义那些在基本的版本中不存在的用户界面——即添加的组件。当插件(附加组件)或其他应用为浏览器提供了新的用户界面元素时,这些元素应当被定义在覆盖文件中。例如,安装一个媒体插件可能会为菜单元素的界面提供新的图标:

Image of SSP UI in browser

例如 navigatorOverlay.xul 为导航包定义了基本的用户界面。 在文件 navigatorSSPOverlay.xul 或单独的文件 navigator.xul 中,这些新的插件元素应当被定义为一组元素或子树:

<menuitem name="Super Stream Player"/>

<menupopup name="SS Favorites">
 <menuitem name="Wave" src="mavericks.ssp"/>
 <menuitem name="Soccer" src="brazil_soccer.ssp"/>
</menupopup>

<titledbutton id="SSP" crop="right" flex="1"
              value="&SSButton.label;" onclick="FireSSP()"/>

覆盖与 ID 属性

ID属性 相同时,基础(base)和覆盖会进行合并。

因此,当给定如下的基础 XUL 时:

...
<menu id="file-menu">
 <menupopup id="menu_FilePopup">
  <menuitem name="New"/>
  <menuitem name="Open"/>
  <menuitem name="Save"/>
  <menuitem name="Close"/>
 </menupopup>
</menu>
...

并给定如下覆盖:

<?xml version="1.0"?>
<overlay id="singleItemEx"
         xmlns:html="http://www.w3.org/1999/xhtml"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 <menupopup id="menu_FilePopup">
  <menu id="file_menu">
   <menuitem name="Super Stream Player"/>
  </menu>
 </menupopup>
</overlay>

结果将会是:

...
<menu id="file-menu">
 <menupopup id="menu_FilePopup">
  <menuitem name="New"/>
  <menuitem name="Open"/>
  <menuitem name="Save"/>
  <menuitem name="Close"/>
  <menuitem name="Super Stream Player"/> 
 </menupopup>
</menu>
...

如果你在开发一个 Mozilla 的扩展。请注意 ID 和名空间是被所有扩展所共享的。所以您应当考虑使用一个独特的前缀来标记 ID 以避免不可预期的行为发生。您可以使用自己扩展的名称或该名称的缩写。

覆盖的载入

覆盖可以显式地(explicitly)载入或动态地(dynamically)载入。如果您显式地加载了一个覆盖,这就是说您希望每次基本文件被载入时这个覆盖都要被载入。由于覆盖的一个主要的用途是为基本的包提供额外的用户界面或组件,显示载入可能在定义可选用户组件的时候存在问题。

显式载入覆盖

处理指令可以用来显式地向主文档中加载覆盖。在基本文件的 DOCTYPE 声明前插入如下的处理指令可以告诉布局引擎加载指定的 XUL 文件:

<?xul-overlay href="chrome://component/content/componentOverlay.xul"?>

这里的 component 是被覆盖的包的名字,如 chrome://navigator/content/navigatorOverlay.xul

布局引擎加载所有覆盖文件,然后汇总出产生的 XUL 文档,所以可以避免在菜单框,表格和表格的逐点插入的相关的问题。任何数量的覆盖都可以加载到主文档上,覆盖上同样可以加载其他覆盖。由于覆盖是叠加在主文档中的,所以样式表或脚本的作用域没有歧义。覆盖加载的样式表和脚本简单地套用到整个主文档上。

动态载入覆盖

chrome registry 使得 动态加载XUL覆盖 成为可能——或仅当必要时。chrome 注册是一种特殊的 RDF 数据源。这个数据源可以永久保存,或存储,包含已安装了浏览器的组件或额外的软件包的特定于用户的信息。例如注册了上文的例子中的“Super Stream Player”组件,与该组件相关联的叠加会自动加载。当组件不存在时,只有基本的文件会被加载。

运行时载入覆盖

Firefox 1.5 和其他基于 Gecko 1.8 的应用同样还支持通过 domxref("document.loadOverlay()" 函数运行时载入覆盖。

覆盖与皮肤

警告:您应当使用基本文件加载主皮肤( master skins),而不应当在覆盖中加载。

区别于基本文件,覆盖永远不应当被用于为一个包加载主皮肤。例如,navigatorOverlay.xul 文件并不且不应加载为这个包定义了主皮肤的 navigator.css 文件。因为覆盖的目的是在现有皮肤的基础上向包中添加新的用户界面元素,覆盖应该添加的是结构而非新的样式。以不幸的方式通过覆盖破坏性地替换基本文件的主皮肤,并修改包的皮肤的基本外观的。(这句话说的什么?)

注意:主皮肤全局的皮肤是不同的。对于任何包,主皮肤文件是以包本身命名的CSS文件。例如主皮肤文件中的书签包被称为 bookmarks.css,并置于在 skin/default 子目录下。

覆盖属性

除了新的元素和子树,你也可以覆盖现有的元素和属性。在 XUL 中,属性控制皮肤的重要特征——如像图像文件源。如下面的例子,一个覆盖错误地指定了图片的地址,使得基本文件中 HTML image 元素指向 Netscape 的 GIF 图标:

<html:img id="foo" src="netscapeImage.gif"/>

在覆盖中,具有相同的 ID 属性的元素指定一个不同的图像。于是这个图像在整合的过程中被叠加到原始的 Netscape image 元素上:

<html:img id="foo" src="mozillaImage.gif"/>

当基本文件引用了包含上述 HTML image元素的叠加文件时,新的 src 属性值会覆盖原来的值,这样一来 Mozilla 的图标就取代了 Netscape 的图标。

覆盖定位

XUL覆盖还支持节点的定位。您可以在覆盖中为一个节点指定 XULAttr("position") 属性,以示意插入到主文档中的位置。在下面的例子中,最后一个菜单项 Example Four 将位于“新建”菜单项的后面,而不是像其他子节点那样被附加到菜单的末尾。

<overlay id="main-overlay" xmlns:html="http://www.w3.org/1999/xhtml"
         xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 <menu id="file_menu">
  <menuitem name="Example One"/>
  <menuitem name="Example Two"/>
  <menuitem name="Example Three"/>
  <menuitem name="Example Four" position="1"/>
 </menu>
</overlay>

The node with the position attribute orders itself to the top of the menu. The position can also be given for nodes in overlay files that will be ordered in a group of similar items in the base file. For example, if only the last menuitem above had been in an overlay and the other items were defined in the base file, the overlayed menuitem would still appear at the top of the parent menu.(没看懂,谁看懂了翻译一下……)

覆盖中添加额外的脚本

要想当一个覆盖被应用时运行一个脚本,您可以使用 <script> 元素:

<script src="overlay.js"/>

如果您需要设置 JavaScript 的版本,您可以使用 type 属性:

<script type="application/x-javascript;version=1.8" src="overlay.js"/>

使用覆盖重用用户界面

使用覆盖的一大好处是他可以让你复用一组经常出现在用户界面中的元素。覆盖机制不仅允许您向已有的子树中合并元素,而且可以让您将常见的UI元素写入覆盖文件,并在将他们合并到任何需要他们的基本文件中去。在基本文件中使用带 ID 属性的空节点,并在覆盖中定义一棵子树以合并到这个节点上。

例如,在许多对话框中可能都需要的一组确定和取消按钮。与其每次都把这些按钮在用到的对话框中写一遍。基本文件可以引入定义了这些按钮的覆盖文件 dialogOverlay.xul。(事实上可能会更为复杂,基本文件引入了覆盖文件 dialogOverlay.xul ,而这个覆盖文件又引入了平台相关的 XUL 文件 platformDialogOverlay.xul ……当然,他们的原理还是一样的~)

于是任何需要这些按钮的对话框就只要在顶部声明:

<?xul-overlay href="chrome://global/content/dialogOverlay.xul"?>

并在界面的最后写一个空的带有 okCancelButtons 字样的 ID 的 box 。下面这段代码展示了一个顶部有用户定义的元素,并在底部引用了覆盖的确定取消按钮的例子:

<box align="horizontal" id="bx1" flex="100%" style="margin-bottom: 1em; width: 100%;">
 <html:input type="checkbox" id="dialog.newWindow"/>
 <html:label for="dialog.newWindow">&openWin.label;</html:label>
 <spring flex="100%"/>
</box>

<box id="okCancelButtons"/>

要了解更多详细信息,请参阅这里引用的全局组件文件 platformDialogOverlay.xul 中的确定与取消按钮。工具栏、子菜单、框等任何其他要在多出出现的子树,需要时都可以用这种覆盖文件的方式引入以提高代码复用。

参见

文档标签和贡献者

向此页面作出贡献: ziyunfei, Kacha, tsh
最后编辑者: ziyunfei,