firefox附加组件开发者指南(三)——XUL简介(中)

XUL中可用的窗体部件

根元素

XUL文档使用不同的根元素来实现不同的目的。本节我们将会看到三种典型的根元素:window、page和dialog。
根元素使用windowtype属性作为这种类型的窗口的标识符。例如,Firefox使用navigator:browser作为其浏览器窗口的windowtype,使用Browser:Preference作为其选项窗口的windowtype。使用将会在第四章描述的方法,我们会看到是如何使用这些值来获取窗口的。
一个窗口在屏幕上的大小和位置可以使用width、height、screenX、screenY(单位都是像素)等属性来指定。使用前面描述的persist属性,你可以简单的存储一个窗口的尺寸和位置。Firefox也是使用这一方法来存储其窗口的尺寸和位置的。

常规根元素

window
至今为止在例子中出现的window元素是用来定义一个普通窗口的。这显示了用于Firefox浏览器窗口、书签管理器窗口一起很多其他窗口种类相同的窗口。一般的,你可以使用window元素作为你的根元素。
page
对于侧边栏以及其他在窗口框架内部打开的XUL文档,使用page元素作为根元素。除了与window元素的目的不同之外,其功能与window元素没有任何不同。

用于对话框窗口的根元素

dialog
创建选项对话框、确认对话框等的时候使用dialog元素。这个元素有很多属性,可以简单的显示控件(按钮,等等)这样的窗体小部件以及适应于任何所运行的平台的布局。
例如,windows将OK按钮放在左边而cancel按钮放在右边,而Mac OS X的布局方式却不一样。这就是Firefox本身使用在bookmark属性以及其他对话框中的方式。
对话框中使用的按钮
一个dialog元素会在其底部显示很多按钮,如表1所示,有4种类型的按钮可以显示,你可以将你想要显示的按钮名称作为逗号隔开的列表写在buttons属性之后。
表1:对话框窗口中可以显示的按钮类型

按钮名称

描述

accept

OK按钮

cancel

Cancel按钮

help

Help按钮

disclosure

提示三角或者按钮。这用来方便用户切换显示附加信息

另外,还有两个特殊的按钮,extra1和extra2.这两个按钮的标签使用buttonlabelextra1和buttonlabelextra2属性来进行设置,这些属性的值是任意的字符串。
当由事件处理器使用按钮名ondialog<button name>定义了的按钮中有按钮按下的时候相应的行为就会发生。如果这些事件处理器没有定义,不管点击accept按钮还是cancel按钮都会关闭对话框。清单9中展示了一个简单的对话框例子,图5展示了其输出。
清单9:一个对话框
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="chrome://global/skin/"?>
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="My Dialog" buttons="accept,cancel"
ondialogaccept="saveValues(); window.close();"
ondialogcancel="window.close();">
<checkbox label="My Option"/>
</dialog>

图5:清单9的输出

注意:The functions behind the dialog elements discussed here require "XPConnect privileges," which are discussed in Chapter 4, so this example will only run correctly if it can run as Firefox code itself or installed extension code. Please be aware that if you attempt to open this sample directly in Firefox, it will not run correctly.

菜单

具有层次结构的下拉菜单是经常在应用程序或者网络服务中使用的访问功能的用户接口的一部分。在过去,使用联合HTML和javascript的方式来产生这样的复杂的UI结构,但是在XUL中,仅仅通过使用标签就可以实现了。

创建菜单

清单10展示了如何将menu元素以及其相关的元素进行联合。其输出如图6所示。
清单10:一个菜单的定义

<menubar>
<menu label="Menu 1">
<menupopup>
<menuitem label="Item 1"/>
<menuitem label="Item 2"/>
<menuseparator/>
<menuitem label="Item 3"/>
<menu label="Submenu">
<menupopup>
<menuitem label="Item 4"/>
<menuitem label="Item 5"/>
</menupopup>
</menu>
</menupopup>
</menu>
</menubar>

图6:清单10的输出

菜单中的每个菜单项都是用menuitem标签来进行标记的。使用menuseparator元素向一组菜单项中插入一个分隔符。menu和menuitem元素都有label属性以设置它们的标签。

