[Zope-CVS] CVS: Packages/Moztop/doc - BasicArchitecture.txt:1.1 DatasourceManagers.txt:1.1 StyleGuide.txt:1.1
Paul Everitt
paul@zope.com
Thu, 30 Jan 2003 07:07:13 -0500
Update of /cvs-repository/Packages/Moztop/doc
In directory cvs.zope.org:/tmp/cvs-serv8040
Added Files:
BasicArchitecture.txt DatasourceManagers.txt StyleGuide.txt
Log Message:
Beginning of documentation on the architecture and coding
=== Added File Packages/Moztop/doc/BasicArchitecture.txt ===
Moztop Basic Architecture
This document is for people fairly new to XUL, chrome packages, and
RDF. It explains the layout of the chrome package, how the
JavaScript files get initialized, etc.
For information about the conventions used in the Moztop packages,
see StyleGuide.txt in this directory.
Chrome
The Moztop chrome package is laid out, like all Mozilla packages,
into three directories:
o content
o skin
o locale
Most of your action is in the content directory. In this directory
you will find some of the core files for Moztop:
o moztop.xul is the basic frame that loads all the overlays, core
stylesheets, core scripts, etc.
o moztop.js contains core initialization logic and perhaps some
global functions
o moztopOverlay.xul adds a Moztop entry in Mozilla's "Tools" menu
o global.js has constants used throughout the application *and
contains no functions*
All the real work in Moztop is done in the major overlay
directories. Each overlay directory corresponds to one of the major
boxes on the screen:
- Moztop, the entire frame
- Menu, the thing at the top
- Explorer, the thing on the left
- Content, the thing in the middle-right
- Status, the thing at the bottom
Each of these overlays also corresponds to a top-level directory in
'moztop/content'. This also means that each of these also have an
overlay loaded from moztop.xul.
This is discussed more in StyleGuide.txt under *chrome*.
Model
Moztop is driven by RDF. This means that some of the look-and-feel
of the interface is driven by data. This is very important, so it
rates a little background.
RDF isn't easy at all. It's quite abstract and debugging it is
hit-or-miss at best. However, it's extremely powerful, it's the
primary idea in building Mozilla applications, and it happens to be
the *exactly* the right idea for what we want to do long-term in
Moztop.
The essential idea is that we have an abstract representation of the
entire Moztop universe. Every kind of thing we want to use or
interact with in our Moztop univers has a place, a node, in this
abstract model.
For example, let's say there is such a thing as a "Folder". In
Zope, "Folder" is a first-class object that has metadata and
methods. In our abstract representation, the RDF model for Moztop,
"Folder" is a resource in the RDF graph. It has properties that we
can use for various purposes.
In Zope, we also have a bunch of objects that are instances of this
"Folder" object. In our Moztop RDF model, we can make resource
nodes for these instances. But, we can also draw a line from these
resources, back to the resource for Folder, and say "MyFolder is a
Folder." This lets us centralize all the information about Folders
and "inherit", in the RDF model, from a single resource.
There's one more part that makes this Moztop universe interesting.
RDF resources aren't really tied to a single Zope server. When I
put a resource like "Folder" into my Moztop universe, I'm making a
statement about an object that is the same for all of my Zope sites.
It doesn't matter if "MyFirstFolder" comes from a site in a '.org'
and "MySecondFolder" comes from a site in a '.com'. They both
contain an "assertion" that says: "Hey, I'm a Folder, and we all
know what that means."
But how does it actually know what that means? This is through
Mozilla's use of Universal Resource Names (URN). The URN for Folder
might look like 'urn:zope3:packages:core:folder:1.2'. This is an
identifier saying "In the core package of our Zope 3 universe, there
is a resource called folder with a version 1.2 that we are referring
to."
Once I have 'urn:zope3:packages:core:folder:1.2' in my little Moztop
universe, the RDF model, I can then say that 'MyFirstFolder' is a
Folder by including this statement::
<z3:resourcetype resource="urn:zope3:packages:core:folder:1.2"/>
Voila, 'MyFirstFolder' now gains all the properties defined
*centrally* by Folder, version 1.2.
This is a basic background on the Moztop RDF model. More specifics
about the conventions used are found in StyleGuide.txt under RDF.
=== Added File Packages/Moztop/doc/DatasourceManagers.txt ===
Datasource Managers
We use quite a few datasources in Moztop: sites, resouretypes,
tasks, log messages, etc.
To make life easier, we're using a JavaScript library called
rdfds.js from XUL Planet. It is indeed a big help. However, we
still have some repetitive work that is confusing, error-prone, and
a duplication:
o Grabbing the datasource from different scripts can be a lot of
work
o Doing common operations means duplicating effort
o Some things, such as grabbing the selected item in a tree, are
just plain no fun
o In some cases, we need to manage our own Flush, so that the
datasource is updated locally and remotely
To fill this need we have an approach called Datasource Managers.
Prototype
The basic idea is that we have a "class", or in JavaScript terms a
prototype. This "class" has a constructor, some "class" attributes,
and some "class" methods.
As an example, let's look at the LogManager. It's job is to
initialize an RDF datasource using RDFDataSource from rdfjs. It
then needs to attach it to the tree and accept new log messages.
Finally, it needs to handle displaying an individual log message
when someone double clicks on the log message summary in the tree.
Thus we have a Log Manager prototype. The constructor sets some
properties, such as which XUL element (in this case,
'logmessages-tree') displays the datasource. The constructor also
creates an instance of RDFDataSource, initializes the root node as a
sequence, attaches it to the tree, and rebuilds the tree.
The Log Manager also has a method for accepting new log messages.
When called, it will take the string arguments, create a new
RDFNode, attach it to the sequence (at the front), and fill in the
properties for the new resource.
The final major method for Log Manager is the 'viewSelectedMessage'.
When called, it grabs the tree, finds the selected resource, grabs
that resource from the datasource, and pops up a dialog box with the
text of the message.
Bootstrapping
There are two challenges in this approach. One, we need to create
the datasource only once, when Moztop itself is started. We
certainly don't want to create the datasource everytime the overlay
is displayed. Second, we want to call addMessage from any script in
Moztop.
Thus, moztop.js initializes a global variable called 'logmanager'.
However, it doesn't assign anything to this variable. In the
'initializeStatus' script in Statusbox.js, which is called from the
moztop initializer routine, we create an instance of the LogManager
prototype and assign it to the global variable.
Futures
o Extend RDFDataSource instead of creating our own prototype
o Create our own JS-based component using a wrapper
o Switch to an XBL approach, so that logic *and* UI are encapsulated
=== Added File Packages/Moztop/doc/StyleGuide.txt ===
Style Guide
This document provides the agreements and rules about "code" in
JavaScript, XUL, CSS, chrome, etc. Examples include:
o How many spaces to indent
o How to name functions
o Where do files go in the chrome layout
o Where to stick CSS
JavaScript
o Use four spaces to indent
o For functions, useCamelCase
o Always return something from your functions
o Never blindly handle an exception
o Don't shove things in the top-level moztop.js, try to use js files
in your overlay areas
o When talking to servers, use async communications
o Prototypes are good, read
http://www.kevlindev.com/tutorials/javascript/inheritance/ for a
background
o Comment single lines with // and blocks with /* */
o Comment as much as possible, using Python conventions (single line
comment under functions as docstring, etc.)
o Use double quotes instead of single quotes for values
Chrome
o The following are the major boxes on the screen:
- Moztop, the entire frame
- Menu, the thing at the top
- Explorer, the thing on the left
- Content, the thing in the middle-right
- Status, the thing at the bottom
o Each of these corresponds to a top-level directory in
moztop/content
o Each of these also have an overlay loaded from moztop.xul
o Each should have a same-named overlay file, such as
'Explorer/ExplorerOverlay.js'
o Each will probably have a same-named js file, such as
'Explorer/Explorer.js'
o This js file will probably have a same-named initializer function,
such as 'initExplorer' in its js file, such as
'Explorer/Explorer.js'
o This initializer is called from, errm (sound of punting)
somewhere. I don't know if it should go in the moztop.js (which
obviously means the initializer will be called when the main app
frame is built) or when the overlay is actually used.
XUL
o The choice of using 'dont-build-content' on templates like trees
has some effects. I've found that I don't use use this flag, as I
like to use the DOM Inspector (your true friend) for debugging.
o Try to let RDF drive style, using the "properties" element. This
lets people customize things by editing files in the "skin"
directory, as well as localize.
o Give your trees a consistent id, such as 'explorer-tree',
'logmessages-tree', etc.
RDF
o Pay attention to the URN structure. Its meaning is absolute.
o Don't stash data away in any directory other than the user's
profile directory.
o Use 'rdf:null' as your datasource in XUL and attach your
datasource via JS
o However, put the 'ref' in the XUL element, don't put that in JS
o The core namespace are: dublin core, ...
CSS
o Thou shalt not use 'style=' attributes in your XUL, unless you are
truly lazy and pathetic
o Try to avoid tossing everything in the global 'skin/moztop.css'
o Instead, try to create separate css files for your overlay, such
as 'skin/Explorer.css'
o There are rules associated with CSS selectors, described on
mozilla.org, that affect performance greatly