April 26, 2007

Verbosio progress, 04/26/2007

It's meat and potatoes time.

As I've mentioned in earlier posts, I've spent some time creating a "preview" or rendered view of a XML document the user is editing:

Of course, seeing the document alone is no fun. You want to be able to edit it. That's what Verbosio is for.

So let's say you hit Ctrl+E (right now you have to click) on the selected menu item. What do you get? How about, oh, an interface for changing that menu item's properties?

This is what I've been dreaming of for the last year and a half: a way to edit XUL on the fly, visually. (Of course, it's not just XUL - not in the long run. XUL's simply what I chose to work with first.)

It's also supporting my vision for Verbosio: having extensions drive most of the work, while Verbosio handles the common tasks. The preview viewer is provided by a Verbosio extension. The yellow box is provided by Verbosio's core, while its contents (the "XML markup template") come from another Verbosio extension. Support for the document you see comes from the same Verbosio extension as the markup template, a XUL language extension. The XUL language extension also provides some metadata about the XUL language in another component (including some basics about how to handle whitespace). Another extension told Verbosio how to open the chrome application the user is editing.

This is a starting point. I'm going to expand it soon, so that you can:

  • Work with sets of elements (like radio buttons inside a radio group, or cells in a table)
  • Build your own templates within Verbosio, using documents you have open in Verbosio
  • Edit DTD localization entities underneath the labels you see
  • Create templates for creating new documents in supported XML languages from scratch

Sometime after that - once I fix other API issues and some pretty important regressions - I'll release Verbosio 0.1 alpha 1. My changelog is in the extended entry.

In the meantime, I'm also very aware of the need to get other eyes on the code behind Verbosio. Just recently, Paul Rouget borrowed my chrome registry viewer code for his CodeEditor tool. That to me is a solid vindication of what I've been trying to do.

At the same time, the entire Verbosio code base is unreviewed and only partially documented. Sooner or later, I'm going to need volunteers who are willing to work with Verbosio - and me - and improve the hackety-hack code I'm crafting from scratch. Very little of this code, as it now stands, would pass any realistic peer review. So I will start asking, as of now, if other people want to directly involve themselves in the Verbosio project over the next few months.

I just want fellow developers to start thinking about it. I couldn't really do that before, because it's so hard to put into words what Verbosio is all about. Now, hopefully with the screenshots above, the vision can become clearer.

For now, though... the steak's on the barbecue.

2007-04-26 21:42  ajvincent

        * verbosio/www/screenshots.html: Add screenshots for April 26, 2007
          to Verbosio's screenshots page.

2007-04-26 20:41  ajvincent

	* verbosio/www/images/Apr26_2007/: menuitemEdit.png,
	  previewPanel.png: Add screenshots of the preview view of the
	  document, and a first look at the XUL menuitem editing template.

2007-04-26 17:05  ajvincent

	* verbosio/src/: core/components/templateXTF.js,
	  core/content/template.css,
	  generic-viewers/preview-edit/content/preview-edit.js,
	  generic-viewers/preview-edit/content/preview-edit.xul,
	  markup-languages/xul/content/templates.xml: More samples of a XML
	  markup template at work.  More!  (Also remove an assert that
	  proved inappropriate.)

2007-04-26 16:34  ajvincent

	* verbosio/src/: core/components/templateXTF.js,
	  core/content/templateFrame.xul,
	  core/content/bindings/template.xml,
	  core/idl/xeIMarkupLanguage.idl, misc/uuid.txt: More XML markup
	  template commits:  Implement setting of template UI fields from a
	  source node.	Implement  element for read-only
	  templates. Also add basic code (unsupported as yet) for
	  ,  elements.

2007-04-26 16:12  ajvincent

	* verbosio/src/core/app-resources/ecma-debug.js: Add stack dumping
	  to the assert function.

2007-04-25 20:40  ajvincent

	* verbosio/src/core/content/: appOverlay.js, appOverlay.xul: Add
	  code to open testing app's chrome://verbosio/content/verbosio.xul
	  for faster testing.

2007-04-25 20:37  ajvincent

	* verbosio/src/core/: chrome.manifest.in,
	  content/bindings/menudeck.xml: Override the XUL Widgets menudeck
	  widget to wallpaper over a trunk regression.	Expect this change
	  to be backed out in the future.

2007-04-24 22:21  ajvincent

	*
	  verbosio/src/generic-viewers/preview-edit/content/preview-edit.js:
	  Drop debugging dump statements.

2007-04-24 22:16  ajvincent

	*
	  verbosio/src/generic-viewers/preview-edit/content/preview-edit.js:
	  Fix Mac bustage, where floatBox doesn't appear onscreen close to
	  the target element.

2007-04-24 00:15  ajvincent

	*
	  verbosio/src/generic-viewers/preview-edit/content/preview-edit.js:
	  Hide floating templates frame when the preview editor loses
	  focus.

2007-04-24 00:06  ajvincent

	* verbosio/src/:
	  generic-viewers/preview-edit/content/preview-edit.js,
	  core/content/templateFrame.xul: Add API for viewing markup
	  templates, based on the wrapped document the user wishes to edit.

2007-04-24 00:04  ajvincent

	* verbosio/src/core/content/template.css: Remove some currently
	  dead XBL bindings.

