7.2. Using custom code to extend the CSS style sheet

In the rare cases where Cascading Style Sheets (CSS) are not powerful enough to style certain elements of a class of documents, it is possible to use custom code written in the Java™ language to do so.

@extension "extension_class_name parameter ... parameter"; must be used to declare the Java™ class implementing the CSS extension.

Example (DocBook):

@extension "com.xmlmind.xmleditext.docbook.TableSupport true";

In the above example, com.xmlmind.xmleditapp.xhtml.TableSupport is a class which is used to style XHTML (that is, HTML 4) tables. The two parameters which follow the class name specify colors used to draw table and cell borders. Parameters are optional and can be quoted if they contain white spaces.

The same CSS style sheet can contain several @extension constructs. For example, an extension class may be used to style HTML tables and an other extension class may be used to localize generated content. If two @extensions reference the same class name, the last declared one will be used by the CSS engine. For example, redeclaring an extension class imported from another CSS style sheet may be useful to change its parameters.

How to write such extension class is explained in detail in the Chapter 7, All stylesheet extension points.

The extension class may have methods which have been written to dynamically evaluate property values. These methods are invoked using the following syntax: invoke(method_name, parameter, ...., parameter). Parameters are optional.

Example (Email schema used as an example in the Chapter 7, All stylesheet extension points):

from:before {
    content: invoke("localize", "From:");
}

In the above example, method localize of class StyleExtension is used to translate string "From:" to the language specified by the xml:lang attribute (if found on the email root element). For example, if xml:lang is set to fr (French), the generated content will contain "De:" instead of "From:".

Methods used to dynamically evaluate property values must have the following signature (see Chapter 7, All stylesheet extension points): com.xmlmind.xmledit.stylesheet.StyleValue Method(com.xmlmind.xmledit.stylesheet.StyleValue[] parameters, com.xmlmind.xmledit.doc.Node contextNode, com.xmlmind.xmledit.styled.ViewFactoryBase factory).

If several extensions classes have dynamic property value methods with identical names (even if this unlikely to happen), the method actually used by the CSS engine will be the method of the class first declared using @extension.

7.2.1. Invoking a static extension method

Alternatively invoke may be used to invoke a static extension method by specifying its fully qualified name. DocBook example:

link {
    tooltip-content: attr(linkend) 
      "\A \A " 
      invoke("com.xmlmind.xmleditapp.dndview.ExtensionMethods.bindingDescription",
             "docb.followLinkAt");
}

In the above example, the static method is called bindingDescription and it is found in “ordinary class”[1] com.xmlmind.xmleditapp.dndview.ExtensionMethods.



[1] That is, unlike an extension class, this class will not be instantiated by the CSS engine and it is not required to have a public constructor having the following signature: Constructor(java.lang.String[] parameters, com.xmlmind.xmledit.styled.ViewFactoryBase factory).