Creating new display types |
A display type is defined by a class deriving from the DaxeNode class in the daxe package.
The implementation of the display type class needs 2 constructors, .fromRef() to create a new instance from the language definition of the element, and .fromNode(), to create a new instance from a DOM node. It also needs at least one method, html(), which returns the DOM node for the node to display, with the node id. As an example, let's look at the implementation for the string display, which is simply an inline display with a start tag and an end tag:
part of nodes; class DNString extends DaxeNode { Tag _b1, _b2; DNString.fromRef(x.Element elementRef) : super.fromRef(elementRef) { _b1 = new Tag(this, Tag.START); _b2 = new Tag(this, Tag.END); } DNString.fromNode(x.Node node, DaxeNode parent) : super.fromNode(node, parent) { _b1 = new Tag(this, Tag.START); _b2 = new Tag(this, Tag.END); } @override h.Element html() { var span = new h.SpanElement(); span.id = "$id"; span.classes.add('dn'); if (!valid) span.classes.add('invalid'); span.append(_b1.html()); var contents = new h.SpanElement(); DaxeNode dn = firstChild; while (dn != null) { contents.append(dn.html()); dn = dn.nextSibling; } setStyle(contents); span.append(contents); span.append(_b2.html()); return(span); } @override h.Element getHTMLContentsNode() { return(getHTMLNode().nodes[1]); } }
The constructors derive from the fromRef() and fromNode() constructors in DaxeNode, doing all the basic initialization for free. The start and end tags are created in the constructors, using the Tag class. The html() method creates a span for the DOM node, sets the id based on DaxeNode.id, adds an invalid CSS class if necessary, and appends the tags' HTML nodes and the contents in another span. Style is applied to the contents with DaxeNode.setStyle(), and the span is returned.
Another method is overridden, getHTMLContentsNode(), to return the DOM node containing the children, which can be different depending on the implementation of html(). In this case, we can simply return the second child of the node's DOM node, which we can get with DaxeNode.getHTMLNode().
While all display type classes have to derive from DaxeNode, all the methods can be overridden, so these classes have complete control over appearance and resulting DOM, for the node itself and all the descendants.