2007-04-24 00:04  ajvincent

	*
	  verbosio/src/generic-viewers/preview-edit/content/preview-edit.xul:
	  Give the template iframe some style (height, width).

2007-04-24 00:03  ajvincent

	* verbosio/src/markup-languages/xul/content/templates.xml: Markup
	  template elements should have a menulabel element, in order to
	  fit with  widget.

2007-04-24 00:02  ajvincent

	* verbosio/src/core/components/templateXTF.js: Implement
	  nsIXTFElement.cloneState for .

2007-04-23 18:35  ajvincent

	* verbosio/src/core/components/xeTestEngine.js: Add XUL doc test 2
	  to xeITestEngine.runAllTests().

2007-04-23 18:28  ajvincent

	* verbosio/src/: core/components/templateXTF.js,
	  core/idl/xeIXMLLanguagePackService.idl,
	  markup-languages/xul/components/xul-language.js, misc/uuid.txt:
	  Add Verbosio markup template language pack.  Add routines to
	  xeIMarkupTemplate.rateSupport for initial checking of a node
	  against its equivalent template.  This includes a whitespaceMap
	  object which caches results from various
	  xeIXMLLanguagePackService.handleWhitespace() calls.

2007-04-23 18:00  ajvincent

	* verbosio/src/misc/component.js.in: Multi-component JavaScript
	  module template:  Support service factories a little easier, by
	  removing the need for Service.prototype; just use a global
	  service object, and Module.addService().

2007-04-23 13:33  ajvincent

	* verbosio/src/: code-languages/css/components/css-document.js,
	  code-languages/css/components/css-language.js,
	  code-languages/javascript/components/js-document.js,
	  code-languages/javascript/components/jsLanguagePack.js,
	  code-languages/javascript/components/jsSourceMap.js,
	  code-languages/xul-application/components/application-ini.js,
	  core/components/DTDDocumentWrapper.js,
	  core/components/XMLDocumentWrapper.js,
	  core/components/documentFile.js,
	  core/components/entityManager.js,
	  core/components/nodePositionService.js,
	  core/components/templateXTF.js,
	  core/components/textDocumentWrapper.js,
	  core/components/verbosio-utils.js,
	  core/components/verbosioEditor.js,
	  core/components/virtualProtocol.js,
	  core/components/xblLanguagePack.js,
	  core/components/xeBaseURIMap.js, core/components/xeFileSearch.js,
	  core/components/xeTestEngine.js,
	  core/components/xmlLanguagePack.js,
	  core/content/bindings/valuepanel.xml,
	  core/content/tools/xeTransactionCommon.js,
	  document-packs/verbosio-app/components/verbosio-app.js,
	  document-packs/xul-application/components/xul-application.js,
	  generic-viewers/inspector/content/inspectorOverlay.js,
	  generic-viewers/source-edit/content/bindings/source-editor.xml,
	  markup-languages/xul/components/xul-document.js,
	  markup-languages/xul/components/xul-language.js,
	  misc/component.js.in, xpathgen/components/nsXPathGenerator.js:
	  QueryInterface cleanup.

2007-04-22 14:29  ajvincent

	* verbosio/src/core/components/xeTestEngine.js: Add initial test
	  code framework for markup templates.

2007-04-21 14:32  ajvincent

	*
	  verbosio/src/generic-viewers/preview-edit/content/preview-edit.js:
	  Get templates corresponding to a DOM node the user selects.

2007-04-21 14:31  ajvincent

	* verbosio/src/: core/components/templateXTF.js,
	  core/components/verbosio-utils.js,
	  core/idl/xeIMarkupLanguage.idl,
	  core/idl/xeIVerbosioUtilsService.idl, misc/uuid.txt: Add initial
	  support for searching Verbosio's markup language templates
	  against a selected DOM node.

2007-04-21 14:21  ajvincent

	* verbosio/src/core/content/: verbosio.js,
	  tools/namespaceRegistry.js: Rewrite namespace registry to reflect
	  more recent API, and use Verbosio utilities service.

2007-04-21 14:19  ajvincent

	* verbosio/src/markup-languages/xul/content/templates.xml: Reduce
	  cruft in templates.xml to immediately testable levels.  I'm
	  moving the markup language bindings to XTF and almost starting
	  over.

2007-04-21 14:17  ajvincent

	* verbosio/src/markup-languages/xul/verbosio-data.xml: Minor bugs
	  in verbosio-data.xml for XUL language extension.

2007-04-21 14:15  ajvincent

	* verbosio/src/core/components/entityManager.js: Entity manager was
	  calling for Verbosio utilities a little too soon.

2007-04-21 10:03  ajvincent

	*
	  verbosio/src/generic-viewers/preview-edit/content/preview-edit.js:
	  Minor adjustments to floatBox:  use click events instead of
	  mousemove (we should really make this selection-dependent), and
	  bail out if the target node hasn't changed from the last such
	  event.

2007-04-21 09:55  ajvincent

	* verbosio/src/: core/components/templateXTF.js, misc/uuid.txt:
	  Initial check-in of XTF binding for XML elements in the markup
	  namespace.

