Table of Contents
In this chapter, we will show where several elements on the end product reference page can be traced back to their origins in the sources.
Note | |
---|---|
At this point we strongly, strongly encourage the reader to undergo an investigation of XPath 1.0 and to find an XML editor which is capable of doing live XPath queries. (Oxygen XML Editor works.) Then, actually run some queries on a js2doc dataset. Without this exercise, the remainder of this chapter will be utter gobbledygook. |
Region | Docbook Element | Relevant Templates | js2doc Element |
---|---|---|---|
A | header navigation | parameters.xsl: navig.showtitles, suppress.header.navigation | - |
B | <refentry xreflabel="<text>" id="LzText" ...> | <xsl:template match="property" mode="refentry"> ("main class template") | <property id="LzText" name="LzText" .../> |
C | header navigation | parameters.xsl: navig.showtitles, suppress.header.navigation | - |
D | <refsynopsisdiv> | js2doc2dbk.xsl: insert-refinfo | |
E | <refsect1> | js2doc2dbk.xsl: generated in main class template | |
F | <refpurpose> | js2doc2dbk.xsl: generated in main class template |
All of the elements in the live example are contained within a <div class="informalexample"> (in html) which comes from a
<informalexample role="live-example">
docbook element. That, in turn, comes from an <example> in the js2doc, which appears as something that matches this XPath
query: "/js2doc/property/doc/text/example"
. All the way back in the source (WEB-INF/lps/lfc/views/LzText.lzs
, in this case), here's what this started out as:
/** * <p>This class is used for non-editable text fields (as opposed to * <tagname>inputtext</tagname>. A text field can be initalized * with text content at compile time.</p> * * <example> * <canvas height="30"> * <text>Hello world!</text> * </canvas> * </example> ... */
Many, many templates are involved in generating the inside of that live example. This is so complicated that we'll leave the table format used above, and instead break it down element by element, in excruciating detail.
In the output HTML, there's just a little script here:
<div class="embedded-canvas"> <script language="JavaScript" type="text/javascript"> lz.embed.swf({url: 'programs/LFC-$10.lzx?lzt=swf', id: 'd0e165236SWF', history: false, width: 500, height: 30 }); </script> </div>
The lz.embed.swf
function is defined in embed-compressed.js, which is included in the page's head. The embed-compressed.js file comes from
$LPS_HOME/lps/includes/embed-compressed.js
, and calling lz.embed.swf
generates an embedded flash player:
<div id="d0e165236SWFContainer" style="width: 500px; height: 30px;">
<embed id="d0e165236SWF" width="500" height="30" align="middle" pluginspage="http://www.macromedia.com/go/getflashplayer"
type="application/x-shockwave-flash" allowscriptaccess="sameDomain" swliveconnect="true"
flashvars="lzt=swf&lzr=swf8&id=d0e165236SWF" name="d0e165236SWF" wmode="window"
bgcolor="#ffffff" quality="high" src="programs/LFC-$10.lzx?lzt=swf&lzr=swf8"/>
</div>
The highlighted section above is the important part; it tells the flash player what content to load. In this case, it's loading
the results of an http query programs/LFC-$10.lzx?lzt=swf&lzr=swf8
, which, if you remember your OpenLaszlo query args, means compile the program named programs/LFC-$10.lzx for the swf8 runtime and return it as a compiled object, with no wrapper.
The file programs/LFC-$10.lzx
contains just exactly the code that was in the <example>
tag in the lzs source. Somehow, probably in dbkpreprocessexamples.xsl
, the contents of the <example>
tag were extracted and tucked away in docs/src/build/developers/programs/LFC-$10.lzx
, and then that file was copied from the build directory to the output directory, as docs/developers/programs/LFC-$10.lzx
.
lz.embed.swf
was inserted by a template in common-html.xsl
: <xsl:template match="programlisting[@language='lzx' and textobject/textdata/@fileref]">
. This template both embeds the live example and handles the program listing and edit button, described below.
The program listing seems like it should be simple, but notice that it's pretty-printed. The html output here looks like this:
<pre class="programlisting">
<span>
<span class="markup"><</span>
<code class="sgmltag-element">canvas</code>
<code class="sgmltag-attribute">height</code>="
<code class="sgmltag-attvalue">30</code>"
<span class="markup">></span>
Notice that this sgmltag
stuff isn't present in the lfcref.dbk intermediate file; it must be inserted by the docbook processing itself. Indeed, it
is inserted by the docbook customization layer, in the lzx-pretty-print.xsl
worksheet, which is included by common-html.xsl
, which is in turn invoked in the ant task, book.html.generate
.
The edit button ties together a few separate threads of complexity. The windows builds, in particular, are subject to troubles
here. The edit button must point an external jsp (editor.jsp) at the program file associated with this program listing. We
leave the details of this as an exercise to the reader, except to note that the insertion of the edit button is guarded by
the statement <xsl:if test="$live">
which in turn consults the value of a variable computed like this:
<xsl:variable name="live" select="ancestor::example[@role='live-example'] or ancestor::informalexample[@role='live-example']"/>
Remember the docbook element that we found in the docbook intermediate file? <informalexample role="live-example">
matches the second option in the XPath query for $live
above, and that's why this example is live.
The attributes table is generated by a set of coherent templates and patterns. There's a lot of them, but they're not very
complicated. It is all run by this template, in js2doc2dbk.xsl
:
<xsl:template match="property" mode="refentry-details">
This template calls the describe-members
template repeatedly with different parameters, depending on which kind of members are being described. For the attributes
table, the describe-members
template calls the describe-members-grid
template, which generates a <refsect2> element, which in turn generates the "Attributes" header indicated in region P. Region
Q is the <thead> element of a docbook <informaltable>, and regions R, S, and T are each instances of the docbook element <row>
Each row (regions R, S, T) in the attributes table are elements of the result of this XPath, which is passed in as the
members
parameter to describe-members-grid
:
$ivars[not &isevent;] | $svars[not &isevent;]
$ivars
is a local variable containing descriptions of the instance variables for the current class:
<xsl:variable name="ivars" select="&objectvalue;/property[@name='__ivars__']/object/property[&isvisible;]"/>
and $svars
is a local variable containing descriptions of the "setters" for the current class:
<xsl:variable name="svars" select="&objectvalue;/property[@name='setters']/object/property[&isvisible;]"/>
The value of these variables is a result tree fragment; it's not just the name of the variables. This becomes important
when we descend into the describe-members
template.
Note | |
---|---|
Review the table in Section 3.2, “JavaScript to js2doc” to get a feel for why these XPath's return the desired result sets. |
This all ends up down in the member-data-row
template in js2doc2dbk.xsl, which fill in columns K, L, M, N, and O in the diagram above. Turn to LzText.lzs, to find where
these variables were declared:
/** * @lzxtype numberExpression (region L) * @modifiers read-only (region O) */ var maxlength; (region K)
The reference for a function is generated by the call to <xsl:apply-templates select="." mode="describe-member">
in the template named describe-members-list
in js2doc2dbk.xsl
. select="." mode="desribe-member"
means apply whatever templates match the current element in the describe-member mode.
That takes us to the template
<xsl:template match="initarg|property" mode="describe-member">
also in js2doc2dbk.xsl. Dancing through a variety of complex template matching, the XSL ends up examining mostly these elements of the js2doc:
<class extends="LzView" inherits="LzFormatter"> <property access="private" id="LzText.tagname" name="tagname" value="text"><!-- region 6 --> <doc> <tag name="modifiers"> <text>override</text> </tag> </doc> </property> ... <property id="LzText.prototype" name="prototype" access="public"> <object> <property id="LzText.prototype.format" name="format"<!-- regions 1, 2 --> access="public"> <doc> <text>Formatted output. Formats its arguments using <xref linkend="LzFormatter.prototype.formatToString"/> and sets the text of the view to the result.</text><!-- region 7 --> </doc> <function> <parameter name="control" <!-- region 3, 9 --> type="string"> <!-- region 10 --> <doc> <text>A control string where % indicates the conversion of the corresponding argument</text><!-- region 11 --> </doc> </parameter> <parameter name="args" <!-- region 3, 9 --> type="[*]"> <!-- region 10 --> <doc> <text>arguments to be formatted according to the control string</text><!-- region 11 --> </doc> </parameter> </function> </property> ... </object> </property> </class>
To carry this reasoning all the way back to the javascript code definining the method, in WEB-INF/lps/lfc/views/LzText.lzs
:
/** * Formatted output. * Formats its arguments using <xref * linkend="LzFormatter.prototype.formatToString"/> and sets the text of the * view to the result. * * @param string control: A control string where % indicates the * conversion of the corresponding argument * * @param [*] args: arguments to be formatted according to the * control string */ function format (control:String, ...args) { this.setAttribute('text', this.formatToString.apply(this, [control].concat(args)).toString().toHTML()); }
Copyright © 2002-2010 Laszlo Systems, Inc. All Rights Reserved. Unauthorized use, duplication or distribution is strictly prohibited. This is the proprietary information of Laszlo Systems, Inc. Use is subject to license terms.