将menu元素插入到menubar元素中科院创建多个菜单。你可以简单的通过为menu元素插入menupopup来创建菜单的层次。
你甚至可以通过添加class="menuitem-iconic"到一个menuitem元素中并将其src属性设置为一个图像的URI来使菜单显示一个图标。图7展示了这样显示的例子。
图7:带有图标的菜单项

当选择菜单项的时候执行命令

与动态HTML非常相似,事件处理器用来在一个菜单项选中的时候执行命令。在HTML中为对鼠标和键盘输入进行响应,典型的是使用onclick事件处理器来响应鼠标点击,使用onkeypress事件处理器来对键盘输入进行响应。
XUL也可以使用这些事件处理器,但是XUL还提供了oncommand这个特殊的事件处理器来处理那些具有特定含义的行为,如:左键点击的选择(或者系统设置为习惯左手时的右键点击)或者回车键的选择。清单11显示了一个oncommand事件处理器的使用例子。除了menuitem元素之外,oncommand也可以用于按钮或其他输入控件。
清单11:oncommand事件处理器

<menuitem label="Open project page" oncommand="loadURI(this.value)"
value="http://mozilla.org/"/>

由于gecko引擎实现了2级DOM的事件处理器,你可以像清单12一样定义动态的事件侦听器。
清单12:使用动态事件侦听器的添加与删除

var item = document.getElementById('menu-item-custom');
function handleCommandEvent(aEvent) {
alert('OK');
item.removeEventListener('command', handleCommandEvent, false);
item.parentNode.removeChild(item);
}

item.addEventListener('command', handleCommandEvent, false);

特殊菜单项

与HTML中的input元素非常相似,menuitem可以通过设置他们的type属性像单选按钮和复选按钮一样进行操作。
Checkbox
为menuitem元素添加type="checkbox"会在它被选中的时候显示选中标记,并在再次选择的时候显示未选中。带有复选框的菜单项的例子可以参考Firefox的view菜单,有菜单项以显示或者隐藏工具栏和侧边栏。当一个菜单项被选中的时候,会设置属性checked="true".
radiobutton
为多个menuitem元素设置type="radio" 并将他们的name属性设置为相同则选择其中的一个就无法选择其他的了,这与HTML中的单选按钮非常相似。Firefox中view菜单下的Character Encoding子菜单项就是一个例子。选中的单选按钮具有属性selected="true" 。
上下文菜单
属性context是用来显示上下文菜单或者说快捷键菜单的,即,一个定制的菜单会在右键点击某个元素的时候显示。
之前我们将menupopup子元素放在一个menu元素内部;这里,我们在menu元素的外面使用它。menupopup是根元素的一个直接子元素,我们在其他XUL元素中使用其id属性值作为context的值来检索它。当我们右键点击这个XUL元素的时候,就可以通过其id来引用这个menupopup,并在上下文菜单中显示其内容。清单13展示了一个例子。
清单13:上下文菜单

<button label="Send" oncommand="send();" context="button-context"/>
<menupopup id="button-context">
<menuitem label="Send with new tab" oncommand="sendInNewTab();"/>
</menupopup>

按钮
用户可以点击的按钮使用button元素来定义,图8显示了一个带有图标的按钮,可以通过定义一个图像的URI作为其image属性的值来实现。
使用icon属性而不使用image属性一可以显示带有系统标准图标的按钮。
Icon属性的可能值在表2中给出。

图8:一个带有图像的按钮

Icon属性值

icon属性值

accept

close

cancel

print

help

add

open

remove

save

refresh

find

go-forward

clear

go-back

yes

properties

no

select-font

apply

select-color

表2:icon属性的值
工具栏按钮
toolbarbutton元素是用来定义工具栏按钮的元素。典型的这是放在一个定义工具栏的toolbar元素内部的,但是也可以放在其他位置。
这几乎与button元素一样,但是如清单14所示,你可以通过使用type属性来改变toolbarbutton元素的行为。这在图9中的输出可以看出来。
清单14:
<toolbar>
<toolbarbutton label="Checkbox Type" type="checkbox" image="firefox.png"/>
<toolbarbutton label="Menu Type" type="menu" popup="button-popup" image="firefox.png"/>
<toolbarbutton label="Menu Button Type" type="menu-button" popup="button-popup" image="firefox.png"/>
<menupopup id="button-popup">
<menuitem label="Item 1"/>
<menuitem label="Item 2"/>
<menuitem label="Item 3"/>
</menupopup>
</toolbar>

