Please note, this is a STATIC archive of website developer.mozilla.org from November 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Building the WebLock UI

到目前为止我们建立了一个可以安装到Gecko应用中的组件。你所使用的XPCOM接口和工具是通用的跨平台的,可以被Gecko Runtime Environment或者任何Mozilla1.2以后任何基于Gecko的应用(这时GRE已经可用)。

本章,我们将建立WebLock组件的用户接口,这就意味着添加到 现有的 Mozilla 浏览器[other-mozlike-browsers]. 他使用 XUL, 这是一个Gecko知道如何呈现用户界面的XML语言, 同时它也跟特定的Mozilla用户界面交互, 为此它要把自己作为UI的扩展安装起来. Specifically, the user interface we create in this chapter will be overlaid into the statusbar of the browser component, where it will provide a small icon the user can click to access the web lock interface.

WebLock Indicator in Browser

Image:web-lock-ui.png

User Interface Package List

本章所描述的用户界面包括4个文件:

  • webLockOverlay.xul is the file that defines the little status icon in the browser.
  • weblock.xul defines the web lock manager dialog.
  • weblock.css provides style rules for both of the XUL files.
  • weblock.js provides JavaScript functions for both of the XUL files.

下面章节描述每个文件的功能。. In the following chapter we'll describe how you can take these files and create a package , an installable archive that includes the WebLock component and the new UI.

因为这些步骤 (特别是 overlay section) 与Mozilla非常相关, the chapter is divided up into a couple of different sections. 第二部分, XUL, 描述XML-based 用户接口语言 (XUL) 以及他如何创建一个对话框访问WebLock 组件和它的服务. 第三部分, Overlaying New User Interface Into Mozilla, 描述如何建立一个overlay到浏览器以便Mozilla build能访问这个对话框. 在overlay section, 我们讨论如何从Mozilla导入scripts, images, 和其他资源到你的 UI, 这会是比较复杂的部分.

If the WebLock component is being installed in Mozilla or another Gecko-based browser, then this third section shows you how to create the entry point in the browser for controlling the web locking. If you are planning on deploying the WebLock component in some other application, you'll have to devise a different means of access (e.g., native widgetry that instantiates and controls the WebLock component).

Client Code Overview

在我们开始实际用户界面以前,我们应该首先建立访问WebLock组件和它的接口来控制browser的Web locking的客户代码.

首先, it's important to be able to 表达Lock的基本状态as soon as it's loaded. 如同安全网页icon, weblock icon 在browser右下角,提示browser是否当前是锁定的. Since the WebLock component is always initialized as unlocked, we can have the 客户代码 - 接口中的JavaScript代码 - 表达并跟踪状态 as the user manipulates the iWebLock interface. A boolean wLocked variable can do this:

// initialize the wLocked variable as unlocked
var wLocked = 0;

Then the functions that get called from the interface and call through to the lock and unlock methods of the WebLock component must also adjust this variable accordingly:

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;
}

这些函数的前提是WebLock 组件对于 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:

var weblock = Components.classes["@dougt/weblock"]
                        .getService()
                        .QueryInterface(Components.interfaces.iWebLock); 

In addition to this basic setup, you must also write JavaScript that uses the AddSite method to add new sites to the white list. This is a bit more complicated, because it requires that you work with the currently loaded page or provide other UI (e.g., a textfield where you can enter an arbitrary URL) for specifying URLs. In the XUL section we'll go into how the user interface is defined. This section describes the functions that are called from the interface and how they interact with the WebLock component.

The URL that the AddSite method expects is a string, so we can pass a string directly in from the user interface, or we can do a check on the string and verify that it's a valid URL. In this tutorial, focusing as it is on the WebLock functionality (rather than the UI), we'll assume the strings we get from the UI itself are URLs we actually want to write to the white list:

function addThisSite()
{
  var tf = document.getElementById("dialog.input");
  // weblock is global and declared above
  weblock.AddSite(tf.value);
}

这段javascript可以直接被 XUL widget调用, where the input string is retrieved as the value property of the textbox element.

你还需要建立一个函数当用户点击weblock icon的时候来显示WebLock 窗口. That function uses the openDialog method from the window object and takes the URL to the XUL file in which the dialog is defined:

function loadWebLock()
{
  window.openDialog("chrome://weblock/weblock.xul");
}

XUL

