editable areas

Basically, there are three simple ways of "marking" a given area as editable in an HTML document instance. Such an area is similar in spirit to a selection.

  1. use an element and specify that this element is editable through an HTML attribute or a CSS property
  2. use two paired elements, one inserted before the area and the second one after the area, the second one carrying an idref to the id of the first one
  3. use two paired comments, one inserted before the area and the second one after the area

Unfortunately, the authoring tool may need to style an editable area with an outline, or a background, or a specific font. So, at least internally, we need an element here because we need to apply CSS styles. Immediate side-effect of that choice: if the start or end of an element has to be contained in an editable area and if that element start or end is not the area's start or end, the whole element has to be contained in the editable area... Example:

<p>blah blah blah <em>foo bar</em> bola bola</p>

The area in bold chars over yellow background cannot become editable because the selection ends inside an element. Making it editable would require cutting the em element in two pieces and that's not acceptable from an author's point of view.

DW

Dreamweaver has chosen the third option above. All the features contained in a DW template are "coded" through SGML/XML comments added to the HTML/XHTML markup of the document. I will only discuss the last version of the DW Templates format that is implemented in DW MX, the former versions of DW uses a slightly different and simpler format.

An editable area is tagged using <!-- TemplateBeginEditable name="foo" --> and ends with <!-- TemplateEndEditable -->.  If you launch DW and place the caret in such an editable area, you'll see that the structure toolbar at the bottom of the window shows an invisible element called mmtemplate:editable.

Repeatable areas are tagged with <!-- TemplateBeginRepeat name="RepeatRegion1" --> and <!-- TemplateEndRepeat --> and create an internal element named mmtemplate:repeat.

Conditional areas (the area is present if and only if a condition is true) are tagged with <!-- TemplateBeginIf cond="facultative" --> and <!-- TemplateEndIf --> and create and internal element named mmtemplate:if.

Template parameters are contained inside the head element of the document and are defined using a comment too. The comment specifies the name, the type and the value of the parameter: for instance <!-- TemplateParam name="fooo" type="text" value="bar" -->. Parameters don't really need to generate an internal element but we're going to discuss that later.

The ugliest thing in DW templates is parameter instanciation in the markup and attributes values. Let's suppose you have a parameter called foo. To copy its value into the markup or into an attribute's value, you have to insert @@(foo)@@ there. I find it absolutely ugly. I understand DW folks made that choice on purpose because an SGML/XML comment cannot be contained into an attribute's value, but still, it's really really ugly, and implies the post-parser has to implement a full-doc text search.. Oh by the way, what's between the parenthesis can be an expression. Think JavaScript... Instead of that ugly @@(foo)@@, they could have used an entity reference. In my mind &MMfoo; is certainly much better and more conformant to the HTML/XML spirit. I understand the HTML parser they used could make it problematic if it drops entity refs to replace them with the entity values...

And so on...Clearly, DW uses internally elements for templates even if those elements are always serialized into comments. It implies that the application has to run a post-parser on the document's tree after load, and a pre-serializer or a hacked serializer.

In Nvu

Well, I guess we'll do the same and implement a post-parser and a pre-serializer, and hack the structure toolbar in Nvu to hide some elements. I am thinking of a _moz_no_serialize attribute. The only difficult things here are the template parameters. I think an easy way to implement them is to attach an xbl binding to the document with a object field that will carry all those parameters and their definitions. I call it the parameters holder. Copies of parameters in the markup will be done through XBL; that XBL will populate an anonymous text node and will refresh it when a given event is received. The parameters holder  mentioned above will implement a watcher, and that watcher will let all parameter copies and conditions know when a parameter is modified. It'll be a bit harder for attribute values but it will also be done through XBL; an attribute making reference to a template parameter will probably trigger the application of a binding to the element, and that binding will refresh the attribute when it receives an event for that from the parameters holder. Could be hard if HTML element already carry a binding...

Given the way I am proposing to implement parameters, the eval JavaScript function will be the only thing needed to evaluate a condition or a parameter. I am pretty sure DW is implemented in a similar way too, the design seems to be made on purpose to rely on JavaScript.

Conclusion

It's feasible. It's not trivial and it'll take some time, but it's feasible. Can be done entirely in JS and XBL. When I read again this conclusion and what I wrote above, I have only one question coming to my mind : why the hell isn't Dreamweaver built on the top of Gecko and XBL ? It seems to me really weird that Macromedia did not push further the talks it had with Netscape at the end of 2000 and beginning of 2001.

Private message : no, it's not "so 1996". It's "so -4000".