Community Bar Panel API
V1.0
Matthew Richardson (mattri@microsoft.com)
The purpose of this document is to assist in the writing of panels for the Community Bar. It begins with some introduction and simple examples, but also contains a reference section near the end for anyone already familiar with it.
A Community Bar panel is simply a small web page which is designed to react to user events such as navigating the browser to a new page, resizing the window, etc.
The easiest way to get started is to look at an existing panel. Take, for instance, the panel which displays the pages which link to a given page. The following is the entirety of the panel:
<html>
<head>
<title>Inlinks</title>
<link rel="stylesheet" href="http://communitybar.net/api/Panel.css " />
<script type="text/javascript" src="http://communitybar.net/api/Panel.js"></script>
</head>
<body class="ScrollPanel">
<script type="text/javascript">
function UserNavigated(url)
{
if (url == null)
inlinksList.innerHTML = "";
else
cbar.BeginRetrieve("InlinkServer.aspx?url="+encodeURIComponent(url), RetrieveComplete, null);
}
function RetrieveComplete(str, userdata)
{
inlinksList.innerHTML = str;
}
</script>
<div class="inlinksList" id="inlinksList"></div>
</body>
</html>
As you can see, it’s just an HTML page with some special scripting and styling. We’ll go through the items line by line now:
<link rel="stylesheet" href="http://communitybar.net/api/Panel.css " />
This defines some styles that are useful for panels. It is highly recommended you include this file so that your panel has a similar look and feel to other panels.
<script type="text/javascript" src="http://communitybar.net/api/Panel.js" />
This javascript file provides your panel with the ability to be notified when events occur, such as when the user browses to a new location. It also allows you to interact with the “ICommunityBar” interface for retrieving pages, etc.
<body class="ScrollPanel">
This sets up the body so that it always has a scrollbar. The other choices are “NoScrollPanel”, which never has a scrollbar, and “Panel” which has the scrollbar appear when there is too much content to fill the panel.
function UserNavigated(url)
{
if (url == null)
inlinksList.innerHTML = "";
else
cbar.BeginRetrieve("InlinkServer.aspx?url="+encodeURIComponent(url), RetrieveComplete, null);
}
function RetrieveComplete(str, userdata)
{
inlinksList.innerHTML = str;
}
The UserNavigated function is called whenever the user has clicked on a link in the main window (the portion of the browser that is not displaying the community bar). It is passed the new URL (encoded using URL-encoding). This is your panel’s opportunity to update its content with whatever it wants to display for the new url. If the user browsed to a
sensitive URL, such as a secure (https) page, the url you are provided in this function is null. This allows your panel to make it clear that it is not showing content related to the secure page.
Often, panels must fetch content from a Web service. In order to retrieve content from the web, use the provided cbar object, which is of class ICommunityBar (see reference section). This allows you to retrieve the contents of URLs. In this case, the call to BeginRetrieve requests data from the URL “InlinkServer.aspx?url=ZZZ”, specifying RetrieveComplete to be called when the content is done downloading. RetrieveComplete will be called with str set to the contents of the url, and userdata set to the third parameter of BeginRetrieve (in this case, null). In this case, it simply inserts whatever was returned by InlinkServer.aspx into the div named “inlinksList”.
That’s it. The InlinkServer.aspx is a ASP.NET program which takes the URL on the command line and returns the list of pages that point to it, which some nice HTML formatting on them. Alternatively, it could have been written to return the inlinks list in XML format, and the panel could have rendered it however it pleased in to the appropriate display format (for this, we would have used BeginRetrieveXML instead, which returns an XML DOM object).
The user has the ability to manipulate a panel’s height and width. For most well-designed panels, the HTML will automatically layout nicely depending on the size of the panel. However, there are times when it is necessary or advantageous to react to your panel changing size. The functions UserResizing and UserResized will be called, if they exist in your panel, to inform you that the user is adjusting, or has adjusted the height of your panel. At the moment, you are not informed when the user adjusts the width of the panel. The functions take no parameters – a panel can determine its own height by checking document.body.clientHeight.
By default, if the user clicks on a link or button in your panel, the browser will load the new page within the panel. Often, a panel would like the link to be opened in the main window. To do this, add the attribute target=mainWnd to the link. If the panel needs to programmatically cause the main window to navigate to a new URL, call the NavigateInMainWindow method of cbar. The former is preferred to the later so that users may open links in a new window if they desire.
When the panel is first loaded, the cbar object is not yet initialized. The Community Bar guarantees that any of the IPanel routines (UserNavigated, UserResized, …) will only be called after cbar is initialized. However, if you have GUI elements which react to user behavior directly and use the cbar object, you must check whether CbarInitialized() is true first.
To publish your panel, first add it to your own settings page. You can do this by visiting your settings page and clicking on the button to expand the “Custom panel” section. Enter the URL of your panel, the title, a description, and optionally your home page. This information will be seen by anyone who adds your panel to their list of custom panels. Click the Add button, and verify that your panel works as expected in your community bar.
Other users may add your panel by clicking on the following URL:
http://www.communitybar.net/Settings?add=<YOUR PANEL URL>.
Never do something which causes a pause in the execution of your script. This will cause the user’s browser to lock up. Whenever you retrieve data from the network, use the provided asynchronous routines (BeginRetrieve and BeginRetrieveXML).
The panel should attempt to look good at various widths and heights. Use HTML’s ability to layout for different sized windows to your advantage to automatically handle width adjustments. If necessary, you can execute script when the user resizes the panel’s height, but if possible try to avoid this and depend on the HTML rendering of the panel instead.
Remember that panels are displayed in a small area. Try not to waste space with extraneous buttons, large text, etc. The user will appreciate a panel that conveys its information in as little space as possible. Also, different users have different sized screens, so try to design the panel to look good at a variety of sizes.
When creating a link which should affect the main window, use the target=mainWnd method, rather than linking to a javascript which calls cbar.NavigateInMainWindow(). This way, the user can choose to open the link in a new window if so desired.
If you include panels.js, you can access any of these routines as a method of the object cbar
|
BeginRetrieve(url, completionCallback, data) Asynchronously retrieves the contents of a given URL.
|
|
|
url |
The URL to retrieve
|
|
completionCallback |
This function will be called when the URL has been retrieved. The callback has the following prototype: completionCallback(str, data) where str is the complete contents of the URL, and data is what was provided as the third argument to BeginRetrieve.
|
|
data |
Arbitrary object which will be passed as the second argument of the completionCallback |
|
BeginRetrieveXML(url, completionCallback, data) Asynchronously retrieves the given URL and parses it into an XML DOM
|
|
|
url |
The URL to retrieve
|
|
completionCallback |
This function will be called when the URL has been retrieved. The callback has the following prototype: completionCallback(xml, data) where xml is the XML DOM of the URL, and data is what was provided as the third argument to BeginRetrieveXML.
|
|
data |
Arbitrary object which will be passed as the second argument of the completionCallback |
|
GetCurrentUrl() Returns the URL that the user is currently viewing in the main window.
|
|
NavigateInMainWindow(url) Causes the main window of the browser to go to the url specified. This should only be used in reaction to a user activity, so as not to interrupt their normal browsing expectations.
|
|
|
url |
The URL to navigate to |
If these functions exist in your panel, they will be called by the Community Bar to inform you of the specified events.
|
UserNavigated(url) The user has clicked on a link or typed a new URL in the browser address bar. The url parameter is the url that the user is navigating to. This is the URL the user entered or clicked on. (Note, this might not technically be a URL because the user may have entered or clicked on a link containing arbitrary characters). Some URLs (such as https: or file:) are filtered out. In this case, url will be null. In this case, we suggest blanking the panel to reflect to the user that it is no longer being applied to the user’s current URL.
|
|
VisibleChanged(bool visible) The user has closed or re-opened the community bar. When a panel is loaded, the community bar is visible to the user. If the user closes the community bar, the panel is still loaded and executing, but is now invisible to the user. Similarly, if the user re-opens the community bar, the panel is not reloaded, it is just now visible. Note: By design, when the community bar is not invisible, the panel will not receive any UserNavigated events. Thus, if your panel is idle other than reacting to that event, you will not need to provide a VisibleChanged method. However, if your panel performs tasks in the background, such as occasionally contacting a server to retrieve new content, playing music, etc, then you may want to modify your behavior when it is no longer visible to the user.
|
|
UserResizing() The user is changing the size of the panel (i.e. is dragging the resize manipulator, and has not released the mouse button yet)
|
|
UserResized() The user changed the size of the panel
|
When the community bar is closed or not visible, you will no longer receive events as the user browses