XUL Stuff
We are refactoring the entire webui section of the project to use nevow, nevow.livepage (on top of xmlhttp) and XUL served from the server.
Alternatives
Alternatives to livepage are straight xmlhttp, xmlrpc, XPCOM, and form posts. We originally looked at straight xmlhttp, but we would need to write a lot of JS and server code to implement a framework in which to use the XMLHTTP, when LivePage? has done this work for us.
Form posts means a lot of work remembering the state of the gui on the server. xmlrpc is a viable alternative. XPCOM is questionably stable and would make it much harder in the future should we be required to turn the application into a cross-network client/server app.
We chose livepage because nevow gives us an easy to use templating language, which we were going to need to start using soon in the project anyway
Here are some of the main changes that will happen and a rough order of things. Some of these steps may turn in to releases, this has yet to be decided:
Step 1:
Goal:
Turn the outline tree and the tabs into xul, using xmlhttp for updating their state.
Summary of Changes
- Main page now xul
- xmlhttp (LivePage?) now used for:
- Navigating between nodes
- Adding Child nodes
- Deleting nodes
- Renaming nodes
- Moving nodes up and down
- Upgrade to twisted 2.0. This is not a necessity and may be left out of this refactoring sprint.
Required Code Changes:
Client Side Changes
Main Page and IFrames
The main page is no longer in an IFrame to catch on close events. The main page is now XUL instead of HTML. The old authoringPane.py plus the save, load and export pages are now rendered in seperate iframes embedded in the main page.
Javascript
In the JS we have added a new file called mainpage.js which contains all the javascript for the main XUL document.
-- main is such a non-descriptive name, if these are xul utility functions how about xulutil.js? -- DJM -- has been changed to mainpage.js and loadpage.js for the load page -- MS
Browser
In order to allow access to XP com objects on the browser (which are needed for the file open dialog in loadpage and drag and drop on the outline tree). go:
- about:config
- In the search box type "applet"
- signed.codebase.applets.principalsupport to true
- At the beginning of any functions that use xp com you must include:
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect")
Server Side Changes
Renames:
- authoringPage.py will be renamed main.py
- authoringPane.py will be renamed authoringPage.py
Redundancies:
The following modules have been made redundant and will be removed:
menupane.py moved into authoringPage.py
packageRedirector.py
packageRedirector now really redirects to a package instead of serving an IFrame. It still creates new packages everytime it's navigated to.
main.py (old authoringPage.py)
-- mainPage.py would be better?
The new main.py will use a nevow xml template (main.xul) to render its page. This means that instead of the old render_GET and render_POST methods, the class will simply derive from nevow.livepage.LivePage, which implements all the old Resource stuff plus much more.
We add a class attribute that tells it where to get its xml template from: docFactory = loaders.xmlfile('template.xul')
And where some dynamic rendering is required in the xml we use the special nevow namespace syntax: n:render="addChild" as a normal xml attribute in the element that needs to be rendered dynamically; in python we simply create a method: def render_addChild(self, ctx, data):. Whatever this method returns becomes the new xml that replaces that tag.
To make it easier nevow has provided some extra methods for generating/modifying the xml, which we are using. Check the source to find out more.
outlinePane.py
The outlinePane now renders itself in XUL. main.py calls its render method, at present it doesn't use template xml.
The outlinePane will now do the following using xmlhttp (livepage):
- Adding a child node
- Deleting a node
- Renaming a node/title
- Reordering nodes
Selecting different nodes is still done with form posts, but in the authoring iframe not in the main window.
This will give us the advantage of no slow refershes of the xul document, we don't need to remember which tree rows are expanded, the current selection (and externally, which tabs are shown) as the information will not be lost.
However the disadvantage of this is that our code has to be more intelligent; aswell as the standard render method, we now have to provide on the fly insertion, deletion and renaming methods (previously handled by process). These new methods have to keep the client up to date, without re-rendering the whole tree. This is done with javascript and direct DOM manipulation.
This limitation is not imposed by liveage or xmlhttp, but by xul. In livepage, one can go tree.set(newXML), which in JS is translated document.getElementById('outlineTree').innerHTML = newXML. Unfortunately because XUL is strict XML and not HTML, this has to be done with JS DOM manipulation.
LivePage? Implementation
To implement live page, the outlinePane provides some methods like def handle_addChild(self, ctx, nodeId). The main.py classes pass these two nevow, who renders all the xmlrpc javascript stuff to the client.
So when, for example a new node is added in the outlineTree, the javascript calls handle_addChild on the server, the server in turn updates its package object, then the server calls a javascript function on the client (XHAddChildTreeItem), which updates the DOM to show the new tree item in the tree without refreshing the main window.
Re-ordering
Reordering will be done via drag and drop, after the drop the server will be notified, will change, its package layout then will call js on the client to re-order the dom. (The dom re-ordering may be implicity done by the tree control. We'll see...)
authoringPage.py (old authoringPane.py)
--- in the user interface it still appears as a pane within the main page. I think we should keep the authoringPane.py name -- DJM
This file used to authoringPane.py but is now a page in its own right. The only real change with this is that it now rendered in its own iframe instead of as part of the main document. Also it now contains the hidden form document. This will probably be removed later.
idevicepane.py
This now renders its I devices as an XUL listbox. It doesn't use xmlhttp yet as its on select methods, simply post the form in the authoringPane iframe.
stylepane.py
This is like idevicepane.py. It now renders as a XUL listbox and uses iframe form posts to actually implement the style changes.
Future Steps
The goal of the whole project is to move as much of the gui into xul and xmlhttp as is beneficial. One of the earliest goals would be to do away with form posts and refreshes altogether.
- The save, load, export and properties tabs can be moved into a file menu and popup dialogs.
- All the editing controls can be taken out of authoringPane and put in to the xul that surrounds it, so will lose ViewMode? and only have PreviewMode? and EditMode? for idevice renders.
- Entered I-Devices under the tree. The outline tree will be split in two parts (top and bottom), the bottom part will show all the eye devices that you have entered in the currently selected section of you docment. You will be able to use this control to re-order the iDevices. IdeasForiDeviceTree?