2007-04-17 23:24  ajvincent

	* verbosio/src/: core/content/templateFrame.xul,
	  generic-viewers/preview-edit/content/preview-edit.js,
	  generic-viewers/preview-edit/content/preview-edit.xul,
	  generic-viewers/preview-edit/skin/preview-edit/preview-edit.css:
	  Lay groundwork for positioned editing templates.  Thanks to
	  bzbarsky for suggesting iframe inside box.
Posted by WeirdAl at 7:24 PM | Comments (1)

April 21, 2007

XTF: When XBL just won't cut it

A few days ago, I was trying to load XBL bindings onto elements that the user doesn't see. By this, I mean the elements were loaded via a DOMParser. Unfortunately, that doesn't work. Since I've no desire to spend time trying to make it work in XBL, I reluctantly turned to another Mozilla technology, the eXtensible Tag Framework (XTF).

Why reluctantly? Well, XTF is something I've never done before, and I would prefer there were some good guides in mozilla.org to use it. XTF suffers from a trifecta of difficulties, for me approaching it as a new consumer:

  1. developer.mozilla.org has unusable (scant, non-existent) documentation on XTF. Existing documentation (on croczilla.com/xtf) is considerably out of date.
  2. XTF is under-utilized in the mozilla.org source tree; there are no JavaScript-based XTF components out there, and XForms is a big, hairy beast.
  3. The XTF interfaces are a bit unclear at first; I ended up having to read the source code to figure out half of what I was supposed to do.

That said, once I did figure out the route I was supposed to take, I found it fairly easy. In the extended entry, I'll lay out a roadmap to writing a DOM implementation for a new XTF-based language in JavaScript.

Someone will have to nudge me to export it to devmo.

Starting point: Declaring your element factory

