XUL Clippings – Midas Rich Text Editor

How to create a rich text or HTML WYSIWYG type editor in Mozilla has come up a few times so I thought a post was in order. Mozilla has a rich text editing system (called Midas) and an API similar to Internet Explorer’s. Mozilla, like Internet Explorer, supports the ability to make an entire document editable by setting the designMode property of the document object. Once in design mode, the document can be manipulated using various DHTML commands.

The API for interacting with the document is:

  • document.execCommand – Executes the given command.
  • document.queryCommandEnabled – Determines whether the given command can be executed on the document in its current state.
  • document.queryCommandIndeterm – Determines whether the current selection is in an indetermined state.
  • document.queryCommandState – Determines whether the given command has been executed on the current selection.
  • document.queryCommandValue – Determines the current value of the document, range, or current selection for the given command.

The most typical way to create a rich text editor in a XUL document is to use the element. In an HTML document, you would use the

You use JavaScript to turn on design mode:


var editor; /* global var */
function onload() {
  editor = document.getElementById("edit");
  editor.contentDocument.designMode = "on";
  setTimeout(function() { editor.contentWindow.focus(); }, 100);
}

window.addEventListener("load", onload, false);

You use the API to send commands to the document:


function toggleBold() {
  editor.contentDocument.execCommand("bold", false, null);
}

function toggleItalic() {
  editor.contentDocument.execCommand("italic", false, null);
}

function alignLeft() {
  editor.contentDocument.execCommand("justifyleft", false, null);
}

function alignRight() {
  editor.contentDocument.execCommand("justifyright", false, null);
}

I found a document that discusses the differences between the Mozilla and Internet Explorer rich editing systems.

I created simple XUL and HTML clippings to demonstrate the system. You can open the HTML clipping in a Mozilla compatible browser. You can download the XUL clipping and open it in XUL Explorer. Right-click on the link and pick “Save Link As” to save it to your machine.

midas-editor.xul
midas-iframe.html

CHI 2007

Looks like I am headed to CHI 2007 to participate in a session on user interface description languages. The session will explore the use of markup language UI’s (such as XUL, XAML and Flex) in prototyping user interfaces before handing them off for system integration. This could allow the interaction designer/engineer to become a more integral part of the iterations in the development cycle.

I’ll be demonstrating using XUL to create a mockup user interface. Scott Stanfield will be building the same interface in XAML. Hopefully, we’ll get people interested in using UI markup.

Session Info:
User Interface Description Languages: XUL & XAML
Thursday 11:30AM – 1:00PM

Scott Stanfield, Vertigo Software
Mark Finkle, Mozilla Corporation

Update: Fixed times and added link to session

XUL Explorer 0.3

After getting sidetracked for a while, I have finally made some progress on XUL Explorer. I have been tinkering around with the editor and integrating the XUL validator. I also reorganized the code a little so I could support sidebars in the future.

xulexplorer.png

I have been trying to stick with the XUL as much as possible. Anyone who has worked with the editor would probably tell me it’s a lost cause, but it’s also been quite a learning experience. I have added tabbed editing by dynamically creating elements inside a . It seems to work well. I make use of the tab-close-button and even change tab image if the editor is modified.

editor-tabs.png

You are prompted to save a modified editor when closing the editor or the application. One thing I have not been able to add was a way to display the current cursor position (row, column). I am still looking into it.

I rearranged the UI a little because of the tabbed editors. The preview pane is no longer below the editor. It was taking room away from the editor, so I added a code/preview toggle. I removed the “Insert Snippet” button from the Snippet Sidebar, but added drag-and-drop as a method of inserting snippets. Double-clicking a snippet also inserts it.

I added a Messages pane at the bottom of the workspace to display output from the, incrementally improved, XUL validator. I’ll probably make more use of the Messages pane in the future.

messages-pane.png

Next up for XUL Explorer:

  • Property Sidebar – Will display the structure of the XUL as a tree and properties of the selected element in a grid. Most likely, it will also allow users to insert/delete XUL elements.
  • Wizards/Generators – Will walk the user through creating XUL files, JavaScript XPCOM, extensions and XULRunner applications. For extensions and application wizards, I really need to add a Project Sidebar.
  • Project Sidebar – Will show the bundle of files needed to support extensions and wizards.

Overall, this project is still giving me lots of Mozilla stuff to play with and learn. And it’s fun.

Keep the feedback coming!

The install is still Windows only. I failed to get a Mac DMG file assembled yet, but I just got some tips on IRC. I am hoping to get Mac and Linux installs someday.

Install: xulexplorer-setup-0.3.exe 4.9MB
Source: xulexplorer-src-0.3.zip

Mozilla Developer Days

Developer days are informal day-long gatherings of Mozilla developers. We’ll be hosting one in Mountain View (Mar 25) and one in Boston (Mar 30). These are mainly oriented to active Mozilla platform, application and extension developers. The agenda is fairly loose and open. It’s a chance for people to talk about what they were working on, get help with problems, hack on code, and discuss where the platform is going, or could be going.