The entire user interface of the Mozilla browser and all of the applications that go with it, including the mail client, the IRC client, and others, have been defined in an XML language called XUL. Elements in the XUL markup map to widgets in the interface that Gecko renders in a fairly straightforward way - so, for instance, the root element of an application window is the element <window/>, the root element of the dialog we'll be creating here is <dialog/>, and so forth. Within a XUL application file, elements like <button/>, menu/>, and checkbox/> can be hooked up to an event model, to scripts, and to the XPCOM interfaces that carry out a lot of the browser functionality in Mozilla.

In Using XPCOM Components you saw how XPCOM objects are reflected into the interface layer as JavaScript objects. In this chapter, now that we've created the WebLock component and made it available to XPCOM, we create the UI that actually instantiates the WebLock component and uses its methods to control page loading in the browser.

In the previous section, we outlined the JavaScript that interacts with the WebLock component. In this section, we are going to create the XUL interface that calls the JavaScript methods when the user interacts with it.

The XUL Document

The first thing to do is create the actual XUL document in which the user interface for the dialog and the events that initiate interaction with the web locking are defined. At the top of all XUL documents, an XML declaration is followed by the root element for the document, which is usually <window/> 对于对话框,也可以是<dialog/>. The "shell" for the XUL file, then, looks like this:

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>

<dialog id="weblock_ui"
        xmlns="https://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 
        title="Web Lock Manager"
        persist="screenX screenY"
        screenX="24" screenY="24">

</dialog>

注意这部分XUL文件也包含了stylesheet declaration, which imports CSS rules and applies them to particular parts of the interface. In Gecko, CSS 被用来几乎控制所有的XUL界面表现 - its color, position, style, and to some extent its behavior as well. The web lock manager dialog does not deviate from the look of a standard dialog, so it can use a single declaration to import the "global" skin from the browser and make it available to the widgets you define in weblock.xul.

You can save this first, 最外层的web lock dialog部分称为weblock.xul, 你要把它放在附录B所描述的安装包里.

注意这个文件包含了当用户/管理员点击web locking icon的时候弹出的对话框. 这部分UI - 需要动态地装载到Mozilla runtime - 在Overlaying New User Interface Into Mozilla.

描述

最终的对话框看起来是.

Web Lock Manager Dialog

Image:Weblock-sitelist-ui.png

As you can see, it's a simple interface, providing just enough widgetry to lock and unlock the browser and to add new sites to the list. The entire XUL file for the web lock manager dialog is defined in weblock.xul below.

The Locking UI

Once you have the basic XUL wrapper set up for your interface, the next step is to define that part of the interface that locks and unlocks the browser. One of the most efficient ways to expose this is to use radio buttons, which allow the user to toggle a particulart state, as the figure above illustrates.

In XUL individual <radio/> elements are contained within a parent element called <radiogroup/>. Grouping radio elements together creates the toggling UI by requiring that one or another of the elements be selected, but not both.

The XUL that defines the radiogroup in the web lock manager dialog is this:

<radiogroup> 
   <radio label="lock"/>
   <radio label="unlock" selected="true"/>
</radiogroup>

Since the WebLock component always starts up in the unlocked position, you can add the selected="true" attribute and value on the unlock radio button and reset it dynamically as the user takes action.

Site Adding UI

The next step is to create that part of the user interface that lets you add a new site to the white list. There are other, more sophisticated ways to do this; you may also want to include some UI that lets you view the white list or edit it as a list. In this part of the tutorial, however, we only provide the means of adding an URL provided as a string (which is not checked for validity) and passing it through to the AddSite API we defined in the earlier part of the tutorial.

<separator class="thin"/>

<hbox align="center">
  <textbox id="url.input" flex="1"/>
  <button label="Add this URL" oncommand="addThisSite();"/>
</hbox> 

This snippet introduces a couple of new general layout widgets in XUL. The separator that appears at the top of this snippet creates a little divider between widgets like the kind you see in menus that divide sets of functionality available there. The parent of the textbox that users enter an URL into is something called an <hbox/>, which is a layout widget - often invisible - that controls the way its child elements are rendered. In this case the <hbox/> centers the textbox and the button children, and it orients them horizontally (in contrast to the <vbox/>, which orients its children vertically).

Notice also that when it's clicked, the button executes a JavaScript function called addThisSite(), which we've already defined in the weblock.js file in Client Code Overview above.

weblock.xul

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>