图9:清单14的输出

-复选框类型的工具栏按钮

指定type=”checkbox”的结果是一个在点击之后下陷、再次点击之后弹起的按钮。按钮在其下陷状态具有checked=”true”的属性。这是用作历史和书签按钮的按钮,可以用来定制工具栏。
-菜单类型的工具栏按钮
指定type=”menu”并添加一个menupopup子元素(在firefox3中你也可以使用pannel元素),或者设置popup属性为一个位于其他地方的弹出菜单的引用将会在按钮按下的时候显示一个弹出菜单。这里,button-click不是其输入,而是将command事件在按钮被选中的时候弹出菜单项。这是用在标签栏右边的列出所有标签的按钮类型。
-菜单按钮类型的工具栏按钮
指定type=”menu-button”的结果是一个特殊的结合了正常工具栏按钮和具有type=”menu”类型的按钮特性的按钮,因此点击这个按钮的时候会产生一个command事件。这是后退和前进按钮的类型;

输入控件

XUL包含很多与HTML的form相关元素非常相似的输入控件元素。

标签

label元素用于独立的文本标签,如描述性文字,value属性的值就是将要显示的文本。control属性的值是其他XUL元素的id,有了这个id,点击那个label或者它获得焦点的时候就可以将焦点传递到那个XUL元素。
这也可以用来显示一长段文本。如果你想要插入自动换行的长字符串,可以使用flex属性如清单15所示,这样就会自动的进行扩展。这种情况下不要使用value属性来设置文本,而要将这些文字作为元素的内容。图10显示了这个清单的输出结果。
清单15:label中处理长字符串

<hbox>
<label flex="1">
Proceeding with this action will send your personal information to a server. Are you sure you want to proceed?
</label>
</hbox>

图10:清单15的输出

简洁标签

在label元素和其他XUL元素的label属性之间,XUL还有很多使用标签的元素。一个常用的可以对所有XUL元素设置的属性是crop属性。
通过对具有label属性的元素或者label元素使用crop属性,标签的一部分会在文本宽度大于其父元素的宽度时被省略号(…)代替。被裁掉大部分可以通过设置其属性值为start、center、或者end来控制。
你可以使用CSS的max-width属性来设置一个box的最大宽度。

复选框

图11所示的复选框是使用checkbox元素来标记的,党其处于选中状态时,其checked属性设为true。
清单16:不同状态的复选框

<checkbox label="Checkbox checked" checked="true"/>
<checkbox label="Checkbox unchecked" checked="false"/>

图11:清单16的输出

单选按钮

在HTML中的单选按钮是多个输入元素通过指定他们都具有相同的name属性作为一组。在XUL中,这是结合两个元素radiogroup和radio来表达的。通过插入多个radio元素到一个radiogroup元素的内容中就可以设置排他的选项,当前选择的radio元素将会有selected=”true”的设置。
radio元素可以通过设置其value属性来进行唯一识别。党那个radio元素被选择的时候,其value属性就会复制到radiogroup中,因此你可以简单的获取radiogroup元素的value值来检查选中的单选按钮。
有时候你可能需要将radio元素放在radiogroup元素的外面。通过结合hbox和vbox可以写出与清单17相似的代码,就会出现如图12所示的输出。
清单17:一个单选按钮的复杂布局

<radiogroup orient="vertical">
<hbox>
<radio label="Top Left"/>
<radio label="Top Right"/>
</hbox>
<hbox>
<radio label="Bottom Left"/>
<radio label="Bottom Right"/>
</hbox>
</radiogroup>

图12:清单17的输出

文本框

使用textbox元素来接受文本输入。在HTML中,有两个独立的元素——用於单行文本的input,和用于多行文本的textarea 。但是XUL中这两种功能都是由textbox来处理的,如清单18所示,其输出的结果如图13.
textbox元素使用value属性来设置其默认的内容;用户输入的内容也可以使用value属性来获取。声明maxlength属性为一个正整数值可以设置设置最大的字符数。设置type=”password”将会使得textbox变为一种特殊的密码输入框,其中输入的字符会被隐藏。
每个字符输入到textbox中都会产生一个input事件。如果你使用oninput事件处理器,你就可以实时的实现与用户相应的命令。
清单18:文本框例子