Feel free to signup on the wiki pages so we get an idea of who’s coming and also list any topics you’d like to see discussed:

Mountain View (Mar 25)
Boston (Mar 30)

We’d like to make these happen a few times a year, in various different places. Should be fun.

Firefox 3 – Offline App Demo

Firefox 3’s offline capabilities have been getting some attention lately: Chris Double’s post on porting Zimbra to use offline shows-off the potential. Robert O’Callahan and John Resig give details on the different pieces of the capabilities, namely: Offline Cache, Offline Events and DOMStorage.

A Simple Demo – Task Helper

I put together a simple offline application sample to help illustrate how the features can work. Call it – explanation through code. The application is a simple task list system. The current functionality includes:

  • Add tasks – Enter text in field and press ‘Add’
  • Complete tasks – Mark completed tasks and press ‘Complete’
  • Remove tasks – Mark tasks and press ‘Remove’
  • Data is stored as JSON and XHR is used to interact with server (PHP)

taskhelper.png

Nothing fancy. However, the application is “offline-aware”, meaning:

  • Application resources (HTML & JS) are tagged as offline cacheable
  • Before interacting with server, online status is checked. If online, use XHR. If offline, use DOMStorage
  • Online/Offline status is monitored using events. When the application switches form offline to online, data is resync’ed with the server

There is really nothing fancy about the offline stuff either, but putting it all together does make for a neat application. Using the latest Firefox 3 alpha, you should be able to:

  • Use the application while online.
  • Go offline using the “Work Offline” menu. The event log should show that the app went offline
  • Continue to use the application while offline
  • Go online using the “Work Offline” menu. The event log should show that the app is back online and has updated the server with any offline changes

If you were using a version of Firefox 3 with the offline cache patch (bug 367447) you would be able to a little more:

  • Use the application while online.
  • Go offline using the “Work Offline” menu. The event log should show that the app went offline
  • Continue to use the application while offline
  • Restart browser
  • Switch to offline (or have no network connection)
  • Enter URL to app (or use a bookmark)
  • Start using app with data from last session
  • Switching to online will update the server with offline data

Currently, the offline events only fire when offline is toggled via the “Work Offline” menu. Getting the events to fire by watching the network connection is the goal and would make this much more unobtrusive for the user.

Here is the source to the task helper application: taskhelper-src.zip

More XUL Dark Matter

In December, Robert O’Callahan had a post about the large amount of XUL-based development happening without much visibility. Mozilla wants to find out as much as possible about such development. At Solutions Linux 2007, there was a Mozilla/XUL Round Table session to examine the potential of the Mozilla platform through success stories. From what I have seen (mostly in French) it was quite a successful session. Some of the demos and stories included:

XULfr.org has a detailed writeup (French) (English via Google Translate). What XUL dark matter development do you know about?

FUEL Project Status

FUEL is the little library that John Resig and I are working on which should make developing extensions a little easier. It’s been a while since we last talked about it so I thought an update was in order.

FUEL now has a place in the Mozilla CVS tree (browser/fuel) and development is happening in a branch (FUEL_DEVEL_BRANCH). We have been tweaking the API (0.1 and 0.2) a little over the past couple weeks. We have also added some information on the testing plan. We are using the Mochitest framework to run our unit tests.

So far, we have the basics parts in place, including:

  • Global Application object.
  • Ability to associate user data with the Application and Extension. No more hidden window hacks.
  • Easy access to preferences, again global with Application and per extension with Extension. The extension-based preferences automatically use an “extensions.your-ext.” branch.
  • Simple events for Application (“start”, “ready”, “quit”) and Extension (“install”, “uninstall”). Events can also be used to watch for changes on preferences and storage items.

We hope to get the code and tests ready for review this week. Then we can get something pushed to the trunk after that. As always, feedback is welcome – comments, email, IRC, or Wiki.

XUL Validator – Beta

I put together a simple XUL validator based on the ideas in my last post. There is a primitive front end where you can put XUL into a textarea and validate it. The validator is completely client-side JavaScript with a simple JSON rules file. You can view the source and the rules from the validator “Tests” page.

Currently, the validator checks the structure and semantics of the XUL using the rules given in the last post, with caveats I’ll discuss in a moment. The validator only tests for a subset of the best practices checks. The current tests are listed on the validator “Tests” page. I’ll be adding the rest of the best practice checks soon.

Now, the caveats for the structure checks. There are very few “hard-fast” rules when it comes to XUL. Elements can appear nearly anywhere. Elements can contain any one-off attributes, even made-up ones, which can be useful for CSS selectors. Attribute events, such as “onclick”, can appear on parent elements because events can bubble. The XUL validator, tries to apply some logical warnings and checks, primarily based on the XUL Reference and Tutorial, as well as what I have seen in the Firefox/Thunderbird source code itself.

The current logic is definitely open for discussion and revision! Feedback appreciated.

Update: I made some fixes to the code/rules based on feedback. I also added a small set of options so user can turn off types of checks.