概述
XUL概览
XUL是一种基于XML的语言,是为mozilla浏览器的GUI标记语言而开发的。结合HTML和脚本语言去开发用户界面的早期实验经历了很长一个过程,可以认为XUL是这个过程的演化结果。用在windows vista中的XAML也经历了相似的过程,在adobe flash中使用的FLEX也一样。与显示平台无关的网页相似,用XUL标记的应用程序在任何运行了Firefox的环境中都能够同样的运行。
由于HTML原本是作为一种标记文档、指定网页的语言,它不可避免的缺少用于标记应用程序的功能。然而,XUL则是在已经成熟的标记语言的基础上用于描述用户界面的语言,插入带有复杂特性的UI组件是可能的,并且只需要写一下标签而不需要任何特殊的脚本。
与那些由W3C这样的标准化组织标准化的正式技术规范的语言不同,XUL当前还没有一个明确的技术规范。最新的XUL技术规范请参见MDC上的XUL参考手册以及mozilla wiki上的XUL页面。
本章中解释的每一个元素,都有一个带有源代码的例子。你可以你可以输入这些例子并在Firefox中打开它们来看看它们有什么样的行为及是怎样展现的。
显示XUL的方法
XUL似乎是mozilla应用程序(如Firefox、thunderbird以及它们的扩展)中专有的,但是其他基于gecko引擎的网页浏览器、甚至基于网页的内容也有使用XUL的。例如,有一个辅助在amazon上购物的,以及用来编写并显示幻灯片的工具。
要试验本章中的示例代码,将它们保存为.xul为后缀的文件并将其拖到Firefox浏览器窗口中即可。(译注:Firefox较高版本不支持这种方式,要这样测试可用使用早期版本的Firefox。如firefox3.6).
如果我们想要Firefox运行的过程中不显示任何Firefox本身的GUI而只显示某个XUL文件的内容,我们可用运行Firefox并设置选项-chrome file_URL.XUL。
另一种方法,如清单1所示,使用window.openDialog()方法,这只能用在XUL窗口中。这是用于扩展来打开独立窗口的。
清单1:打开一个没有Firefox固有GUI的Firefox窗口
window.openDialog( 'another.xul' , '_blank' , 'chrome,all,dialog=no' );
XUL作为一个XML应用程序
清单2展示了一个由XUL(一个XUL文档)标记定义GUI的文件例子。在XUL中,根元素一般是window元素。其名字空间是:
如果字符编码是UTF-8,编码的指定和XML声明都可以省略。但是本章中的例子都将它们包含进来了。
因为一个XUL文档也是一个XML文档,它可以包含XHTML,SVG、MathML,以及其他元素;如果你使用外部的实体参考,XML文档的内容都是模块化的;联合使用其他与XML相关的技术如DOM,XLink,或XSLT,你可以在很多不同的应用程序中使用它。
清单2:XUL文档的一般结构
xml version = "1.0" encoding = "UTF-8" ?>
xml-stylesheet href = "chrome://global/skin/" ?>
< window xmlns = "" >
window >
即使在Firefox和扩展的国际版中,也使用了这种XML功能。
读取样式表
XUL使用CSS来指定其原始的外观。因为XUL也是一种XML,读入样式表使用xml-stylesheet处理指令。
在清单2的第二行,我们在读入主题的标准样式表。通过chrome://global/skin/指向一个特殊的样式表,我们就可以使标签和按钮尺寸,窗口背景色等等与当前Firefox选择的主题相匹配。我们也可以读入一个我们自己设置的样式表。
XUL的box模型
原则上,XUL联合使用两类box:水平box和垂直box,对所有的UI组件进行布局。如清单3所示,可以使用hbox来将元素水平的布局,也可以使用vbox来将元素进行垂直的布局。当这个文件在Firefox中打开的时候,显示如图1所示。
清单3:水平和竖直box
< label value = "Horizontal layout" />
< hbox >
< button label = "horizontal1" />
< button label = "horizontal2" />
hbox >
< label value = "Vertical layout" />
< vbox >
< button label = "vertical1" />
< button label = "vertical2" />
vbox >
< label value = "mixed" />
< hbox >
< button label = "mixed1" />
< vbox >
< button label = "mixed2" />
< button label = "mixed3" />
vbox >
< button label = "mixed4" />
hbox >
图1:清单3的输出
还有一个grid元素,可以用于进行相似的布局,也可以使用HTML的table元素,stack元素来对其他元素进行布局,等等。所有在屏幕上显示的微件都是使用这些box来布局的,这使得复杂接口的设计成为可能。
共有属性
在看各种接口对象之前,我们来看看他们中的一些共同属性,特别是那些经常使用的属性。
Id和class
属性id和 class与XHTML中的功能相同。id是用来定义一个元素的唯一标识名称的,class是用来为元素分类的;这两个都为CSS和javascript提供了引用元素的方便的途径。也有特殊类型的元素只在别的元素引用的时候才会显示出来。
orient
一个box中的内容是竖直还是水平排列的取决于这些元素的初始状态。你可以使用orient属性来设置或者改变这一布局方式,orient的选项是horizontal和vertical。
align和pack
align和pack属性都是指定box中元素布局的。他们的值可以是start(上边或者左边),center,end(下边或右边),或者stretch(将元素扩展到最大以匹配其所在的元素)。
align属性定义为与orient属性相垂直的方向,而pack属性与orient属性的操作方向一致。图2展示了分别为两个元素设置align="center" pack="start"的时候结果的不同。
清单4:align与pack与orient的关系
< box flex = "1" align = "end" pack = "end" >
< button label = "Happy" />
< button label = "Sad" />
box >
图2:清单4的输出
align: 上 中 下 star,center,end 拉伸 stretch
pack:左 中 右 star,center,end 拉伸 stretch
flex
一般的,元素都有修正的高和宽。属性flex说明了一个元素应该扩展以占据一个窗口的高度和宽度的比例。
flex的值是一个正整数,表示在父元素的orient属性方向上的增长倍数。例如,flex=“1”表示这个元素应扩展以适合其orient方向;如果有两个flex=“1”的元素在同一行,他们就会变化相同的尺寸。你也可以设置flex=“2”(或者更高的数值)作为元素的尺寸倍数。在清单5中第二个标签将会显示成第一个的两倍(图3)。
清单5:随着flex增长
< hbox >
< label value = "label1" flex = "1" style = "border: 1px solid;" />
< label value = "label2" flex = "2" style = "border: 1px solid;" />
hbox >
图3:清单5的输出
ordinal
在XUL的box中,元素通常会按照它们在代码中出现的顺序进行布局(从左到右或者从上到下)。使用ordinal属性可以改变它们的顺序。ordinal属性的值是正整数,用来为box的布局进行排序——在清单6中的例子,按钮会按照button3,button2,button1的顺序显示(图4)。
如果多个元素具有相同的ordinal值,就会按照它们在源代码中出现的相对顺序进行布局,ordinal默认的值是1.
清单6:使用ordinal改变顺序
< vbox >
< button label = "button1" ordinal = "3" />
< button label = "button2" ordinal = "2" />
< button label = "button3" ordinal = "1" />
vbox >
图4:清单6的输出
box的尺寸
你可以用width和height属性为XUL元素准确的设置尺寸,如清单7所示。如果你创建的元素使用了flex属性可以变化,你也可以使用minwidth,minheight,maxwidth,maxheight等来设置最小和最大尺寸。这些都使用像素为单位。
清单7:设置按钮的尺寸
< button label = "Button" width = "200" height = "100" />
如清单8所示,你也可以使用style属性嵌入CSS到元素中,这样你就可以用其他的单位设置尺寸了。
清单8:使用CSS标记来设置按钮的尺寸
< button label = "Button" style = "min-width: 10em;" />
hidden和collapsed
hidden和collapsed属性作为关闭元素显示的开关。
设置hidden=“true”可以禁用元素的显示。这与在CSS中设置display:none的效果是一样的。你可以使用这个来设置一个隐藏的或者不需要出现的状态,例如在右键菜单中不需要出现的菜单项。
设置collapsed=“true”可以将一个元素的高和宽设置为0,但是这个元素还是会被认为是存在的。这与在CSS中设置visibility:collapse的效果相同。使用这个可以将当前不使用的侧边栏“收起”。
disabled
当不是所有的元素都合适的时候,你可以使用disabled属性来暂时的禁用对一个元素的输入,这也是用户通常所做的,典型的,disabled=“true”的元素会显示成浅灰色或者透明的。
tooltiptext
使用tooltiptext属性可以在元素上显示一个简短的解释性工具提示。输入需要作为工具提示的文本作为这个属性的值。
persist
persist属性是一种在用户操作改变了XUL元元素状态之后存储其状态的简单方式。其他你想要存储的以空格隔开的属性名称组成一个ASCII字符串作为persist的参数。下次那个XUL文档打开的时候,保存的值就会自动的修复。设置的系统我们会在第四章中进行说明,使得保存简单的状态变得可行且不需要任何复杂的脚本。
注:这些值存储在localstore.rdf文件中,在用户profile里面。
为了让persist属性记录其他元素的状态,这些元素都必须设置id。
http://blog.csdn.net/z6482/article/details/7317898
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定义了的按钮中有按钮按下的时候相应的行为就会发生。如果这些事件处理器没有定义,不管点击accept按钮还是cancel按钮都会关闭对话框。清单9中展示了一个简单的对话框例子,图5展示了其输出。
清单9:一个对话框
xml version = "1.0" encoding = "UTF-8" ?>
xml-stylesheet href = "chrome://global/skin/" ?>
< dialog xmlns = ""
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 = "" />
由于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" >
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的输出
其他XUL功能
Overlay
XUL的一个与众不同的特性就是overlay。可以将多个XUL文档联合起来,并当做一个单独的XUL文档来处理。在Firefox中,这用来对各种功能进行模块化并实现了扩展。
通过在XML声明中插入一个xul-overlay处理指令和根元素的开始标签,通过xul-overlay指定的XUL文档会在当前当前的XUL文档读取的同时进行读取。实际显示的XUL文档是原始XUL文档和由xul-overlay指定的文档结合体。
将清单25的内容保存为文件base.xul。看看使用这个XUL文档的显示例子。
清单25:base.xul
xml version = "1.0" encoding = "UTF-8" ?>
xml-stylesheet href = "chrome://global/skin/" ?>
xul-overlay href = "overlayDocument.xul" ?>
< window xmlns = "" >
< hbox id = "box1" >
< label id = "label1" value = "Text label" />
hbox >
< hbox id = "box2" >
< label id = "label2" value = "Text label" />
hbox >
window >
附加元素
当定义XUL文档打开为overlay的时候,使用overlay元素作为根元素。将清单26命名为overlayDocument.xul并保存在base.XUL文件相同目录下。
我们在Firefox窗口中打开base.xul。在读取base.xul的同时读取了文件overlayDocument.xul,结果如图19所示,overlayDocument.xul文件附加到 base.xul之后。
清单26:overlayDocument.xul文件
xml version = "1.0" encoding = "UTF-8" ?>
< overlay xmlns = "" >
< button label = "Button 1" />
< button label = "Button 2" />
< button label = "Button 3" />
overlay >
图19:清单25和26的输出
合并与插入元素
通过在overlay的XUL文档中插入id属性到要添加的元素,基本文档中相同id值的元素就会将它们的属性和值合并到overlay文档中。
用清单27中的内容覆盖overlayDocument.xul并重新存储。
清单27:代替overlayDocument.xul的内容
xml version = "1.0" encoding = "UTF-8" ?>
< overlay xmlns = "" >
< hbox id = "box1" align = "center" style = "border: 1px solid; margin: 1em;" >
< button label = "Button 1" />
< button label = "Button 2" insertbefore = "label1" />
hbox >
< button label = "Button 3" />
overlay >
再次在Firefox窗口中打开base.xul。如图20所示,style属性从具有id为”box1”元素的overlay文档合并到了基文档中具有相同id的标签上,插入到box中。
图20:清单25和27的输出
更多的,声明了insertbefore=”label”的”button2”按钮插入到了id为label1的元素之前。相反的,如果想要直接插入到后面,就开业使用insertafter属性。也可以使用position元素的方法来准确定位到任何位置。例如,使用position=”4”可以将其插入作为第四个元素。
外部实体
XUL作为XML的一种形式,也可以使用基于DTD的实体参考,如清单28所示。注意外部DTD文件只限于使用chrome URL来给出。网页或本地目录的常规DTD文件不会打开。
Note: You may use a relative path to access a chrome URL from an XUL document.
清单28:读取外部实体
xml version = "1.0" encoding = "UTF-8" ?>
xml-stylesheet href = "chrome://global/skin/" ?>
>
< window xmlns = "" >
< button label = "&button.1.label;" />
< button label = "&button.2.label;" />
window >
清单29:testapp.dtd
属性声明的替代CSS
Gecko渲染引擎包含很多-moz-开头的CSS属性;这些是XUL的自定义属性,下面表4中显示了与常规XUL属性的对应。事实上,那些XUL属性是通过这些CSS属性来操作的。
为这些CSS属性声明的值与XUL属性使用的是相同的整型值或者按键值。然而不推荐将这些属性用于常规的XUL开发中,这些在自定义Firefox的UI时非常有用,不需要对userChrome.css编写脚本。例如,如果你将清单30中的内容命名为userChrome.css并保存到用户profile文件目录下的chrome目录,tab工具栏就会出现在内容区域的下方。
表4:css属性与XUL属性的对应
XUL attribute
CSS property
Example
orient
-moz-box-orient
-moz-box-orient: vertical;
align
-moz-box-align
-moz-box-align: start;
pack
-moz-box-pack
-moz-box-pack: stretch;
flex
-moz-box-flex
-moz-box-flex: 1;
ordinal
-moz-box-ordinal-group
-moz-box-ordinal-group: 2
清单30:一个将tab工具条放到底部的用户样式表
tabbrowser .tabbrowser-strip {
-moz-box-ordinal-group: 2;
}
tabbrowser tabpanels {
-moz-box-ordinal-group: 1;
}
文件类型对应的图标
Firefox中使用一种特殊的URI结构moz-icon来产生文件类型的图标,这些图标是Firefox运行的系统中的标准图标。例如,要为后缀为.pdf的文件显示一个16×16的图标,就可以使用moz-icon://.PDF?size=16。
你也可以使用内容类型作为关键词而不使用点后缀来作为图标的参考;例如,你可以使用moz-icon://goat?size=16&contentType=text/plain来显示一个纯文本的图标。
表2中提到的按钮图标也可以使用moz-icon URI来调用,使用的标记为moz-icon://stock/gtk-button name?size=button。注:在unix环境中这不起作用。
微调按钮
你可以为textbox元素添加一个type=”number”的声明就可以将文本框指定为一个熟人数字值的控件。这也会导致如图21所示的微调按钮的出现。与这个相关的属性是min和max用来设置最小和最大值,以及increment来设置党点击一次微调按钮时显示的值的变化量。
图21:用于数字输入的文本框
滑动条
scale元素用起来与windows中的音量控制滑块非常相似,用滑块可以通过上下或左右移动滑块来改变值(如清单31和图22所示)。
Note: Although this control is also known as a slider, the slider element already exists in XUL as a part of a scrollbar, so this element has been named "scale".
清单31:scale元素
< hbox >
< scale orient = "horizontal" min = "-100" max = "100" value = "0" />
< scale orient = "vertical" min = "0" max = "100" value = "50" />
hbox >
图22:清单31的输出
阅读(513) | 评论(0) | 转发(0) |