<vbox align="start">
<textbox/>
<textbox multiline="true" rows="5" cols="15"/>
</vbox>

图13:清单18的输出

自动完成

为textbox元素添加type=”autocomplete”可以为这个文本框启用一个自动完成的功能。
注意要实际的使用这个功能,你必须同时为自动完成文本要使用的autocompletesearch属性指定一个搜索目标。如果你想要使用地址栏的历史,可以将这个值设为history;如果你想要使用搜索栏的历史,则可以设为search-history;如果你想要设置为其他表格的输入历史,使用form-history;这个属性可以有一个值,也可以用空格将多个值隔开以接受多个值
同样的,为了能够实际的读取一个历史记录用来进行自动完成,你需要XPConnect权限,这会在第四章中描述。

菜单列表

使用menulist元素来创建一个从下拉列表中做出选择的控件,如清单19所示,这是通过联合menupopup元素来实现的,其产生的结果如图14所示。
点击就会出现下拉列表;党一个项被选择的时候,那一项的label和value属性就会复制到menulist的label和value属性。默认选择的是第一个菜单项,但是任何菜单都可以通过添加selected=”true”来设置为默认选中。
清单19:菜单列表示例

<menulist>
<menupopup>
<menuitem label="Item 1" value="1"/>
<menuitem label="Item 2" value="2"/>
<menuitem label="Item 3" value="3"/>
</menupopup>
</menulist>

图14:清单19的输出

通过添加editable=”true”到menulist中,可以接受任意的文本输入来辅助进行列表选择,就像文本处理器中经常使用的用来选择字体的菜单一样。

特殊元素

嵌入图像

除了直接在javascript代码中写事件处理器之外,XUL还支持使用script元素将脚本嵌入到XUL文档中,就像HTML一样;这样就可以读取外部脚本文件也可以直接将代码放在script元素内容中。
如果你在一个页面中嵌入脚本,你需要将你的代码括在一个CDATA段中,如清单20所示;这样可以避免由读取&加其他字符开头的实体引用时出现错误。
清单20:在XUL代码中嵌入脚本

<script type="application/javascript"><![CDATA[
var nodes = gBrowser.mTabContainer.childNodes;
for (var i = 0; i < nodes.length; i++)
alert(nodes[i].label);
]]></script>

注意:尽管嵌入javascript是可以的,但一般还是推荐将javascript代码写到一个独立的外部文件中。

Browser 和 tabbrowser

XUL允许使用内联帧(frame)。你可以将一个iframe元素的src属性设置为另外一个XUL文件或者网页的URI,就会显示在那里。但是在实际中iframe基本上很少用于XUL中,经常使用的是browser元素。
browser元素是一个更强大的内联帧,具有网页浏览器的所有基本功能。与iframe不同,一个browser元素有前进后退的功能也包含有阻止嵌入在frame内部的脚本访问frame之外的位置的能力。对于构建与外部网页有关的应用程序,browser是一个更加安全和方便的途径。
tabbrowser元素比browser元素能力更加强大,因为它包含了Firefox中标签处理特性的基本内容。要使用它需要XPConnect权限,与自动完成相同。这会在第四章中描述。
打开一个页面
如果你为browser元素的src属性指定一个URI值,就会默认打开这个URI。改变c属性的值,就可以动态的打开不同的网页或者XUL文档。
后退、前进、重新载入等功能都可以通过调用goBack、goForward和reload方法来实现。使用stop方法可以停止加载当前正在加载的页面。
访问限制
使用HTML的frame和iframe元素定义的帧,可以通过子帧用window对象的parent和top属性访问其父帧以及其祖先帧。对于可以打开任意网页的应用程序,这会传递给网页一个脚本来访问XUL文档的帧,也可能会创建危险的可能导致个人信息泄露的页面。
为安全性考虑,你可以通过在browser元素上声明type=”content”来设置访问限制。如果你这样做了,任何打开的网页都会将其视为最顶层的帧。如果你开发的是一个具有打开网页接口的应用程序,我推荐你使用这个声明以限制网页访问父帧。
在某些环境中,你可能会声明type=”content-primary”。一个具有这种声明的browser元素会被认为是与其他XUL文档不同的特殊浏览器,这样窗口对象就可以通过使用window.content属性来访问其网页并进行显示。在Firefox中,被当做其内容区的活动标签就是使用type=”content-primary”声明了的browser元素。

