http://blog.youkuaiyun.com/lava_sdb/article/details/8582031
编写组件的UI
到目前为止我们建立了一个可以安装到Gecko应用中的组件。你所使用的XPCOM接口和工具是通用的跨平台的,可以被Gecko Runtime Environment或者任何Mozilla1.2以后任何基于Gecko的应用(这时GRE已经可用)。
本章,我们将建立WebLock组件的用户接口,这就意味着添加到 现有的 Mozilla 浏览器[other-mozlike-browsers]. 他使用 XUL, 这是一个Gecko知道如何呈现用户界面的XML语言, 同时它也跟特定的Mozilla用户界面交互, 为此它要把自己作为UI的扩展安装起来。特别是,我们在本章编写的用户界面会叠加到浏览器组件的状态栏,它提供了一个小图标,用户可以通过点击它访问weblock接口。
WebLock Indicator in Browser
1. User Interface Package List
本章所描述的用户界面包括4个文件:
· webLockOverlay.xulis 这个文件定义了叠加到浏览器的图标的状态
· weblock.xuldefines the web lock 管理器对话框.
· weblock.cssprovides 所有XUL文本的CSS样式
· weblock.jsprovides 所有XUL文件使用到的JavaScript函数
下面章节描述每个文件的功能。下一章回描述你怎么使用这些文件创建一个包,一个包含了WeLock组件和UI的安装归档。
因为这些步骤 (特别是 overlay section) 与Mozilla非常相关,这一章被分成几个不同的部分。 第二部分, XUL, 描述基于XML的用户接口语言 (XUL) 以及他如何创建一个对话框(提供访问WebLock 组件和它的服务)。 第三部分, Overlaying New User Interface Into Mozilla, 描述如何建立一个overlay到浏览器以便Mozilla build能访问这个对话框. 在overlay 部分, 我们讨论如何从Mozilla导入scripts, images, 和其他资源到你的 UI, 这会是比较复杂的部分。
如果WebLock组件被安装到Mozilla或者其他基于Gecko的浏览器,那么第三节怎么在浏览器里创建一个控制web locking的入口点。 如果你计划部署WebLock到其他的程序,你不得不制定一个不同的访问方式(例如,原生widget实例化并控制WebLock 组件)。
2. Client Code Overview
在我们开始制作实际的用户界面之前,我们应该首先建立访问WebLock组件和它的接口的客户代码,他们用来来控制浏览器的Web locking。
首先,当组件加载后尽快的展示他的基本状态是很重要的。 如同安全网页图标,weblock图标放在browser右下角,提示browser是否当前是锁定的。 WebLock组件的初始状态总是unlock,我们需要一些客户代码(接口中的JavaScript代码)来表达并跟踪用户操作iWebLock接口的状态。一个boolean型变量:wLocked 就可以完成这个工作:
// initialize the wLocked variable as unlocked
var wLocked = 0;
这个函数被用户界面调用并且调用被传递到WebLock组件的lock和unlock函数,我们也需要对组件里的相应变量做出调整:
function wLock()
{
// check to see if locking is on or off
weblock.lock();
wLocked = 1;
}
function wUnLock()
{
// check to see if locking is on or off
weblock.unlock();
wLocked = 0;
}
An important preliminary of these functions is that the WebLock component be made available to the JavaScript in the form of the weblock object being used in the snippets above. As you can see, weblock is initialized as a global JavaScript variable, available in the scope of these functions and others:
使用这些函数的重要前提是WebLock 组能够在JavaScript里使用,就像上面的代码片段里的weblock对象一样。 正如你所看见,weblock被初始化为一个Javascript全局变量,那样他就可以在这些函数里使用了:
var weblock = Components.classes["@dougt/weblock"]
.getService()
.QueryInterface(Components.interfaces.iWebLock);
你还必须编写JavaScript代码,通过AddSite方法把新的站点加入白名单。 这个有点复杂,因为它需要你与当前页面交互,或提供另外的用户界面(例如,一个编辑框,允许在其中输入任意的URL)用于输入指定的URL。 在XUL那一节,我们将描述用户界面是如何定义的。 这一节描述如何调用接口的函数和他们怎么与WebLock组件进行交互。
AddSite方法期望的URL实际上就是一个字符串,所以我们直接通过用户界面传入一个字符串,或者我们可以对字符串的有效性进行验证(是否有效的URL)。我在本指南里只聚焦于WebLock的功能(而不是UI),我们假设从界面获得的字符串是有效的,可直接加入白名单:
function addThisSite()
{
var tf = document.getElementById("dialog.input");
// weblock is global and declared above
weblock.AddSite(tf.value);
}
此JavaScript函数可直接被XUL构件调用,输入字符串通过textbox 元素的属性value获取。.
你还需要建立一个函数,当用户点击WebLock 图标的时候可以显示WebLock 窗口。 这个函数使用window对象的openDIalog方法,方法有一个参数,此参数为定义对话框的XUL文件的URL:
function loadWebLock()
{
window.openDialog("chrome://weblock/weblock.xul");
}
3. XUL
Mozilla使用XUL(文件使用XML语言)来定义它的应用的用户界面,浏览器,邮件客户端,IRC客户端等等,都是使用XUL来定义整个用户界面。 XUL标记里的元素映射为用户界面里的构件,他们由Gecko渲染显示 - 因此,对一个实例,应用程序窗口的根元素的标记为<window/>,对话框的根元素为<dialog/>。 在XUL文件内部, <button/>, <menu/>, 和<checkbox/>这些元素能够挂接到一个事件模型,挂接到脚本,挂接到能够执行大量浏览器功能的XPCOM接口。
在Using XPCOM Components 那一章,你已经看到了XPCOM对象怎么反射为一个JavaScript对象。 现在我们已经创建了WebLock组件并且在XPCOM里运行良好,在这一章,我们创建用户界面,用于实际的实例化WebLock组件和使用它的方法控制浏览器控制页面的加载。
在前一节中,我们概述了JavaScript与WebLock组件怎么进行交互。在本节中,我们将要创建的XUL界面,当用户同他交互时,它调用相应的JavaScript方法,实现功能。
3.1 The XUL Document
创建实际的XUL文件要做的首要事情是,在其中定义对话框的用户界面和定义与Web locking初始化交互的事件。 在XUL文档顶端,紧跟在XML申明后的根元素通常是<window/>,但是对于对话框这个元素是<dialog/>。这个XUL看起来如下所示:
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<dialog id="weblock_ui"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="Web Lock Manager"
persist="screenX screenY"
screenX="24" screenY="24">
</dialog>
注意这部分XUL文件也包含了样式申明,倒入CSS规则并把规则应用到界面的细节部分。在Gecko里,CSS 被用来几乎控制所有的XUL界面表现 - 颜色,位置,样式和一些扩展行为。 Web lock管理对话框基于标准对话框,所以你可以使用一个单一的申明,因此它可以从浏览器导入“global”皮肤,并把它应用到weblock.xul里定义的构件上。
现在你需要保存一下,最外层的web lock dialog部分称为weblock.xul,你要把它放在附录B所描述的安装包里。
注意,这个文件包含了当用户/管理员点击web locking icon的时候弹出的对话框。这部分UI - 需要动态地装载到Mozilla runtime - 在Overlaying New User Interface Into Mozilla描述 。
最终的对话框看起来如下所示:
Web Lock Manager Dialog
如你所见,这个界面很简单,只提供了最基本的构件。 完整的web lock管理器对话框的XUL文件参见下面定义的weblock.xul 。
3.2 The Locking UI
我们使用Radio Buttons来让用户选择web lock状态,就像上图显示的那样。在XUL里<radio/>元素被包含在<radiogroup/>父元素里。 它让用户只能选择radiogroup里的一个radio,不能多选。
Web lock 管理器里的radiogroup构件的定义如下所示:
<radiogroup>
<radio label="lock"/>
<radio label="unlock" selected="true"/>
</radiogroup>
WebLock组件的启动初始化状态总是 unlocked,所以你可以为unlock radio按钮增加 selected属性,并赋值为true(selected="true" )。
3.3 Site Adding UI
下一步是创建让你新建站点到白名单的界面。 也许你想加入一些界面让你能够查看白名单或者想列表那样编辑他。 在本指南我们只提供简单的添加功能,输入一个字符串,传输它到AddSite API。
<separator class="thin"/>
<hbox align="center">
<textbox id="url.input" flex="1"/>
<button label="Add this URL" oncommand="addThisSite();"/>
</hbox>
上面片段展示了XUL里的布局控件。 separator 创建一个小的隔离控件。 Textbox用于用户输入URL,他的父控件<hbox/>,是一个水平布局控件- 控制它的子控件的渲染方式,这里<hbox/>表示他的子控件在水平方向排列布局(当然也存在<<vbox/>,他的子控件在垂直方向布局)。
注意,当按钮被点击是,后面的会调用JavaScript函数:addThisSite(),函数在weblock.js 里定义,参见上面的Client Code Overview 。
3.4 weblock.xul
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<dialog id="weblock_mgg"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="Web Lock Manager"
style="width: 30em;"
persist="screenX screenY"
screenX="24" screenY="24">
<script src="chrome://weblock/content/weblock.js"/>
<hbox>
<separator orient="vertical" class="thin"/>
<vbox flex="1">
<separator class="thin"/>
<hbox align="center">
<textbox id="dialog.input" flex="1"/>
<button label="Add this URL"
oncommand="addThisSite();"/>
</hbox>
<hbox align="center">
<radiogroup onchange="toggleLock();">
<radio label="lock"/>
<radio label="unlock"/>
</radiogroup>
<spacer flex="1"/>
</hbox>
</vbox>
</hbox>
</dialog>
4. Overlaying New User Interface Into Mozilla
你已经有了一个可以跟WebLock组件交互的对话框, 但是你怎么把它装到browser中? 然后你怎么访问它呢? 当安装和准备好以后,WebLock 组件已经可以用了:XPCOM发现它把它添加到已注册组件列表里,然后WebLock组件观察到XPCOM启动事件并初始化自己。
但是,为了调用组件的功能,你仍然需要添加你的界面到浏览器里,Mozilla 的叠加机制可用来解决这个问题。Overlays是XUL文件可以用来注册他们自己到Browser,以便动态地嵌入到Browser UI合适的位置。
4.1 webLockOverlay.xul
XUL定义了一个新的小图标:这个小图标用来调用JavaScript函数,加载我们前面定义的weblock.xul 文件。这个图标实际上是一个单独的<statusbarpanel/>元素,获取叠加到主浏览器,以及一些JavaScript 和一些 CSS, 控制元素的行为和外观的元素。 这些全部在XUL文件里:
The WebLock Overlay
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://navigator/content/weblock.css" type="text/css"?>
<overlay id="weblockOverlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://weblock/content/weblock.js"/>
<statusbar id="status-bar">
<statusbarpanel class="statusbarpanel-iconic"
id="weblock-status"
insertbefore="offline-status"
oncommand="loadWebLock();"
status="none"/>
</statusbar>
</overlay>
注意,文件的根元素不是<window/> 而是<overlay/>。在叠加机制里,XUL元素使用唯一ID来区分自己,防止和已存在的浏览器的产生冲突。 在这个例子里, weblock <statusbarpanel/> 显示为<statusbar/>(id为"status-bar")元素的子元素。这个id与navigator.xul里<statusbar/>的id一样,这意味着新UI将会叠加在这里(例如,weblock statusbarpanel)并且UI已经在运行时在浏览器的<statusbar/>里进行定义。
5. Other Resources
这部分描述剩下的需要添加和打包到WebLock组件来提供web locking用户界面的文件。
Other Front End Resources
在某些UI包中, 本地化资源也被打包进去。 他们包含DTDs(界面的标签被打包进此文件),如果切换为其他语言,只需要替换此文件就可以了。 例如,用户界面包通常包含了English的DTD文件,文件里面定义了菜单,按钮,标签等在界面上显示的字符串。 不用语言只需提供不同语言版本的DTD文件就可以了,当用户选择了不同的语言包,程序会自动使用相应语言包。
5.1 weblock.css
下列样式表在文件weblock.css,里定义,CSS文件在应用图标叠加反射web lcok状态和提供访问呢web lock管理器对话框时被加载。
statusbarpanel#weblock-status
{
list-style-image: url("chrome://weblock/wlock.gif");
}
statusbarpanel#weblock-status[status="locked"]
{
list-style-image: url("chrome://weblock/wl-lock.gif");
}
statusbarpanel#weblock-status[status="unlocked"]
{
list-style-image: url("chrome://weblock/wl-un.gif");
}
样式规则由XUL里id为“weblock-status”的元素的状态决定。 正如你在上面看到的,当状态被设置为“locked”,图片wl-lock.gif用于显示这个状态,当状态变为unlocked时,使用wl-un.gif。(注意,我们使用了三张图片来展示weblock的状态,但是wlock.gif 和wl-lock.gif是相同的,因为weblock推定它加载时为未锁定。此教程使得使用的只有两个不同的状态,但您可以进一步定制 weblock,如果你想使用这三个图像的外观)。
演示里的 weblock 管理器对话框本身不需要任何特别的样式,你需要的所有规则在 weblock.css 中。请注意,weblock.xul 文件,在其中定义管理器仅导入global皮肤:
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
保存weblock.css 到你的工作路径。
现在你应该已经有了本章开始的“打包清单”里的4个文件清单,他们用于WebLock 打包(参见 User Interface Package List)。 现在不用担心这些文件怎么放。下一章, Packaging WebLock, 我们讨论如何打包这些文件以便 WebLock 组件或者别的资源利用它们。
5.2 Image Resources
如果你学习本教程并且希望使用WebLock组件在statusbar中的图片,你可以从 http://www.brownhen.com/weblock下载他们和其他weblock相关资源. 这些GIF文件表示的它的几种状态:
· wlock.gif
· wl-lock.gif
· wl-un.gif
Note: other-mozlike-browsers
1 或者你可能会很喜欢这些东西. 还有一些基于 Gecko的browsers ,例如Beonex 和 IBM Web Browser 也会共享很多Mozilla用户界面成分, 你也可能装载 WebLock 组件和用户界面到其中。不过请注意,WebLock有可能还不能保证完全安装到Mozilla Firefox,因为firefox有一些新的变化 (这本书是2003的版本).