<dialog id="weblock_mgg"
        xmlns="https://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> 

Overlaying New User Interface Into Mozilla

你已经有了一个可以跟WebLock组件交互的对话框, 但是你怎么把它装到browser中? 然后你怎么访问它呢? 当安装和准备好以后,WebLock 组件已经可以用了: XPCOM finds it and adds it to the list of registered components, and then WebLock observes the XPCOM startup event and initializes itself.

But you still have to add your new UI into the browser so it can call the component, and the Mozilla overlay mechanism is the way to do this. Overlays 是 XUL文件可以用来注册他们自己以便动态地嵌入到Browser UI合适的位置.

webLockOverlay.xul

The XUL that defines the new icon is small: 这是一个调用JavaScript function来装载前面我们定义的weblock.xul 文件的小图表. The icon is actually a separate <statusbarpanel/> element that gets overlaid into the main browser, along with some JavaScript and some CSS to control the behavior and appearance of the element, respectively. Here is that XUL file in its entirety:

The WebLock Overlay

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://navigator/content/weblock.css" type="text/css"?>

<overlay id="weblockOverlay"
         xmlns="https://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

  <script type="application/x-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/>. In overlays 被 XUL elements用来把他们和其他元素相区分的id属性被设置称为browser中他们要嵌入部分的值. In this case, the weblock <statusbarpanel/> appears as a child of the <statusbar/> element with id "status-bar". This id is the same one used by the <statusbar/> in navigator.xul, which means that the overlay mechanism will merge the new UI here (i.e., the weblock statusbarpanel) and the UI already defined within that browser <statusbar/> at runtime.

Other Resources

这部分描述剩下的需要添加和打包到WebLock组件来提供web locking用户界面的文件。

Other Front End Resources

在某些UI包中, 本地化 resources are also defined. These include DTDs in which the language in which the UI is labelled can be extracted into external files, which are swapped with DTDs for other languages. For example, user interface packages often include an English DTD that defines labels and strings for button and menus and other elements in the interface. When the user selects a different language pack , all of the English that's been externalized in these files is dynamically replaced with the new choice. In addition to DTDs, the localization parts of a user interface may also include string bundles in which strings that are used in the interface JavaScript can be similarly replaced. 有一些技术通过单独的文件来提供这种功能. 包含 bindings in XML files, metadata in RDF files, whole collections of CSS files called skins , and others.

weblock.css

The following style rules are defined in weblock.css, a CSS file that is loaded by the overlay and applied to the icon in the browser that reflects the current status of the web lock and provides access to the web lock manager dialog.

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");
}

The style rules are distinguished by the state of the status attribute on the element in the XUL with the id "weblock-status." As you can see above, when the status of the element is set to "locked", the image wl-lock.gif is used to show the state, and when the web locking is unlocked, it uses wl-un.gif. (Note: We include three images to represent the state of the weblock, but wlock.gif and wl-lock.gif are identical, since weblock is presumed to be unlocked when it's loaded. This tutorial makes use of only two different states, but you can further customize the look of the weblock using the three images if you wish.)

Since the presentation of the weblock manager dialog itself doesn't require any special styles, these are all the rules you need in the weblock.css. Note that the weblock.xul file in which the manager is defined imports only the global skin:

<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>

Save weblock.css in your working directory.

You should now have the four files listed at the top of this chapter as the "packing list" for the WebLock package (see User Interface Package List). Don't worry for now about where these files are. 下一章, Packaging WebLock, 我们讨论如何打包这些文件以便 WebLock 组件或者别的资源利用它们.

Image Resources

如果你学习本教程并且希望使用WebLock组件在statusbar中的图片,你可以从 https://www.brownhen.com/weblock下载他们和其他weblock相关资源. The GIF files that represent the various states are:

  • wlock.gif
  • wl-lock.gif
  • wl-un.gif
  1. Note: other-mozlike-browsers
    或者你可能会很喜欢这些东西. 还有一些基于 Gecko的browsers ,例如Beonex 和 IBM Web Browser 也会共享很多Mozilla用户界面成分, 你也可能装载 WebLock 组件和用户界面到其中. 不过请注意, WebLock有可能还不能保证完全安装到Mozilla Firefox,因为firefox有一些新的变化 (这本书是2003的版本).

Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.

文档标签和贡献者

标签: 
 此页面的贡献者: ziyunfei, Secure alex
 最后编辑者: ziyunfei,