Calendar:Dev Guide
This page is a work in progress. It is eventually meant to replace the old Developer's Guide at http://www.mozilla.org/projects/calendar/dev_guide.html
Introduction
The Sunbird and Lightning code-bases can be roughly divided into the 'Front End', which corresponds to the XUL and js files that the user directly interacts with, and the 'Back End', which consists mainly of XPCOM components.
As is often the case with software code, the actual code is usually the best resource. There are a fair number of comments throughout the code that can help explain in greater detail what is going on. This page is merely meant to give a "bird's eye" view of the code-base, to help provide entry points for searches.
Folder Structure
All of the calendar-specific code lives in the calendar/ directory of the mozilla source tree. Within there:
- base/ is meant to contain all of the files that are shared by both Lightning and Sunbird. This rule is not strictly followed at this time though.
- base/content/ contains shared front-end code.
- base/public/ contains IDL files for all calendar-specific interfaces.
- base/src/ contains the actual code for all XPCOM components.
- import-export/ contains implementations of the import and export interfaces.
- lightning/ contains files specific to Lighting.
- locales/ contains the en-US strings. Alternative locales live in the /l10n repository.
- providers/ See the Providers section of this document.
- resources/ is the original front-end directory. Many front-end files live here.
- sunbird/ Sunbird specific files.
Front End
Start-up points: The front-end code in Sunbird begins to be called with the calendarInit() function in calendar.js. In Lightning, the ltnOnLoad() function in messenger-overlay-sidebar.js is registered as an onload listener. Note that backend components (especially the alarm-service) begin much earlier in the startup process.
Calendar Management
Note: See also the backend Providers section for information on what actually makes up a calendar object.
See also the backend calCalendarManager interface.
Sunbird
Within Sunbird, all of the calendars that the user subscribes to are placed in a listbox within a tab in the upper-left of the display (as specified in calendar.xul). The code that builds this listbox, as well as other related code (such as the code that controls calendar colors) may be found in calendarManagement.js.
Lightning
Within Lightning, all of the calendars that the user subscribes to are placed in a tree in the tabbox in the lower left of the display, as specified in messenger-overlay-siderbar.xul). The equivalent of Sunbird's calendarManagement.js is calendar-management.js.
Both Sunbird and Lightning use the Calendar Creation Wizard to provide the user with a way to create and subscribe to new calendars. It is defined in calendarCreation.xul and calendarCreation.js.
Both Sunbird and Lightning use the Calendar Properties dialog to allow the user to modify an existing calendar. It is defined in calendarProperties.xul and calendarProperties.js.
Task Lists
The current status of the task lists is under review.
Event Lists
The current status of the event lists (agenda-tree vs. unifinder) is under review.
The Views
Both Sunbird and Lightning use a deck to display a series of views. Each of these views implements the calIDecoratedView Interface. Each of these decorated views inherits from calendar-decorated-base.xml Within each of these decorated views is an embedded calICalendarView object.
Note: Only Sunbird implements the Multiweek view.
Navigation (next/prev) is controlled within the actual xml files. Switching of views, and interaction with exterior code is controlled (temporarily) in Sunbird by calendarWindow.js and in Lighting by parts of messenger-overlay-sidebar.js
Dialogs
The main dialog that users interact with is the event/task creation/modification dialog. This dialog is currently under review. Both Sunbird and Lightning offer publish dialogs as well, and these too are under review
Sunbird and Lightning share the event/task dialog. The dialog is defined in calendar-event-dialog.xul and calendar-event-dialog.js. It also relies on code in calendar-item-editing.js.
Sunbird and Lightning share the publishing dialog. The dialog is defined in publishDialog.xul and publishDialog.js. It also relies on code in publish.js
Sunbird
Sunbird also offers a goToDate dialog (goToDateDialog.xul and goToDateDialog.js) and a printing dialog (printDialog.xul and printDialog.js). Printing also relies on calPrintEngine.xul and calPrintEngine.js for actual print-previews.
Lightning
None.
See also the backend section on 'Events/Tasks'
Preferences
Sunbird
The files controlling Sunbird's preferences are all in the calendar/base/content/preferences/ folder.
Lighting
Lightning overlays a prefpane directly into Thunderbird's prefwindow. This prefpane is defined in lightning-preferences.xul and lightning-preferences.js
Alarms
The alarm system is currently undergoing a rewrite in Bug 298358.
The referenced bug is no longer active, as it has been marked resolved.
Other useful files
The calendarUtils.js file contains many common functions used in both Sunbird and Lightning. It also contains the code for guessing the system timezone that the user is in. Sunbird additionally offers a applicationUtil.js file that controls Sunbird specific utilities, such as opening the Extension/Theme managers.
Back End
The back-end of Lightning and Sunbird consists largely of a series of XPCOM components that have been designed specifically for calendar-related purposes. In most cases, these components implement a specific interface defined in an IDL file. All of these interface definitions reside in public/ and contain substantial documentation on their use and implementation. The back end is entirely shared between all calendar applications and extensions.
SQLite
Sunbird/Lightning are now using the new mozStorage system to keep track of the majority of user-entered information. There are several tables stored in the database. The tables concerning calendar locations and preferences are defined here and those concerning events in individual calendars are defined here.
Providers
There are currently 3 types of calendars that are available to the user, and 5 back-end types to support these. Each of these calendar types must implement the calICalendarProvider interface. Then, individual instances of a calICalendar object are created for each calendar the user subscribes to.
- Local Calendars use the mozStorage (sqLite) system. They are defined in calStorageCalendar.js.
- ICS (called "remote webdav" in the UI) calendars are defined in calICSCalendar.js They rely heavily on the calIICSService. With every ICS calendar a calMemeoryCalendar is also created, to help improve speed. ICS Calendars are built on top of the libical. component, which handles the lowest level parsing of ICS files. All interactions with libical should go through calICSService.
- Caldav (called "remote caldav" in the UI) calendars are defined in calDavCalendar.js.
Additionally, there is a special calendar type that has been created to reduce complexity the front-end code. Rarely will the front end code interact with any of these calendars directly. Instead, the calendar-management system will add and remove calendars from a calCompositeCalendar. This calendar contains a collection of all the active ("check-marked") calendars. Asking it for events will return all events in all active calendars that meet the criteria specified.
Events/Tasks
Events are defined in the calIEvent interface and tasks similarly defined in the calITodo interface. Each of these inherits from calIItemBase.
Additionally, events and tasks rely on the majority of other interfaces defined.
Build System
The build system is magic. Don't ask too many questions about it. Hopefully XULRunner will simplify things.
Filling .jars
During the build process, the jar.mn file in each directory of the calendar/ source is read. Files referenced in there are added to the appropriate jar. The syntax is fairly self-explanatory. Note, however, that whenever you wish to add new files to the code, you must add an appropriate line to the relevant jar.mn file.
Registering Components
(someone check me on this) Sunbird and Lighting only define 1 'real' component, in calItemModule.js. This module then creates on-the-fly factories for most of the other components used. To add a new component, you should add it to the array of components defined there. See the patch on Bug 298358 for an example of how to do this. Note that you'll also need to modify the jar.mn file for lightning, so that the component file can be added to the .xpi.