XTF's nsIXTFElementFactory interface has a single method, createElement(aLocalName). (The IDL suggests you receive the whole tag name; this is incorrect. You only get the local name of the element.) When you implement this method, you'll need to return a nsIXTFElement object (I'll cover this in a moment). This new object acts as the bridge between your custom element's methods and properties, and the element itself.

All XTF element factories have a contract ID which starts with "@mozilla.org/xtf/element-factory;1?namespace=" and ends with the namespace URI of elements in that namespace. So if I have an element:

<markup:template xmlns:markup="http://verbosio.mozdev.org/namespaces/markup/"/>

The contract ID for my XTF element factory must be:

"@mozilla.org/xtf/element-factory;1?namespace=http://verbosio.mozdev.org/namespaces/markup/"

Your element factory should also be a service, using nsIClassInfo's SINGLETON flag.

Individual elements

Each "class" of element (based on a particular local name) you bind with XTF should have its own constructor, yet all constructors need to implement a few interfaces, like nsIXTFElement. In JavaScript, I figured the best way to do this would be to combine JS prototypes with a "hash" object containing the constructors:

MarkupConstructors = {}

function addMarkupConstructor(aName, aFunction, aProperties) {
  MarkupConstructors[aName] = aFunction;
  aFunction.prototype = new MarkupElement();
  for (var prop in aProperties) {
    aFunction.prototype[prop] = aProperties[prop];
  }
}

/* <markup:template> */
addMarkupConstructor("template",
  function MarkupTemplate() {
    // nsIXTFPrivate
    this.inner = null;

    this._baseElementNode = null;
  },
  {
    // xeIMarkupLanguage
    rateSupport: function rateSupport(aNode) {
      dump(this._baseElementNode.nodeName + "\n");
      return 1;
    },

    // nsIXTFElement
    getScriptingInterfaces: function getScriptingInterfaces(aCount) {
      var interfaces = [xeIMarkupTemplate];
      aCount.value = interfaces.length;
      return interfaces;
    }
  }
); /* </markup:template> */

(The "rateSupport" method I'll come back to in a moment.) Then the XTF element factory's createElement method looks like this:

  // nsIXTFElementFactory
  createElement: function createElement(aLocalName) {
    if (aLocalName in MarkupConstructors) {
      return (new MarkupConstructors[aLocalName]).QueryInterface(nsIXTFElement);
    }
    return null;
  },

Note I do not throw any errors if my XTF components do not support a particular element. If someone tries to create an element in your namespace and you don't support it, simply return null.

Interacting with the native element wrapper

For each implementation of nsIXTFElement, there is a nsIXTFElementWrapper which Gecko provides and which drives interaction between the source document and your XTF binding. You only get this wrapper once, with the nsIXTFElement.onCreated() method. If you're going to do any work with the raw XML element your node is based on, you need to store the wrapper's elementNode property privately. (Note: Smaug recommends storing the wrapper itself; I defer to his expertise on the subject.)

Also, XTF allows you the possibility of handling the core DOM interactions yourself. However, you must tell the element wrapper which DOM-related methods of nsIXTFElement you support. You do this by setting the notificationMask property of the element wrapper inside onCreated(). For my purposes, I simply set it to 0, because I don't want to change how the DOM inserts nodes, etc. (At least, not yet. I don't need to.)

Olli Pettay (smaug) has raised the point that if you store the original XML element as a private property, you may end up leaking the element. I don't see any easy way around that. The XPCOM cycle collector should take care of this kind of leak.

Extending the DOM of the original element

This is what XTF, to me, is all about. I mentioned rateSupport earlier, as a custom method on a custom interface. XTF lets you do this, indirectly.

First, there's the nsIXTFElement.getScriptingInterfaces() method. This method is the primary reason you do not need to implement nsIClassInfo on your nsIXTFElement components: XTF's wrapper code takes the interfaces you record here, and appends them to the native DOM element's own supported interfaces and class info. (This means that the consumer sees all the native element interfaces, plus yours!)

Internally, your XTF element component must support them. For that, you need a modified QueryInterface() method:

  // nsISupports
  QueryInterface: function QueryInterface(aIID) {
    if (aIID.equals(nsIXTFElement) ||
        aIID.equals(nsISupports))
      return this;

    // Maybe we've scripted support for it.
    var sInterfaces = this.getScriptingInterfaces({});
    for (i = 0; i < sInterfaces.length; i++) {
      if (aIID.equals(sInterfaces[i])) {
        return this;
      }
    }

    // Discover what interfaces we need.
    var i = Components.interfaces;
    var found = false;
    for (var prop in i) {
      if (aIID.equals(i[prop])) {
        found = true;
        dump("QUERYINTERFACE: MarkupElement " + prop + "\n");
        break;
      }
    }
    if (!found) {
      dump("QUERYINTERFACE: MarkupElement Unknown\n");
    }
    return null;
  }

In the rateSupport example above, you might think for a moment your this object is actually the original XML element your component binds. This is not the case; instead, this is your component. This is why I recommend storing a reference to the raw XML element, so you can do additional DOM manipulations (such as reflecting an attribute's value as a DOM property).

If you're too lazy to write IDL interfaces for your elements, you can also implement the nsIXTFPrivate interface on your XTFElement components. This lets you define an "inner" object of any type, and should be accessible via wrappedJSObject. I personally recommend against this approach; clearly-defined interfaces are superior to hand-waving and creating properties internally.

Conclusions: Tip of the iceberg

XTF does have the potential to do more; as I said before, you can follow DOM manipulations on your element. You can't control DOM changes (canceling them, for example), because the element wrapper doesn't check any error messages you might throw at present. So validation doesn't yet appear feasible.

Because nsIXTFWrapper.onCreated() offers you a route to the original XML element you're binding to, you could QueryInterface that element to nsIDOMEventTarget and add custom event listeners to the element (or anything else in the element's accessible DOM).

There's also XBL 2 coming up, on the Mozilla 2 project. XBL 2 should obsolete XTF, and give us bindings for data documents (non-rendered documents) as well. Mozilla 2 is a long, long ways off, though.

Finally, be very aware of who may try to use your XTF-bound elements. I have a desire to let extension authors write custom JavaScript objects which extend the capabilities of the original element. That said, my XTF elements are probably available to untrusted content. So I have to figure out how to sandbox the custom JS where it can't reach into my XTF component - but can only touch the element and what the element publicly exposes. There is a possibility for security holes if you're not careful with other people's use.

I've begun implementing a XTF-based component set under Verbosio's markup namespace. Much more work on it to come in the next several days.

Posted by WeirdAl at 5:38 PM | Comments (5)

Tooting my own horn

This isn't something I do much, but in this case someone else made the announcement and it hasn't hit planet yet.

Neil Deakin and I were both interviewed by the Mozilla Digital Memory Bank project - Neil last June, me a couple weeks ago. The home for both interviews is here.

When the announcement from MDMB does hit planet.mozilla.org, I will probably delete this entry.

Posted by WeirdAl at 2:32 AM | Comments (1)

April 15, 2007

Imageless browsing, 2007

Due to some issues with my ISP at home, I've temporarily shut off images in my Firefox installation. It doesn't take long for me to realize just how much I appreciate them, especially at the level of little icons.

It actually causes some readability issues. For instance, on CNN.com, the image alternate text is larger than the size of the icon in many respects. (Note: Another instance occurs in my weblog, where I can't see the "Logout" link in the page where I'm writing this very entry!)

To really get the feel for it, I think the web community at large should pick a day (say, April 30, two weeks hence), where advanced users turn off their image browsing for that day and see how it impacts their day-to-day operations. In particular, web designers could take a look at their own pages with images off. Looking at other websites, well, please be polite and considerate of the site designers. This is a suggested evangelism effort.

Note I'm excluding image hosting websites and image "portals" (for which the lack of images would defeat their whole purpose of existence). So don't yell at me about the Hubble Space Telescope. Your favorite web comics should probably be excluded for the same reason. In short, where a picture or image is the overall goal, there's no point in getting upset about it.

Is this an unrealistic request in the days of broadband Internet access? I don't think so, since a large percentage of the public still use dial-up (NetZero, PeoplePC anyone?) Images eat bandwidth - not as much as movies, of course, but still a sizable portion.

What do you think, as a member of the community at large? I just think it's worth taking a survey of the Web, and seeing it how we used to ten years ago, as we downloaded images. Just how much do we rely on them now, and is it too much?

Posted by WeirdAl at 11:23 PM | Comments (9)

April 13, 2007

Trekkie Anime

Anyone who knows me really well knows I'm a pretty big fan of Star Trek, although not the type to go to conventions. (Or at least, I've never gone out of my way to visit one.) I even submitted a story to the Strange New Worlds VIII contest, although it was rejected - and thankfully, not for technical reasons. (For those who wonder, the title was "Peanuts, Popcorn, Hasperat!". I'll give my fellow fans one guess what it referred to.)

When I was growing up, I remember watching the Nickelodeon channel, in particular for episodes of Star Trek: The Animated Series. As with the other Star Trek series, I'd never seen all the episodes in the series, nor had I had the opportunity to do so. Thank goodness for DVD's, even if they do come twenty years late!

Today, I wandered into the local comics shop (where I've been picking up issues of Battlestar Galactica comics - thank you, Ron Moore, for endorsing that). I'd seen the Animated Series on the shelf before, but I didn't buy it then. I bought it today, and I'm finally getting to see episodes of this classic, semi-canon series for the first time since I was a young teenager.

Personally, I've always felt that the animated series completed the Enterprise's original five-year mission. The original series ran for three seasons, which translates to about three years (something which later series have confirmed, as we watched Wil Wheaton and then Cirroc Lofton grow up on screen). Today, I discovered ST:TAS lasted two seasons. Three plus two equals five. A nice coincidence (even if that very last season only had six episodes in it). Of course, I'm not counting the books, of which I have dozens.

Sadly, I don't get to feel like a kid again. I'm watching the new episodes, and while I enjoy them, my ears and other senses are picking up on little things that I didn't notice two decades ago.

Now this is just a thought from a fan, but I'd like to hear Scott Bakula, Jolene Blalock, John Billingsley, etc., etc. (and yes, Jeffrey Combs) get together and do a few seasons of Enterprise as an animated series. Putting aside the rather excellent book, "The Good That Men Do" by Andy Mangels & Michael A. Martin, there seemed to be no shortage of ideas when Enterprise ended.

Judith? Garfield? Please?

Posted by WeirdAl at 8:27 PM | Comments (1)

April 11, 2007

Verbosio progress, 04/11/2007

The goal is in sight... literally.

A few days ago, I checked in another viewing extension to Verbosio, one that shows you what the document would really look like. It's not editable yet - it's just an iframe - but at least now you can see what your changes do to your document. (No screenshots yet - what's so pretty about an iframe?)

It also means I'm finally done writing mostly component code and now I can get back to writing mostly chrome code. I can finally make Verbosio into an editing application instead of a clunky DOM Inspector clone. :-)

I'm working now on integrating my markup template system with the visual rendering. Just this evening I landed sample code from the experimental branch to mark a starting point. I'm also beginning to figure out a little more clearly what Verbosio and its extensions need from each other.

Already I'm thinking about a Verbosio 0.1 alpha 1 release in the near future (read: within a few weeks). I will have a very tough time deciding what makes 0.1a1 and what should come later, though.

The changelog since March 7, 2007 is in the extended entry.

2007-04-11 19:12  ajvincent

	* verbosio/src/: core/content/template.css,
	  core/content/verbosio.dtd, core/content/bindings/template.xml,
	  markup-languages/xul/content/templates.xml,
	  markup-languages/xul/content/xul-language.dtd,
	  markup-languages/xul/locale/en-US/xul-language/templates.dtd,
	  markup-languages/xul/skin/xul-language/xul-language.css: Initial
	  landing of main templates code from verbosio/experimental.

2007-04-11 19:09  ajvincent

	* verbosio/src/core/content/verbosio.css: Add license boilerplate
	  to verbosio.css.

2007-04-11 18:12  ajvincent

	* verbosio/src/core/: components/verbosio-utils.js,
	  content/verbosio.js, idl/xeIVerbosioUtilsService.idl: Add code
	  for reading Verbosio extension metadata documents.  Interpreting
	  them will come later.

2007-04-11 17:17  ajvincent

	* verbosio/src/backport.pl.in: Adjust backport.pl.in to include
	  verbosio-data.xml.

2007-04-11 17:15  ajvincent

	* verbosio/src/: make-project.pl,
	  markup-languages/xul/verbosio-data.xml: Add sample data file for
	  Verbosio extensions, so Verbosio can identify a language an
	  extension provides.  Also adjust make-project.pl to generate
	  slightly cleaner objdirs.

2007-04-11 12:42  ajvincent

	*
	  verbosio/src/generic-viewers/preview-edit/content/preview-edit.js:
	  Add an error event listener on the preview iframe to silence most
	  errors from content.

2007-04-11 11:15  ajvincent

	* verbosio/src/core/content/bindings/verbosio.xml: Add support for
	  changing documents via Ctrl+PGUP, Ctrl+PGDN.	Also add support
	  for changing viewers via Alt+PGUP, Alt+PGDN.	Finally, shave a
	  few lines of inefficiency off the command event handler for tabs.

2007-04-11 03:56  ajvincent

	*
	  verbosio/src/generic-viewers/preview-edit/content/preview-edit.js:
	  Show the document the user is editing in a preview panel.

2007-04-11 03:54  ajvincent

	* verbosio/src/core/components/xeTestEngine.js: Adjust baseURIMap
	  automated test to account for ../ cases.

2007-04-11 03:53  ajvincent

	*
	  verbosio/src/document-packs/xul-application/components/xul-application.js:
	  Clean up file paths with ../ in them, and resolve file:// URI's
	  to local file paths.

2007-04-11 03:50  ajvincent

	* verbosio/src/core/components/documentFile.js: Minor adjustment to
	  documentFile component for URL handling.

2007-04-11 03:49  ajvincent

	* verbosio/src/core/components/xeBaseURIMap.js: Fix typo in base
	  URI map:  XPCOM error code was incorrectly named.

2007-04-09 12:40  ajvincent

	* verbosio/src/core/content/bindings/verbosio.xml: Viewer tabs for
	  the document viewer binding should start out disabled.

2007-04-08 22:56  ajvincent

	* verbosio/src/make-project.pl: Add preview / WYSIWYG document
	  viewer to the Verbosio build process.

2007-04-08 22:55  ajvincent

	* verbosio/src/generic-viewers/preview-edit/: VER_LAST,
	  chrome.manifest.in, install.rdf.in, content/preview-edit.dtd,
	  content/preview-edit.js, content/preview-edit.xul,
	  locale/en-US/preview-edit/.cvsignore,
	  locale/en-US/preview-edit/preview-edit.properties,
	  skin/preview-edit/preview-edit.css: Initial landing of the
	  preview-edit extension.  Note this is just a framework; there is
	  no actual support for previewing documents yet.

2007-04-08 21:31  ajvincent

	* verbosio/src/generic-viewers/source-edit/content/:
	  source-edit.js, bindings/source-editor.xml: Use sanitized content
	  from entity manager for XML documents.  Fix subtle dataloss bug
	  in re-parsing of XML documents.  Source edit transactions should
	  be managed by notifyEvent(), not the input event handler.

2007-04-08 21:26  ajvincent

	* verbosio/src/markup-languages/xul/components/xul-document.js: XUL
	  documents shouldn't lose an existing doctype.  Also, remove more
	  noisy dump statements for XUL document wrapper invariants.

2007-04-08 21:20  ajvincent

	* verbosio/src/core/components/entityManager.js: Entity manager
	  doesn't implement nsISecurityCheckedComponent.

2007-04-08 21:18  ajvincent

	* verbosio/src/core/components/documentFile.js: Add a few useful
	  dump statements, fix strict warnings in documentFile.js.

2007-04-08 21:15  ajvincent

	* verbosio/src/code-languages/css/components/css-document.js:
	  Remove some noisy dump statements in css-document.js component.

2007-04-08 20:11  ajvincent

	* verbosio/src/markup-languages/xul/components/xul-document.js: Use
	  the entity manager's getSanitizedContent() method to handle
	  DTD's, entities.

2007-04-08 19:59  ajvincent

	* verbosio/src/generic-viewers/source-edit/VER_LAST: Back out rev
	  1.2 to VER_LAST.  It's too soon to update this.

2007-04-08 19:57  ajvincent

	* verbosio/src/generic-viewers/source-edit/: VER_LAST,
	  content/bindings/source-editor.xml: Get source code through a
	  document wrapper's entity manager, and remove the
	  findEndOfDoctype code, which Verbosio utilities already takes
	  care of.

2007-04-08 19:54  ajvincent

	* verbosio/src/core/components/entityManager.js: Implement code for
	  sanitizing the source code contents of a XML document.

2007-04-08 19:50  ajvincent

	* verbosio/src/core/content/verbosio.dtd: Add MARKUP_NS namespace.

2007-04-08 17:47  ajvincent

	* verbosio/src/core/content/tools/domTreeViewMaker.js: DOM tree
	  view maker should display entity reference nodes when it hits a
	   element.

2007-04-08 17:31  ajvincent

	* verbosio/src/core/components/: entityManager.js, xeTestEngine.js:
	  Add parsing of text entities to the entity manager.

2007-04-08 16:42  ajvincent

	* verbosio/src/core/components/entityManager.js: Fix some minor
	  bugs in entity manager:  don't check node value, exclude children
	  of markup:entity-ref elements, and make sure all entity ref
	  fragments have their own DTD's, so entities referencing entities
	  can still be parsed.

2007-04-08 16:38  ajvincent

	* verbosio/src/core/components/documentFile.js: Normalize XML
	  documents.

2007-04-07 17:01  ajvincent

	* verbosio/src/core/: components/entityManager.js,
	  components/xeTestEngine.js, content/entityTest.xul: Fix minor
	  bustages in entity handling, and create a baseline testcase for
	  the entity manager.

2007-04-06 21:49  ajvincent

	* verbosio/src/core/content/tasksOverlay.xul: Well-formedness error
	  fix, for a missing quote.

2007-04-06 19:32  ajvincent

	* verbosio/src/core/components/entityManager.js: XML entity
	  manager:  implement most of the mapping functionality.  Still
	  non-functional (it should be surrounding nodes in entity refs,
	  but isn't for some reason).

2007-04-04 09:44  ajvincent

	* verbosio/src/: core/components/entityManager.js,
	  markup-languages/xul/components/xul-document.js, misc/uuid.txt:
	  Add framework for XML entity manager code.  Not yet fully
	  implemented.

2007-03-29 16:38  ajvincent

	* verbosio/src/core/content/tools/domTreeViewContext.dtd: Fix
	  regression with key bindings:  overlays only apply to one element
	  per ID-type attribute.

2007-03-29 11:37  ajvincent

	* verbosio/src/core/content/: verbosio.xul,
	  tools/domTreeViewContext.dtd: Add native-app key bindings for
	  cut, copy, paste, delete edit commands.  Note there is no
	  equivalent to insert commands.

2007-03-28 23:06  ajvincent

	* verbosio/src/core/content/: verbosio.js, verbosio.xul,
	  tools/xeTransactionCommon.js: Initial check-in of Verbosio cut,
	  copy, paste commands and code to call on them.

2007-03-28 23:02  ajvincent

	*
	  verbosio/src/document-packs/xul-application/components/xul-application.js:
	  Add transaction listener for XUL application pack.

2007-03-28 23:01  ajvincent

	* verbosio/src/markup-languages/xul/components/xul-language.js:
	  Clarify QueryInterface calls.

2007-03-26 11:16  ajvincent

	* verbosio/src/: code-languages/css/components/css-document.js,
	  misc/uuid.txt: Forgot to mark a couple UUID's for a given
	  component.

2007-03-19 19:25  ajvincent

	* verbosio/src/code-languages/css/components/css-document.js: Add
	  an initial class invariant on CSS document packs.

2007-03-19 19:23  ajvincent

	* verbosio/src/core/components/xeTestEngine.js: Test engine needs
	  to set the correct length for data (bypass mozilla.org bug
	  374562).

2007-03-19 17:10  ajvincent

	* verbosio/src/core/content/tools/ecma-debug.js: Remove
	  chrome://verbosio/content/tools/ecma-debug.js; replaced by
	  resource://app/res/ecma-debug.js
	  (verbosio/src/core/app-resources/ecma-debug.js).

2007-03-19 17:06  ajvincent

	* verbosio/src/:
	  code-languages/xul-application/components/application-ini.js,
	  document-packs/verbosio-app/components/verbosio-app.js,
	  misc/component.js.in: Replace remaining references to
	  chrome://verbosio/content/tools/ecma-debug.js with
	  resource://app/res/ecma-debug.js.

2007-03-19 16:59  ajvincent

	* verbosio/src/: core/components/DTDDocumentWrapper.js,
	  core/components/XMLDocumentWrapper.js,
	  core/components/documentFile.js,
	  core/components/nodePositionService.js,
	  code-languages/css/components/css-document.js,
	  code-languages/css/components/css-language.js,
	  code-languages/javascript/components/js-document.js,
	  code-languages/javascript/components/jsLanguagePack.js,
	  core/components/textDocumentWrapper.js,
	  core/components/verbosio-utils.js,
	  core/components/xblLanguagePack.js,
	  core/components/xeFileSearch.js, core/components/xeTestEngine.js,
	  core/components/xmlLanguagePack.js, core/content/verbosio.xul,
	  document-packs/xul-application/components/xul-application.js,
	  markup-languages/xul/components/xul-language.js: Replace
	  remaining references to
	  chrome://verbosio/content/tools/ecma-debug.js with
	  resource://app/res/ecma-debug.js.

2007-03-19 16:40  ajvincent

	* verbosio/src/markup-languages/xul/components/xul-document.js:
	  Convert XUL document wrapper to use ECMA Debugging functions from
	  resource://app/res/ecma-debug.js.

2007-03-19 16:35  ajvincent

	* verbosio/src/core/app-resources/ecma-debug.js: Copy
	  verbosio/src/core/content/tools/ecma-debug.js rev 1.9 to
	  verbosio/src/core/app-resources/ecma-debug.js rev 1.1.

2007-03-19 16:32  ajvincent

	* verbosio/src/core/content/tools/ecma-debug.js: Bug fixes for
	  invariant class contracts.

2007-03-19 16:30  ajvincent

	* verbosio/src/: backport.pl.in, make-project.pl: Add support for
	  resource://app/res/ building.

2007-03-19 15:49  ajvincent

	* verbosio/src/core/content/tools/ecma-debug.js: Allow
	  InvariantContract's _generateContract method to look for an
	  existing contract function and adopt it.  Also, prepare to move
	  ecma-debug.js to resource://app/res/ecma-debug.js.

2007-03-18 14:34  ajvincent

	* verbosio/src/core/: components/verbosio-utils.js,
	  components/xeTestEngine.js, idl/xeIVerbosioUtilsService.idl: Add
	  initial support for Verbosio clipboard manipulation, including
	  caching an object closely related to the clipboard contents.

2007-03-17 19:26  ajvincent

	* verbosio/src/: core/content/tools/ecma-debug.js,
	  markup-languages/xul/components/xul-document.js: Add class
	  invariant support for JS-based XPCOM components.

2007-03-14 20:32  ajvincent

	* verbosio/src/: misc/uuid.txt, core/idl/xeIEntityManager.idl,
	  core/idl/xeIXMLDocumentWrapper.idl: Add interface for managing
	  XML entity references in a document.	Not implemented yet; this
	  is a sketch.

2007-03-09 20:18  ajvincent

	* verbosio/src/: core/components/DTDDocumentWrapper.js,
	  core/components/documentFile.js,
	  document-packs/xul-application/components/xul-application.js:
	  Replace  href pseudo-attributes with
	  virtual:// equivalents.  Note this messes up a few things
	  downstream (like source code editing), but this should fix most
	  of bug 16341.

2007-03-09 14:54  ajvincent

	* verbosio/src/: make-project.pl, core/components/xeTestEngine.js,
	  code-languages/css/VER_LAST, code-languages/css/install.rdf.in,
	  code-languages/css/components/css-document.js,
	  code-languages/css/components/css-language.js: Initial
	  implementation of CSS language pack extension (including document
	  wrapper).
Posted by WeirdAl at 6:33 PM | Comments (1)

April 7, 2007

Verbosio progress, 04/07/2007

When a XML editor finishes messing with DTD's, the next thing which comes to mind is entity references (&foo;). In the case of Mozilla code, these entity references don't exist: the XML parsing code replaces the entity ref with the appropriate source code from the DTD. So the DOM in Mozilla never actually sees entity references.

This is a major problem for Verbosio. As a XML editor, it must know where a XML document uses entity references. With that knowledge, Verbosio can then provide a user-interface which guides people to editing the DTD entity underneath the entity ref.

What makes it more interesting is that Mozilla really has no effective code for entity references in DOM. Try var foo = document.createEntityReference("bar");. You'll find out that, even if there is no declared <!ENTITY bar "...">, no error will be thrown; instead, foo is null.

How can Verbosio work around this? At present, I have an imperfect solution, a XML "entity manager". Read on if you have any interest.

I've already checked in a first-draft entity manager component (with XPIDL interface). Currently it's only minimally functional, with several bugs I need to track down.

Entities contain fragments of XML markup, which (in many, but not all) cases comprise full DOM nodes which could fit into a document fragment or a XML element "wrapper". So what I have been doing is taking the contents of each entity and parsing them into little XML documents inside a specially constructed wrapper. Then I compare the nodes in each entity's DOM fragment against the nodes of the document.

Note I cannot use isEqualNode() on any of these, because in the entity fragments I have no way of knowing which namespaces to associate with each element and attribute in the entity declaration.

The problem is a little more complex, because some entities are for attributes-only, and others are for XML fragments. So there are really two different types of entity references: those inside an attribute's value, and those which could span several (non-attribute!) nodes. The first type can only contain CharacterData nodes; the second can contain almost any types of nodes.

When the entity manager finds a match of the second type, it currently surrounds the matching DOM nodes in the document with a <markup:entity-ref/> element. This is a really hackish way to take care of business, but in theory it should work. In practice, it means document viewers (like the Inspector view and the source code view) will have to work a little harder than is nice.

I also tried to move the new contents of this entity-ref element into the element's anonymous content. (The idea is that all the user sees in the source code is the entity ref itself, and not its contents - but in a rendered view, the contents are visible.) Unfortunately, to do so you need to add a binding to the entity-ref element, and that doesn't work for DOMParser-created documents. So that's a dead end.

It's also worth noting that currently, attribute nodes in Mozilla can't have entity references for children. (If you can't create them, you can't insert them.)

Ultimately, it's enough of a quagmire that, even once I get all the algorithms for my entity manager fixed and operational, I'll still think it's not right. It would be far better to actually implement entity reference classes natively in Gecko, and to use them to simplify the DOM of the document. Verbosio's entity manager would take care of inserting the entity references, but the references themselves would belong to the core DOM. That would make the proposed <markup:entity-ref/> element obsolete and (fortunately) easy to replace.

Oh, by the way, Mozilla's doctypes return null when you ask for their entities property. Another nice quirk of the Mozilla DOM.

Personally, I don't think we'll see native entity references or entity nodes in Mozilla DOM anytime soon. It's a lot of work for admittedly little gain. Sure, Verbosio would benefit... but not Firefox, Thunderbird, or Songbird, I'd think. That's why these not-so-little hacks are (for now) necessary.

Posted by WeirdAl at 6:46 PM | Comments (1)

April 5, 2007

WYSIWYG for multiple XML languages?

Just a few moments ago, I noticed a post in mozilla.dev.tech.mathml for a WYSIWYG MathML editor. If you factor in tools like TinyMCE for HTML editing, and Mark Finkle's SVG RichDraw tool, you can't help but be amazed, as I am. (No word on the licensing behind the MathML tool; I've just asked in the newsgroup.)

Just to see efforts like this for individual languages impresses me greatly. Plus, since they work in web pages, there's no reason they can't work in chrome pages. Web pages operate under a lot more restrictions than chrome.

How nice it would be to integrate all of these into a common platform, so that you'd have WYSIWYG XHTML + MathML + SVG!

This is precisely the sort of thing I'm building Verbosio for: people who develop great tools for individual markup languages could drop them into Verbosio as extensions and have them working together. That's the vision behind my Verbosio work.

Where's WYSIWYG in Verbosio? A little ways off. I don't think true WYSIWYG will make Verbosio 0.1, although I'd very much want it; I simply have to concentrate on minimal functionality first. (I have other editing-what-you-see plans first.)

All the same, I'd love to start a community discussion between these individual projects and see what I can do to integrate these tools and help them.

My hat's off to all of you.

Posted by WeirdAl at 10:30 PM | Comments (1)