Architecture

Structure

The following describes the core files and directories included in the Sidebar gadget. Not all files are explained here, for simplicity.
  • css -- Contains all CSS files
  • img -- Contains all images
  • js -- Contains all JavaScript files
  • main.htm -- Main view
  • message.htm -- New message fly-out
  • settings.htm -- Settings
  • gadget.xml -- Standard gadget manifest file

Design Decisions

Gadget Properties

The following gadget properties are used within Chirpr.
Property Description
tUserName User name of the user connecting to the Twitter service
tPassword Password of the user connecting to the Twitter service
toUser User name of the target user, when replying to a message
displaySize Height, in pixels, of the gadget

Handling Quotes

Due to issues with the Twitter service, double quotes (") cannot be sent in messages. To work around this, Chirpr replaces double quotes with the single quote/tick (') character.

Object Structure

Chirpr is built around three core JavaScript objects, each with a specific focus: chirpr, page, and util.

chirpr / chirpr.js

chirpr contains the core interaction and business logic. It consists of sub-classes for specialized functionality along with cached user settings, a credential-check (chirpr.hasCredentials(), and initialization function (chirpr.init()). The two most important things to remember when interacting with the chirpr.js page are that (1) it automatically calls chirpr.init() when the page is done loading (body.onload); and, (2) it calls page.init(), whether it exists or not, which will cause an error, if it doesn't. We could do a simple check to prevent errors, but figured this was key to our architecture, so left it as is.
Class Description
pages Page name constants
host Properties and functions of the host (Sidebar or browser) (show/hide fly-out)
properties Functions and constants for dealing with persisted properties (get/set, sync with saved properties)
twitter All Twitter integration (sign in/out, get/send messages)

page / *.htm

Each page has its own page class, which handles the page processing. Due to this, there is only one standard thing about each implementation: they have a page.init() function.

util / util.js

Lastly, the util.js file contains utility functions, not specific to Chirpr. As with the chirpr class, this class has root and sub-classed functionality. At the root, the util.addHandler() function attaches a function to an event (i.e. having chirpr.init() called on body.onload). The rest of the class consists of the following sub-classes.
animator Performs positional animation of a "slide show" image (not sure how to describe it; look at busyIcon.png and you'll understand)
busyIcon Wraps the util.animator class calls specifically for the Chirpr busy icon (this isn't used yet; when it is, it will most likely be moved to the chirpr.host class)
http Exposes HTTP objects and performs standard HTTP calls
opacity Changes the opacity of an item
scrolling Performs automatic and one-time scrolling
string String functions (isEmpty)
textarea Adds automatic word-counting support to a <textarea> control

Call Hierarchy

The following is a hierarchy of all calls made by all pages, as initiated by the Chirpr runtime. This happens automatically when including the chirpr.js file.
  • chirpr.js
    • util.addHandler -- attaches chirpr.init to the document.onload event
    • document.onload
      • chirpr.properties.sync -- synchronizes in-memory object with data store
        • chirpr.properties.get
      • page.init

NOTE: chirpr.init assumes there is a page class and that it has a page.init function.

As mentioned, the above calls are made on every page. The following is a list of page-specific calls.
  • Main View
    • page.init
      • page.resize -- ensures the page size is initialized to the last-saved value
        • chirpr.properties.set -- saves new page size
      • util.addHandler -- browser only attaches window blur/focus event handlers to test visibility changes
      • page.alerts.show -- welcome message
        • page.alerts.show -- if an alert has multiple messages (due to size limitations), a timeout loops thru each message
      • page.load
        • chirpr.hasCredentials
        • page.load ... -- if no credentials have been obtained, a timeout loops until they have been provided
          • page.updateMessages
            • page.alerts.show ... -- shows standard alerts to user informing him/her of status changes
            • page.__getMessages
              • chirpr.twitter.getMessages
                • util.http.get
                  • util.http.send
              • page.__getErrorHtml -- converts HTTP error code to friendly error message
            • page.__renderMessages
              • page.__fixDateFormat
              • page.__getMessageHtml
                • page.__formatDate
                • page.__formatText
            • page.updateMessages ... -- update at the configured refresh interval, if the refresh flag is set
    • Refresh image click
      • page.updateMessages ... -- update messages without refresh
    • New chirp or user name link click
      • page.__newMessage
        • chirpr.host.showFlyout
    • Scroll up/down click
      • util.scrolling.scroll -- when scroll button is clicked
      • util.scrolling.start -- when mouse moves on scroll button
      • util.scrolling.stop -- when mouse moves off scroll button
  • New Message
    • page.init
      • util.textarea.register -- registers the textarea as a "managed" control (fancy talk for adding the word counting capability)
      • page.__getReplyToUser -- gets the user this is in reply to (if appropriate) and reconfigures the page accordingly
    • Post (chirp) link click
      • page.submit
        • chirpr.twitter.sendMessage
    • Cancel link click
      • page.cancel
        • chirpr.host.hideFlyout
  • Settings
    • page.init
      • util.string.isEmpty -- check string values for null/empty
    • OK button
      • page.__settingsClosing
        • page.isValid -- checks for required values
          • util.string.isEmpty -- checks username/password
        • chirpr.properties.set -- sets username/password

Debugging

To provide debugging support, all gadget API calls are wrapped by the chirpr JavaScript object. Thanks to this, the individual HTML files can be opened directly within a web browser. IE is recommended, since that is the rendering engine used to host the gadget. To specify gadget properties, use querystring parameters with the same name of the property you want to set (see Gadget Properties above for a list of the supported properties).

NOTE: To specify querystring parameters on files browsed to locally, you must specify the file: protocol (i.e. file:///c:/chirpr/main.htm?tUserName=flanakin)

In addition to the gadget properties, you can also work offline by using offline=true (case-sensitive).

Building/Packaging

There are two ways you can build/package Chirpr. The easiest way for most people will be to simply use what Windows gives you out of the box.
  1. Browse to the directory files are located in Windows Explorer
  2. Select all files and directories in the project root (i.e. css, img, js, main.htm, etc.)
  3. Right click and select Send To > Compressed (zipped) folder
  4. Rename file to chirpr.gadget (or custom name, ending in .gadget, if you do not want to override an existing gadget)
NOTE: If you install a gadget with a different file name, it will be treated as a different gadget. This is why Chirpr releases do not include version number.

Given the number of times you may have to go thru this process, we also have a build (more like packaging) script. This script requires PowerShell and, due to the zip API in Windows not being exposed, requires 7-zip (which is actually a much better packaging utility). The build process is simple, once you have PowerShell open in the directory it's located in:
  1. PS C:\chirpr> .\build.ps1
That's it! One additional step the build script does is update the version number. Before explaining how it works, you must understand the components of a version number: <major>.<minor>.<build>.<revision>. Not complicated, but important. Building with no parameters updates the revision (last) number. If you are building a higher-level release, specify the component you wish to change, 1 (major) thru 4 (revision). For instance, .\build.ps1 2 would change the version from 0.1.2.3 to 0.2.0.0.

Important
One issue with the build script is that, due to the method in which the gadget.xml file is updated, you must manually change the file type to UTF-8 w/ Signature. Not performing this step will cause the gadget not to load and not to get added to the list of available gadgets.

Last edited Oct 18, 2008 at 8:10 PM by flanakin, version 6

Comments

roncordell Oct 23, 2008 at 2:38 PM 
Stupid question - could you be more explicit on what you mean by changing the file type for the gadget.xml file?