source: chrome/content/v_identity/v_identity.xml @ 97d350

lite_0.1multiEditng_0.6ng_0.6_helpng_0.8ng_0.9
Last change on this file since 97d350 was 97d350, checked in by rene <rene@…>, 13 years ago

created new branch for upcoming 0.6 release. focus on object-orientation. somehow working.

  • Property mode set to 100644
File size: 21.3 KB
Line 
1<?xml version="1.0"?>
2<!-- ***** BEGIN LICENSE BLOCK *****
3   - This program is free software; you can redistribute it and/or modify
4   - it under the terms of the GNU General Public License as published by
5   - the Free Software Foundation; either version 2 of the License, or
6   - (at your option) any later version.
7
8   - This program is distributed in the hope that it will be useful,
9   - but WITHOUT ANY WARRANTY; without even the implied warranty of
10   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11   - GNU General Public License for more details.
12
13   - You should have received a copy of the GNU General Public License
14   - along with this program; if not, write to the Free Software
15   - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
16
17   - The Original Code is the Virtual Identity Extension.
18
19   - The Initial Developer of the Original Code is Rene Ejury.
20   - Portions created by the Initial Developer are Copyright (C) 2007
21   - the Initial Developer. All Rights Reserved.
22
23   - Contributor(s):
24   - ***** END LICENSE BLOCK ***** -->
25
26<!DOCTYPE overlay [
27<!ENTITY % vIdentDTD SYSTEM "chrome://v_identity/locale/v_identity.dtd">
28%vIdentDTD;
29]>
30
31
32<bindings id="mailComposeBindings"
33          xmlns="http://www.mozilla.org/xbl"
34          xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
35          xmlns:xbl="http://www.mozilla.org/xbl">
36   
37    <binding id="autoReplyTo" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete">
38    <content>
39        <children />
40        <xul:label class="menupopup_clone-description" value="autoReplyTo" />
41        <xul:observes element="msgIdentity_clone" attribute="label" onbroadcast="alert(document.getBindingParent(this).label); document.getBindingParent(this).value = document.getBindingParent(this).label" />
42    </content>
43    </binding>
44   
45    <binding id="tooltipPopupset">
46    <implementation>
47    <method name="addTooltip">
48    <parameter name="identityData" />
49    <parameter name="randID" />
50            <body><![CDATA[
51        this.removeTooltip(randID);
52        if (!randID) randID = "tooltip_" + parseInt((new Date()).getTime());
53        var toolTip = document.createElement("tooltip");
54        toolTip.setAttribute("class", "identityDataTooltip");
55        toolTip.setAttribute("id", randID);
56        toolTip.identityData = identityData;
57        this.appendChild(toolTip);
58        return randID;
59        ]]></body>
60    </method>
61    <method name="removeTooltip">
62    <parameter name="randID" />
63            <body><![CDATA[
64        if (randID) this.removeChild(document.getElementById(randID))
65        ]]></body>
66    </method>
67    </implementation>
68    </binding>
69   
70    <binding id="vI_identityDataTooltip" extends="chrome://global/content/bindings/popup.xml#tooltip">
71    <content onpopupshowing="this.popupshowing();this.resize()" onpopupshown="this.resize()" >
72            <xul:browser style="overflow:hidden" anonid="tooltipBrowser" class="vI_htmlTextBox" flex="1" disablehistory="true" onoverflow="document.getBindingParent(this).resize()"/>
73            <children />
74    </content>
75    <implementation>
76    <method name="popupshowing">
77            <body><![CDATA[
78        if (this.identityData && !this._initialized) {
79            if (!this._identityInfo) this._identityInfo =
80                "<table><tr><td colspan='2' class='name'>" +
81                    this.identityData.combinedNameHtml +
82                "</td></tr>" +
83                "<tr><td class='image'><img src='chrome://v_identity/skin/vi-info.png' /></td>" +
84                "<td class='identityTable'>" +
85                    "<table><tbody>" + this.identityData.getMatrix() + "</tbody></table>" +
86                "</td></tr></table>"
87            this._tooltipBrowser.outputString = this._identityInfo;
88            this._tooltipBrowser.cssSource = "vI_TooltipBrowser.css";
89            this._initialized = true;
90        }
91        ]]></body>
92    </method>
93    <method name="resize">
94        <body><![CDATA[
95        var width = document.getElementById("msgIdentity_clone").boxObject.width * 0.7;
96        var height = this._tooltipBrowser.contentDocument.lastChild.scrollHeight + 5;
97        this.sizeTo(width, height);
98        width = document.getElementById("msgIdentity_clone").boxObject.width * 0.75;
99        this.sizeTo(width, height);
100        ]]></body>
101    </method>
102    <field name="blocked">false</field>
103    <field name="identityData" />
104    <field name="_identityInfo">false</field>
105    <field name="_initialized">false</field>
106    <field name="_tooltipBrowser">document.getAnonymousElementByAttribute(this, "anonid", "tooltipBrowser")</field>
107    </implementation>
108    </binding> 
109   
110    <binding id="fromPopupItem_clone" extends="chrome://global/content/bindings/menu.xml#menuitem">
111    <content excludes="template,observes,menupopup">
112        <xul:image class="menupopup_clone-icon" xbl:inherits="src"/>
113        <xul:label class="menupopup_clone-text" xbl:inherits="value=label,accesskey,crop" crop="right" flex="1"/>
114        <xul:label value="&vident.accPane.prettyName.prefix;" class="menu_clone-description virtIdLabel" vid="false" xbl:inherits="vid" crop="right"/>
115            <xul:label class="menupopup_clone-description" xbl:inherits="value=description" crop="right"/>
116    </content>
117    <implementation>
118    <constructor>
119        <![CDATA[
120        this._identityDataStorage = this.identityData;
121       
122        this.label = this._identityDataStorage.combinedName;
123        this.value = this._identityDataStorage.id;
124        this.description = this._identityDataStorage.sideDescription;
125       
126        this.setAttribute("tooltip",
127            document.getElementById("vI_tooltipPopupset")
128            .addTooltip(this._identityDataStorage, this.getAttribute("tooltip")));
129        ]]>
130    </constructor>
131    <method name="clean">
132            <body><![CDATA[
133        document.getElementById("vI_tooltipPopupset")
134            .removeTooltip(this.getAttribute("tooltip"));
135        ]]></body>
136    </method>
137    <destructor>
138        <![CDATA[
139        this.clean();
140        ]]>
141    </destructor>
142    <property name="_identityData" onget="return this._identityDataStorage;" />
143    <property name="vid" onget="return this.getAttribute('vid');" onset="this.setAttribute('vid', val); return val;" />
144    <property name="label" onget="return this.getAttribute('label');" onset="this.setAttribute('label', val); return val;" />
145    <property name="value" onget="return this.getAttribute('value');" onset="this.setAttribute('value', val); return val;" />
146    <property name="description" onget="return this.getAttribute('description');" onset="this.setAttribute('description', val); return val;" />
147    </implementation>
148    </binding>
149
150    <binding id="smtpServerList" >
151    <resources>
152            <stylesheet src="chrome://global/skin/menu.css"/>
153    </resources>
154    <content sizetopopup="pref">
155        <xul:spacer flex="1" />
156            <xul:menulist class="smtpServerMenuList" anonid="smtpServerMenuList" allowevents="true" id="smtp_server_list">
157                <xul:menupopup anonid="smtp_server_list_popup" />
158            </xul:menulist>
159    </content>
160    <implementation>
161    <method name="_addDefaultServer">
162            <body><![CDATA[
163        var listitem = document.createElement("menuitem");
164        listitem.setAttribute("label", document.getElementById("bundle_messenger").getString("defaultServerTag"));
165        this._smtpPopup.appendChild(listitem);
166        this._smtpMenu.selectedItem = listitem;
167        ]]></body>
168    </method>
169    <method name="_addServer">
170        <parameter name="server" />
171            <body><![CDATA[
172        if (server instanceof Components.interfaces.nsISmtpServer && !server.redirectorType) {
173            var listitem = document.createElement("menuitem");
174            listitem.setAttribute("label", (server.description?server.description:server.hostname));
175            listitem.setAttribute("key", server.key);
176            this._smtpPopup.appendChild(listitem);
177        }
178        ]]></body>
179    </method>   
180    <constructor>
181        <![CDATA[       
182        this._addDefaultServer();
183        this._smtpPopup.appendChild(document.createElement("menuseparator"));
184
185        var servers = Components.classes["@mozilla.org/messengercompose/smtp;1"]
186            .getService(Components.interfaces.nsISmtpService).smtpServers;
187       
188        if (typeof(servers.Count) == "undefined")       // TB 3.x
189            while (servers && servers.hasMoreElements())
190                this._addServer(servers.getNext());
191        else                            // TB 2.x
192            for (var i=0 ; i<servers.Count(); i++)
193                this._addServer(servers.QueryElementAt(i, Components.interfaces.nsISmtpServer));
194       
195        this._prefroot.addObserver("extensions.virtualIdentity.show_smtp", this._observer, false);
196        this._observer.observe();
197        ]]>
198    </constructor>
199    <destructor>
200        <![CDATA[
201        this._prefroot.removeObserver("extensions.virtualIdentity.show_smtp", this._observer);
202        ]]>
203    </destructor>
204    <property name="smtp" onget="return this._smtpMenu.selectedItem.getAttribute('key');" >
205        <setter><![CDATA[
206        var MenuItems = this._smtpPopup.childNodes
207        for (var index = 0; index < MenuItems.length; index++) {
208            if (MenuItems[index].localName == "menuseparator") continue;
209            if (MenuItems[index].getAttribute("key") == val?val:"") {
210                this._smtpMenu.selectedItem = MenuItems[index];
211                break;
212            }
213        }
214        ]]></setter>
215    </property>
216    <field name="_observer"><![CDATA[({
217        _self: this,
218            observe: function(aSubject, aTopic, aPrefName) {
219            if (this._self._prefroot.getBoolPref("extensions.virtualIdentity.show_smtp"))
220                this._self.removeAttribute("hidden")
221            else    this._self.setAttribute("hidden","true")
222        }
223        })]]></field>
224    <field name="_prefroot">Components.classes["@mozilla.org/preferences-service;1"]
225            .getService(Components.interfaces.nsIPrefService)
226            .getBranch(null).QueryInterface(Components.interfaces.nsIPrefBranch2)</field>
227    <field name="_smtpPopup">document.getAnonymousElementByAttribute(this, "anonid", "smtp_server_list_popup")</field>
228    <field name="_smtpMenu">document.getAnonymousElementByAttribute(this, "anonid", "smtpServerMenuList")</field>
229    <field name="_smtpService"></field>
230
231    </implementation>
232    </binding>
233   
234   
235   
236   
237    <binding id="fromMenuList_clone" display="xul:menu" extends="chrome://global/content/bindings/menulist.xml#menulist-description">
238    <resources>
239            <stylesheet src="chrome://global/skin/menu.css"/>
240    </resources>
241    <content sizetopopup="pref">
242        <xul:hbox anonid="contentHBox" flex="1"  >
243                <xul:vbox><xul:spacer flex="1" />
244                    <xul:image class="menulist_clone-icon" id="msgIdentity_clone_image" xbl:inherits="src"/>
245                <xul:spacer flex="1" /></xul:vbox>
246                <xul:vbox flex="1"><xul:spacer flex="1" />
247                    <xul:textbox anonid="textBox" type="search" id="msgIdentity_clonetextBoxElem" class="plain menulist_clone-textbox" xbl:inherits="value=label,crop,accesskey,vid" allowevents="true" oncommand="event.stopPropagation();document.getBindingParent(this).inputEvent();" crop="right" />
248                <xul:spacer flex="1" /></xul:vbox>
249            <xul:vbox><xul:spacer flex="1" />
250                <xul:hbox>
251                    <xul:label value="&vident.accPane.prettyName.prefix;" class="menu_clone-description virtIdLabel" xbl:inherits="vid" crop="right"/>
252                    <xul:label id="msgIdentity_clone_label" class="menu_clone-description" xbl:inherits="value=description" crop="right"/>
253                    <xul:label id="msgIdentity_base_id_label" class="menu_clone-description" xbl:inherits="value,hidden=base_id_key_hidden" crop="right" hidden="true"/>
254                </xul:hbox>
255            <xul:spacer flex="1" /></xul:vbox>
256        </xul:hbox>
257        <xul:hbox oncommand="event.stopPropagation();document.getBindingParent(this).smtp = this.smtp" anonid="smtpServerListHbox" class="smtpServerListHbox" />
258        <children />
259    </content>
260        <implementation>
261    <constructor>
262        <![CDATA[       
263        var inputTextbox = document.getAnonymousElementByAttribute(this, "class", "plain menulist_clone-textbox");
264       
265        // check if 'search' textboxes are implemented, if not change to 'timed'
266        if (!inputTextbox.timeout) inputTextbox.setAttribute("type", "timed");
267        inputTextbox.setAttribute("timeout", "300")
268       
269        this._msgIdentityElem.setAttribute("hidden", "true");
270        this._msgIdentityElem.previousSibling.setAttribute("control", "msgIdentity_clone");
271        ]]>
272    </constructor>
273    <destructor>
274        <![CDATA[
275        document.getElementById("vI_tooltipPopupset")
276            .removeTooltip(this.getAttribute("tooltip"));
277        ]]>
278    </destructor>
279
280    <!--
281    double the Identity-Select Dropdown-Menu to be more flexible with modifying it
282    the original Identity Dropdown Menu is hidden and stores the base Identity, on which one
283    the Virtual Identity is build upon
284    -->
285    <method name="command">
286        <body><![CDATA[
287        this.identityData = this.selectedMenuItem.identityData.getDuplicate();
288        // clean reply-to fields before reinit
289        vI_msgIdentityCloneTools.cleanupReplyTo();
290        // set orignal Identity-Menu to the selected Identity
291        vI_msgIdentityCloneTools.copySelectedIdentity(this.value);
292        // recognize reply-to fields for auto-reply
293        vI_msgIdentityCloneTools.initReplyToFields(this.value);
294        ]]></body>
295    </method>   
296    <method name="init">
297        <body><![CDATA[
298        vI_notificationBar.dump("** v_identity.xml: clone_Obj_MsgIdentity\n");
299       
300        this.dontInitExtras = true;
301        var MenuItems = this._msgIdentityPopupElem.childNodes
302        for (var index = 0; index < MenuItems.length; index++) {
303            var identity = gAccountManager.getIdentity(MenuItems[index].getAttribute("value"));
304           
305            var newExtras = new vI_storageExtras(); newExtras.readValues();
306            var newIdentity = new identityData( identity.email, identity.fullName, identity.key,
307                                identity.smtpServerKey, newExtras,
308                                vI_helper.getAccountname(MenuItems[index]))
309
310            var menuItem = this.addIdentityToCloneMenu(newIdentity)
311
312            if (this._msgIdentity_selectedItem == MenuItems[index]) {
313                this.selectedItem = menuItem;
314                vI_notificationBar.dump("** v_identity.xml: clone_Obj_MsgIdentity selectedMenuItem " + menuItem.value + " found\n");
315                this.identityData = newIdentity.getDuplicate();
316            }
317        }
318        this._popupMenu_separator = true;
319        this.dontInitExtras = false;
320       
321        vI_msgIdentityCloneTools.initReplyToFields(this.value);
322        ]]></body>
323    </method>
324    <method name="clean">
325        <body><![CDATA[
326        vI_notificationBar.dump("** v_identity.xml: clean\n");
327        var MenuItems = this._popupElem.childNodes;
328        while (MenuItems.length > 0) {
329            try {MenuItems[0].clean();} catch (e) { };
330            this._popupElem.removeChild(MenuItems[0])
331        }
332        this.selectedItem = null;
333        ]]></body>
334    </method>   
335    <method name="addIdentityToCloneMenu">
336        <parameter name="localIdentityData" />
337        <body><![CDATA[
338        vI_notificationBar.dump("** v_identity.xml: addIdentityToCloneMenu '" + localIdentityData.id + "'\n");
339       
340        var existingItem = this._isExistingCloneMenuItem(localIdentityData);
341        if (!existingItem) {
342            var MenuItem = document.createElement("menuitem");
343                MenuItem.identityData = localIdentityData;
344            MenuItem.setAttribute("class", "identity_clone-popup-item");
345            MenuItem.value = localIdentityData.id;
346
347            // set vid explicitely
348            if (this._popupMenu_separator) MenuItem.setAttribute("vid", "true");
349            else    MenuItem.setAttribute("vid", "false");
350                       
351            this._popupElem.appendChild(MenuItem);
352            return MenuItem;
353        }
354        else return existingItem;
355        ]]></body>
356    </method>
357    <method name="addIdentitiesToCloneMenu">
358        <parameter name="identityCollection" />
359        <body><![CDATA[
360        for (var index = 0; index < identityCollection.number; index++)
361            identityCollection.menuItems[index] =
362                this.addIdentityToCloneMenu(identityCollection.identityDataCollection[index])
363        ]]></body>
364    </method>
365    <method name="_getMenuItemForIdentity">
366        <parameter name="identitykey" />
367        <body><![CDATA[
368        var MenuItems = this._popupElem.childNodes;
369        vI_notificationBar.dump("** v_identity.xml: getMenuItemForIdentity key " + identitykey + " menulength " + MenuItems.length + "\n");
370        for (var index = 0; index < MenuItems.length; index++) {
371            if (MenuItems[index].value == identitykey)
372                return MenuItems[index]
373        }
374        return null;
375        ]]></body>
376    </method>
377    <property name="_popupMenu_separator" >
378        <getter><![CDATA[
379            if (this._menu_separator) this._menu_separator.removeAttribute("hidden");
380            return this._menu_separator;
381        ]]></getter>
382        <setter><![CDATA[
383            if (!val) return;
384            // add hidden separator as indicator that now only virtual identities are added
385            this._menu_separator = document.createElement("menuseparator");
386            this._menu_separator.setAttribute("id", "vid_separator");
387            this._menu_separator.setAttribute("hidden", "true");
388            this._popupElem.appendChild(this._menu_separator)
389        ]]></setter>   
390    </property>
391    <property name="selectedMenuItem" >
392        <getter><![CDATA[
393            return this.selectedItem;
394        ]]></getter>
395        <setter><![CDATA[
396            if (typeof(val) == "object") this.selectedItem = val
397            else if (val == "default")
398                this.selectedItem = this._getMenuItemForIdentity(gAccountManager.defaultAccount.defaultIdentity.key)
399            else this.selectedItem = this._getMenuItemForIdentity(val)
400            this.doCommand();
401        ]]></setter>   
402    </property>
403    <method name="_isExistingCloneMenuItem">
404        <parameter name="localIdentityData" />
405        <body><![CDATA[
406        vI_notificationBar.dump("** _isExistingCloneMenuItem\n");
407           
408        var MenuItems = this._popupElem.childNodes
409        for (var j = 0; j < MenuItems.length; j++) {
410            if (MenuItems[j].localName == "menuseparator") continue;
411            vI_notificationBar.dump("** comparing id " + MenuItems[j].identityData.id + " with " + localIdentityData.id + "\n");
412            if (MenuItems[j].identityData.equals(localIdentityData)) {
413                vI_notificationBar.dump("** _isExistingCloneMenuItem: found existing one\n");
414                return MenuItems[j];
415            }
416        }
417        vI_notificationBar.dump("** _isExistingCloneMenuItem: none found\n");
418        return null;
419        ]]></body>
420    </method>
421    <field name="_msgIdentityElem">document.getElementById("msgIdentity")</field>
422    <field name="_msgIdentityPopupElem">document.getElementById("msgIdentityPopup")</field>
423    <property name="_msgIdentity_selectedItem" >
424        <getter><![CDATA[
425            if (!this._msgIdentityElem.selectedItem) {
426                vI_notificationBar.dump("** v_identity.xml: msgIdentityElem.selectedItem not set, using first Menuitem\n");
427                this._msgIdentityElem.selectedItem = this._msgIdentityPopupElem.firstChild
428                vI_notificationBar.dump("** v_identity.xml: msgIdentityElem.doCommand()\n");
429                this._msgIdentityElem.doCommand();
430            }
431            return this._msgIdentityElem.selectedItem;
432        ]]></getter>
433    </property>
434   
435    <method name="inputEvent">
436            <body><![CDATA[     
437        this.identityData.combinedName = this.label;
438        this.label = this.identityData.combinedName; // reset to possibly changed value
439        this.setAttribute("label", this.label);
440       
441        this.tooltipElem.setAttribute("tooltip",
442            document.getElementById("vI_tooltipPopupset")
443            .addTooltip(this._identityDataStorage, this.tooltipElem.getAttribute("tooltip")));
444
445        var existingIdentity = this.checkForVirtualIdentity();
446        if (existingIdentity) this.selectedMenuItem = existingIdentity;
447       
448        vI_msgIdentityCloneTools.updateReplyTo();
449        ]]></body>
450    </method>
451    <method name="checkForVirtualIdentity">
452        <body><![CDATA[
453        var existingIdentity = this.identityData.isExistingIdentity();
454        if (!existingIdentity) { this.vid = true; vI_msgIdentityCloneTools.updateReplyTo(); }
455        else this.vid = false;
456       
457        vI_msgIdentityCloneTools.signatureSwitch(existingIdentity);
458       
459        return existingIdentity;
460        ]]></body>
461    </method>
462    <property name="smtp" onget="return this.identityData.smtp;" >
463        <setter><![CDATA[
464        this.identityData.smtp = val;
465       
466        this.tooltipElem.setAttribute("tooltip",
467            document.getElementById("vI_tooltipPopupset")
468            .addTooltip(this._identityDataStorage, this.tooltipElem.getAttribute("tooltip")));
469
470        var existingIdentity = this.checkForVirtualIdentity();
471        if (existingIdentity) this.selectedMenuItem = existingIdentity;
472        ]]></setter>
473    </property>
474    <field name="dontInitExtras" />
475    <property name="identityData" onget="return this._identityDataStorage;" >
476        <setter><![CDATA[
477        vI_notificationBar.dump("** v_identity.xml: updating DataStorage.\n");
478        var oldIdentityData = this._identityDataStorage;
479        this._identityDataStorage = val;       
480        if (!this._identityDataStorage.id) {
481            this._identityDataStorage.id = oldIdentityData.id;
482            var idName = this._identityDataStorage.idName;
483            this._identityDataStorage.sideDescription = (idName)?" - "+idName:"";
484        }
485        this.label = this._identityDataStorage.combinedName;
486        this.value = this._identityDataStorage.id;
487        this.description = this._identityDataStorage.sideDescription;
488        document.getAnonymousElementByAttribute(this, "anonid", "smtpServerListHbox").smtp = this._identityDataStorage.smtp;
489       
490        if (!this.dontInitExtras && this._identityDataStorage.extras) {
491            vI_notificationBar.dump("** v_identity.xml: set extra Values\n");
492            this._identityDataStorage.extras.setValues();
493        }
494        if (!this._identityDataStorage.extras)
495            this._identityDataStorage.extras = new vI_storageExtras();
496       
497        vI_notificationBar.dump("** v_identity.xml: read extra Values\n");
498        this._identityDataStorage.extras.readValues(); // fill in the missing Values
499       
500        this.checkForVirtualIdentity();
501       
502        this.tooltipElem.setAttribute("tooltip",
503            document.getElementById("vI_tooltipPopupset")
504            .addTooltip(this._identityDataStorage, this.tooltipElem.getAttribute("tooltip")));
505       
506        vI_notificationBar.dump("** v_identity.xml: updating DataStorage done.\n");
507        ]]></setter>
508    </property>
509    <field name="_popupElem">document.getElementById("msgIdentityPopup_clone")</field>
510    <field name="tooltipElem">document.getAnonymousElementByAttribute(this, "anonid", "contentHBox")</field>
511    <field name="textBoxElem">document.getAnonymousElementByAttribute(this, "anonid", "textBox");</field>
512    <property name="email" onset="this.identityData.email = val; this.label = this.identityData.combinedName; this.inputEvent()" />
513    <property name="vid" onget="return (this.getAttribute('vid') == 'true');" onset="this.setAttribute('vid',val?'true':'false'); return val;" />
514    <property name="label" onget="return this.textBoxElem.value;" onset="this.textBoxElem.value = val; return val;" />
515    <property name="value" onget="return this.getAttribute('value');" onset="this.setAttribute('value', val); return val;" />
516    <property name="extras" onget="return this.identityData.extras;" />
517    <property name="description" onget="return this.getAttribute('description');" onset="this.setAttribute('description', val); return val;" />
518    </implementation>
519    </binding>
520</bindings>
Note: See TracBrowser for help on using the repository browser.