Bug 496271, automation config for Tb2.0.0.22 build1, p=joduinn, r=me
[mozilla-1.9.git] / content / xtf / readme.txt
blobf25783b3c52443909e27544f1fcda7b0cc0947df
1 XTF: An eXtensible Tag Framework
2 ================================
4 XTF allows you to extend Mozilla by implementing new XML elements in
5 XPCOM modules. It is not a C++-version of XBL: XTF elements can be
6 written in any XPCOM-compatible language. I myself tend to write most
7 elements in JavaScript.
9 XTF support needs to be explicitly switched on for Mozilla builds by
10 specifying the configure option '--enable-xtf' (add "ac_add_options
11 --enabl-xtf" to your .mozconfig).
13 To serve a particular namespace "urn:mycompany:mynamespace" with your
14 own XTF elements, create an XPCOM component that implements the
15 interface nsIXTFElementFactory, and register it with the component
16 manager under the contract id
17 "@mozilla.org/xtf/element-factory;1?namespace=urn:mycompany:mynamespace".
18 Whenever Mozilla encounters a tag in your namespace it will call your
19 factory's 'createElement()' function.  This function should either
20 return a new xtf element (an object implementing 'nsIXTFElement' and
21 some other interfaces, depending on type and required features), or
22 'null'. In the later case, the implementation will build a generic XML
23 element.
25 All interfaces relevant to XTF factory modules and XTF elements can be
26 found in mozilla/content/xtf/public/.  The implementation code itself
27 is mainly spread over the directories mozilla/content/xtf/ and
28 mozilla/layout/xtf/.
30 Binding outermost elements (document elements)
31 ============================================== 
33 Binding of outermost elements is not (yet) supported. Depending on
34 what you use xtf elements for, this might or might not be a
35 problem. If you use xtf to implement a whole new language, rather than
36 just widgets that will get used in html, xul, or svg docs, then you'll
37 probably want to wrap up your documents in an xml element for which
38 you provide some style (e.g. via a ua style sheet), so that things get
39 displayed instead of pretty printed. This outermost element can be in
40 your xtf-served namespace, as long as your xtf factory returns a
41 failure for this element's tagname. The implementation will then
42 generate a generic XML element for this element.
44 XTF and XUL
45 ===========
47 When using XTF elements in XUL documents, note that the owner document
48 (both wrapper.ownerDocument & wrapper.elementNode.ownerDocument) will
49 be null at the time of the onCreated() call. (For XML and SVG
50 documents, at least wrapper.ownerDocument should be non-null.)  This
51 is unfortunate, since it is often advantageous to build the visual
52 content tree at the time of the onCreated() call and not wait until
53 the visual content is explicitly requested, so that attributes set on
54 the xtf element can be mapped directly to elements in the visual
55 content tree. It is possible to build the content tree using a
56 different document than the ultimate target document, but this in turn
57 leads to some subtleties with XBL-bound content - see below.
60 XTF and XBL
61 ===========
63 XTF elements generally behave well in conjunction with XBL. There are
64 a few issues when using XBL-bound elements in an XTFVisual's
65 visualContent that arise from the fact that XBL bindings are attached
66 to elements at layout-time rather than content-tree contruction time:
67 Accessing an XBL-bound element's interfaces or JS object before
68 layout-time usually doesn't yield the expected result. E.g. a listbox
69 won't have the members 'appendItem', 'clearSelection', etc. before
70 layout-time, even if QI'ed for nsIDOMXULMenuListElement. Worse, if the
71 visual content has been constructed in a different document (because
72 the target doc wasn't available at the time of content tree
73 construction time - see above), then the JS object obtained before
74 layout time will be different to the one that will ultimately receive
75 the bound implementation, i.e. even QI'ing at a later stage will
76 fail. To work around these issues, XBL-bound content should a) either
77 be build as late as possible (i.e. when requested by the wrapper with
78 a call to nsIXTFVisual::GetVisualContent()) or b) if this is not a
79 possibility (e.g. because you would like to map attributes directly
80 into the visual content tree), all JS object references to the element
81 should be re-resolved at the time of the first layout (listen in to
82 DidLayout() notifications).
85 Bugs
86 ====
89 For xtf elements written in JS (and possibly C++ as well),
90 constructing a visual's visualContent using the same document as the
91 visual's leads to some nasty reference cycle which prevents the
92 wrapper, inner xtf element, anonymous content and possibly the whole
93 document from ever getting destroyed. A workaround is to construct the
94 visualContent in a different document (e.g. setting the document in
95 nsXMLContentBuilder to null, or not setting the document at all, will
96 lead to new content being build in a new temporary document).
100 XBL-bound elements behave strangely if *any* XUL content underneath
101 them is accessed from JS too early.
102 Example: 
104   <groupbox>
105    <caption><xtf:foo/></caption>
106    <label value="label text"/>
107   </groupbox>
109 If the JS-implemented xtf element 'foo' accesses any xul content
110 before it receives the 'didLayout' notification, the groupbox will not
111 be properly build (it will not contain the label text). 'Accessing xul
112 content' includes any operation that leads to a js wrapper being
113 constructed for a xul element. E.g. if the xtf element listens in to
114 parentChanged-notifications, a wrapper will be build for the
115 notification's 'parent' parameter and groupbox construction
116 mysteriously fails.
120 Some XUL interfaces can't be used via XPCOM and thus might not work as
121 expected. E.g. menulist's
122 nsIDOMXULSelectControlElement::insertItemAt() is supposed to return an
123 element of type nsIDOMXULSelectControlItemElement. However, since
124 menulist's XBL implementation of insertItemAt creates a xul element
125 which will only be bound when the next asynchronous layout occurs,
126 QI'ing to nsIDOMXULSelectControlItemElement fails. The result is that
127 the method call always fails when invoked through XPCOM.  A pragmatic
128 solution would be to change the XUL interface signatures to return
129 nsIDOMXULElement instead of nsIDOMXULSelectControlItemElement.
132 4.  
133 QI'ing a JS-implemented xtf element's wrapper from JS as in 
135   element.QueryInterface(Components.interface.nsIXTFPrivate);
137 occasionally hits the assertion
139   ###!!! ASSERTION: tearoff not empty in dtor: 
140   '!(GetInterface()||GetNative()||GetJSObject())', 
141   file /home/alex/devel/mozilla/js/src/xpconnect/src/xpcinlines.h, line 627
143 with the result that the QI succeeds (i.e. doesn't throw an exception)
144 but the interface methods/properties aren't available on the element
145 after the QI, even though element implements the given interface.
147 This seems to happen if GC kicks in *afer* the xtf element is being
148 queried for its interface ( resulting in the creation of an
149 nsXTFInterfaceAggregator) but *before* the nsXTFInterfaceAggregator
150 has been wrapped for JS use by XPCConvert::NativeData2JS().
152 The workaround is to a) either expose the interface via
153 getScriptingInterfaces (in which case it will be available to JS
154 callers automatically), or b) call QI until the interface is correctly
155 installed, e.g.:
157   while (!element.inner)
158     element.QueryInterface(Components.interface.nsIXTFPrivate);
160 With this code the QI should succeed in the first or second iteration.
164 07. October 2004 Alex Fritze <alex@croczilla.com>