键盘快捷键

要在基于DHTML的接口中实现键盘快捷键(按住修饰键如ctrl或者shift的时候按某个键),你需要一个拦截键盘输入的脚本。
在XUL中,你可以很简单的通过使用key元素来定义键盘快捷键,如清单21所示。
清单21:定义键盘快捷键

<key id="key-save" key="s" modifiers="accel,shift" oncommand="save();"/>
<key id="key-scroll-up" keycode="VK_PAGE_UP" oncommand="advanceFocus(-1);"/>

要让字母、数字、符号或空格键作为触发器,就可以将那个字符声明为key属性的值。你既可以使用大写字母也可以使用小写字母,都会进行同样的处理。
对于那些特殊键作为触发器的可以使用keycode属性,并为其赋予合适的键值作为其值。通常,你可以对任何键使用键值;最常使用的一些键值如表3所示。
表3:典型的键值名称

Key

Keycode name

Return

VK_RETURN

Enter

VK_ENTER

Backspace

VK_BACK_SPACE

Delete

VK_DELETE

Escape

VK_ESCAPE

VK_UP

VK_DOWN

VK_LEFT

VK_RIGHT

使用修饰键
使用modifiers属性,将下面的一个或者多个值用逗号隔开作为modifiers属性的值:"control", "alt", "shift", 以及"meta"这样就可以限制键盘快捷键只在这些修饰键同时按下的时候才起作用。Windows和linux系统的标准修饰键是ctrl键;在Mac OS上是command键。一个简单的自动使用这个修饰键的方法是将修饰键设置为”accel”,这在windows和linux系统上对应为control键,在Mac OS上对应为command键。
Note: The "meta" key is the Command key on Mac OS X (the one with the cloverleaf design on it).
key元素本身从来不会显示在屏幕上。为了显示定义了的键盘快捷键如图15所示,可以将这个key元素的id对应到menu或者menuitem元素的key属性上。
图15:原文缺少该图

与box布局相关的元素

XUL包含很多用来严格组织屏幕小部件布局的元素。

spacer

如果你想要开启按钮之间的空白可以使用spacer元素。你可以使用flex属性或者style属性来使空白扩张或者设置为某一个值。

grid

与table元素在HTML中对内容进行布局一样,你可以在XUL中使用grid元素,如清单22所示,首先声明列数,然后定义每一行的内容。这个例子的输出如图16所示。你也可以先声明行,然后通过列来定义内容。
HTML中table可以使用的rowspan和colspan属性在XUL中不可用。
清单22:使用grid进行布局

<grid>
<columns>
<column/>
<column flex="1"/>
</columns>
<rows>
<row align="center">
<label value="User ID"/>
<textbox/>
</row>
<row align="center">
<label value="Name"/>
<textbox/>
</row>
</rows>
</grid>

图16:清单22的输出

stack

使用stack元素可以将多个部件叠加起来。与通常的box元素不同,stack元素中的所有元素都是一个堆在另外一个上面的,从最下面开始向上叠加。清单23展示了一个温度计类型的进度条的例子,其输出如图17所示。
清单23:用stack进行重叠

<stack>
<progressmeter mode="normal" value="50"/>
<hbox align="center">
<label value="In progress…"/>
</hbox>
</stack>

图17:清单23的输出

tab

使用tab元素可以将多个页面分开,就像属性页对话框中使用的那样;使用tabbox元素里对相关的元素进行分组。清单24举例说明,图18是其输出。
清单24:使用tab

<tabbox>
<tabs>
<tab label="tab1"/>
<tab label="tab2" selected="true"/>
</tabs>
<tabpanels>
<tabpanel>
<checkbox label="check1"/>
</tabpanel>
<tabpanel orient="vertical">
<checkbox label="check2"/>
<checkbox label="check3"/>
</tabpanel>
</tabpanels>
</tabbox>

图18:清单24的输出



发布了32 篇原创文章 · 获赞 83 · 访问量 29万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章