
|
Home |
Screenshots |
Installation |
Technical Overview |
Stories |
Feedback |
Contact |
Overview of Technical Information for the Fabula Project
This document is relevant for version 1.1 of the program. Some technical
information is available for version 1.0.
For a less technical overview, please see the Fabula Homepage.
Table of Contents
- Introduction
- Installation
- Source Code
- Stories
- The Fabula Reader
- The Fabula Maker
- Localisation
- Modifying the Code
- Getting Involved
- Links
Introduction
When Fabula was first conceived back in 1998, XML Workshop had the foresight to see that Mozilla* would be an ideal solution. Back then, Mozilla was in its infancy and working with it was quite hard, as the browser was still full of bugs. Since then, Mozilla has matured nicely, and as it turns out is the perfect platform for Fabula. Mozilla is very XML compliant, and XML forms the basis for file saving and sharing in Fabula. Mozilla is also cross-platform, so without a lot of work, Fabula can be ported to other platforms. Windows is the principle development plaform, although Macintosh computers are also quite popular in schools, which is the target audience. In fact, linux is also an important platform, as it has been speculated that Fabula can be extended to other languages in third-world countries, where linux, as a free OS, is more popular
Installation
Every package addon to Mozilla is available as an XPI file (XPI stands for Cross Platform Installer). Fabula is split into 2 XPI files, the Maker and the Reader. An XPI file is simply another zip file with the reader/maker.jar file and an install script install.js. When an XPI is opened by Mozilla or called with the InstallTrigger() function, Mozilla unzips the XPI file and runs the install.js script, which registers the chrome and copies the jar file to the chrome subdirectory of Mozilla. Mozilla must be restarted before this chrome is available. The install.js script included with the Maker and Reader is quite rudimentary, and there are better ones available from mozdev.org which should be implemented in future versions. Once the Maker or Reader is successfully installed, there are two ways to run the Maker or Reader:
- Start Mozilla from the command line like so:
mozilla -console -chrome chrome://maker/content
This is a more elegant approach and it shows what the Maker/Reader should look like in the final version. (The -console option opens the Mozilla console to print debugging information). - Start Mozilla as usual and type the following into the url bar:
chrome://maker/content
This is quite an ugly way to see fabula, but it is good for development as you can make a change to the Fabula source code and then hit refresh in the main Mozilla toolbar to see the changes (make sure you have "Disabled XUL-Cache" in the Mozilla debug options). - Actually, a third way has been mooted. It is possible for the install script to insert an item in the tasks menu of Mozilla, which would launch the Maker/Reader. This is detailed in bug #132.
Source Code
The very nature of the Mozilla front end programming language (XUL) is that it is open-source. So, if you have already downloaded Fabula, then you have the source code. Once you have successfully installed the Reader or the Maker, you will find a reader.jar or maker.jar file in the chrome directory of whereever you have installed Mozilla. These jar files are simply zip files which can be opened with Winzip or a similar unzipping program. You will see that the jar file consists of XUL(XML-Based User-Interface Language), JS(Javascript), DTD(Document Type Definition) and GIF(image files). The XUL files are used to describe the layout of Fabula (and all of Mozilla). There is a very good XUL tutorial over at xulplanet. The javascript is the javascript we all know and love, but with DOM extensions. There are more details of Mozilla's javascript engine here. DTDs descibe the locales, ie. the different languages that Fabula has been made into.
The best documentation is the source code, as most of it has been commented. If you really want to find out how fabula does something, read the source code, as it goes into far more detail than I do here. It is also beneficial to download the Mozilla source code (or view it online), and in particular the idl files which provide access to a lot of Mozilla lowlevel functions via the Javascript XPCOM.
Stories
Fabula is all about stories, Making and Reading stories. Stories are stored in XML format, using a story dtd that was developed specially. Examples of elements in our story document are: <lang1>, <audio>, <wordlist>, etc. For a full set, open up a sample story from the library. A drawback to the current method of saving (as used in v1.1), is that the stories are also saved in html format. This is necessary in order to reopen the story in the Maker, as the Mozilla Editor (which forms the backend for the Maker) cannot open XML files directly. A solution to this has been discover, but won't be available until a later version (see bug #138** for more details of this solution.
Stories are rendered in the Maker and Reader by CSS, which Mozilla supports (CSS 2.0 in fact). See the reader-story.css and maker-story.css files for details on how stories are rendered. Note: the XUL files for rendering the user interface also use CSS.
The Fabula Maker also saves the XML file along with the html file. This XML file is for use with the Fabula Reader, which only opens XML files. All embedded images and sounds in the story are saved in images and sounds subdirectories of where the story XML file is, and all urls are relative to this. This is a rather messy solution, specially when it comes to distributing stories. A solution to this is detailed in bug #139, ie. to save the story and all embedded content in a zip file (.fab) using Mozilla's zip file api.
The Fabula Reader
The Fabula Reader is used for viewing existing stories. The Reader is intended for opening the story XML file only, however it is possible to open the accompaning html file (with nasty results!). The backend of the reader is Mozilla's navigator shell. Simply said, the Reader uses the standard Mozilla browser to open and view the XML file and images. Sounds are handled using the sound api functions of Mozilla. The wordgames in the stories are handled by Mozilla's support for xlink. The other elements of the Reader are handled by javascript manipulating the DOM (Document Object Model) of the XML file using Mozilla's inbuilt DOM support. A breakdown of the features follows:
- Opening File. Simply sets the location of the active document to the location of the XML story file you want to open.
- Images. Images are handled by embedded html <img> elements in the XML file.
- Sounds. Sounds are xlinks which trigger a javascript function to play the sound using Mozilla's sound api. Sounds can be accessed via the horn icon or by clicking on some pictures.
- Page Turning. Only one page at a time is displayed in the Reader. The whole XML document is loaded, but all other pages are set to "hidden". When the "Next Page" button is pressed, the javascript calls a DOM function to turn off the hidden attribute for the next page, and turn on the hidden attribute for the current page, thus giving the impression that the page has been turned.
- Wordgames. The wordgame is started and played with xlinks (fancy XML version of the standard html <a href> type tag). Again, the xlink simply fires up some javascript, which highlights different parts of the story in order to make a word matching game between the two languages.
- Wordlist. The wordlist is a dialog box that displays language word pairs for both languages in all the letters of the (English) alphabet. This dialog box words by calling the DOM function getChildNodes on the <wordlist> element (there is only one per story). The child nodes of wordlist are all word-pairs, which this dialog can then display, by altering the DOM attributes for the current XUL window (the wordlist window). Each time someone clicks a different letter, the words starting with that letter are displayed.
- Exiting. Exiting calls up a confirmation XUL dialog box, and if confirmed just closes the browser window (this.close()).
The Fabula Maker
The Fabula Maker uses the Mozilla Editor as its backend. This means that the user can type directly into the window and that the editor document is available to use, so we can use javascript to modify its DOM tree (via the editorshell - see editorshell.idl in the Mozilla source code for a full list of functions available). The editorshell provides access to functions like saving and setting the title of the document, as well as insert elements and sourcecode.
The Maker is a wysiwyg editor, which looks almost the same as the Reader, except you can scroll up and down to different pages. The default story in the Maker is MakerInitPage.html. In most cases, editing stuff in the Maker will give you direct feedback to what that looks like in the Reader. The Maker saves the story in both html (in order to reopen in the Maker) and XML (in order to open in the Reader) formats. It saves/copies the images and sounds in a subdirectory of the html/xml story file. A breakdown of the main features/functions in the Maker follows:
- New Story. Opens a new browser window and loads the Maker chrome into it.
- Opening. Uses the open function in the editorshell.
- Saving. Uses the save/save as function in the editorshell. Uses the file.js file i/o library to save the XML file. The XML file is constructed from the html DOM tree using the t2s.js file, which converts a DOM tree to a string (which can then be written to a file), and also does some translation to our XML story format, eg. <img> becomes <html:img>. After that, any sounds or images are copied to subdirectories of the XML file and their URLs changed to relative. Note: by default, the editorshell asks for the title of the page, which we discard in the XML file.
- New Page. Uses the DOM cloneNode() function to copy the hidden page (which is at the end of every story). Then sets the page to not hidden.
- Insert Image. (Clicking button or clicking image will bring up this dialog). Images are already inserted on every page by default, so this dialog just changes the src attribute or this. It also inserts an xlink around the image if a hotspot sound is required. It detects the current page using the shared getPage() function, which is used throughout the maker.
- Insert Sound. Creates a new sound element before each language panel and displays them as an image in CSS. Also wraps an xlink around this, which allows playing of the sound.
- Wordlist. When this dialog opens, it checks to see if there are already words defined in the story file (in a similar manner to the reader wordlist dialog above). To add more words, this dialog clones existing words in the list, if any (actually, every story has 1 hidden word, so that others can be cloned).
- Connections. This is probably the most complicated of functions in the Maker. The first dialog is a list of connections for the current page, in which you can add or remove. The add connection dialog asks for a word from each language panel (the javascript gets the selection using the editorshell getSelection() method), and then does the appropriate DOM manipulation to wrap the connected words with an xlink and to insert the connections icon, etc. Full documentation for this, like others, is in the source code.
- Outline View. Outline view is achieved by switching the style sheet for the story so that each page is a lot smaller and is displayed 3 across. This is done using the applystylesheet() function in the editorshell. We also need to do some fancy manipulation of <br>s in order to get 3 across in a row.
- Preview. Preview mode opens a new Mozilla window with the Reader chrome as default. It passes the url of the story as an argument to the openDialog() function. The preview function saves the story first.
- Undo/Redo. Call editorshell functions.
- Insert Extra Letters. This allows for the insertion of special characters into the story. The dialog is opened as non-modal, so the user can type at the same time as having it open. This dialog calls the insertSource() method of editorshell. Note: adding a new character in this dialog requires you add the corresponding code in t2s.js
- Other. There are numerous other undocumented features of the Maker (eg. trying to delete a language panel automatically undoes the change). Some of these are documented through bugula and others through the source code, however a sizable number of the 10,000+ lines of code in Fabula is largely undocumented and is therefore not easily maintainable. Unfortunately, as Mozilla is still a development platform, some of the darker recesses of Fabula are not for the faint hearted. However, XUL and Javascript is pleasantly easy to understand, so we're half way there!
Most of this functions are available via the toolbar, menus or popup menu.
Localisation
Fabula has been localised into 9 different languages. The Fabula Reader is available in English, French, Dutch, Spanish, Welsh, Irish, Basque, Frisian and Catalan. The Fabula Maker is currently only available in English, French, Dutch, Spanish, Welsh and Frisian, but the other languages are planned.
For verion 1.1, each language is in a separate XPI file. However, Mozilla supports multiple languages in the same chrome, but this has to be implemented in Fabula, together with a language switcher (see bug #30.
Modifying the Code
Modifying the code can be cumbersome, as one must zip up the source tree as a jar file and copy it to the Mozilla chrome directory everytime (although this is probably no more complicated than having to compile a program before running it). I recommend using a batch file (there is a sample one included in the reader.jar file) or a shell script (here is an example of one). Make sure the batch/script zips the source tree up like this:
- content subdirectory of zip file containing mostly XUL and JS files.
- skin subdirectory of zip file containing mostly CSS and image files.
- locale subdirectory of zip file containing all locales for package.
- en-US subdirectory of locale containg English DTDs and property file.
- Other locales are called (although this isn't implemented in v1.1 - instead each language is a separate file with the language in en-US):
- fr French
- nl Dutch
- es Spanish
- cy Welsh
- fr Frisian
- ca Catalan
- eu Basque
- ga Irish
So, to recap, if you edit a XUL,JS,DTD, or any file, you must zip up the content tree as a jar and copy it over the maker.jar or reader.jar file in the Mozilla chrome directory. Make sure the zip file preserves the reletive directory structure as described above.
Getting Involved
Any one can make changes to the Fabula source code, but if you would really like to contribute to the project as a whole, let us know and we can tell you what you can do.
There are plenty of bugs/features to fix/implement and a shortage of people to fix them! If you would like to get involved, please mail the Fabula Developer Mailing List or alternatively Eoin Campbell, the technical supervisor.
Links
- fabula.mozdev.org Fabula developer resources.
- fabula.eu.org The website for fabula resources.
- XML Workshop The intitial (technical) developers of Fabula.
- Mozilla.org Where is all started.
- Bugzilla The bug-tracking system for Mozilla. If something that should work, doesn't, check if it's listed here.
- LXR The Mozilla source code.
- Bugula The bug-tracking system for Fabula. Developer password needed.
- xulplanet XUL resources.
- Mozdev.org A database for other Mozilla-based projects. A good place to find code samples.
Footnotes
* Mozilla is the term used in this document for the Mozilla open source browser. However, Netscape 6 and others are based on Mozilla and may be able to run Fabula.
** Bugs are recorded in bugula, which requires a username and password, which are only available to developers of Fabula
Author: David McNamara, Date: Monday February 5th, 2001