mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-10 18:00:15 +01:00
255 lines
8.8 KiB
HTML
255 lines
8.8 KiB
HTML
|
<html>
|
||
|
<head>
|
||
|
<title>Compiled Stylesheets</title>
|
||
|
<style>
|
||
|
.comment {
|
||
|
font-style: italic;
|
||
|
}
|
||
|
</style>
|
||
|
</head>
|
||
|
<body>
|
||
|
|
||
|
<h1>Compiled Stylesheets</h1>
|
||
|
|
||
|
<h2>Overview</h2>
|
||
|
<p>
|
||
|
There are 5 main entities: Stylesheet-loaders, stylesheet-compiler,
|
||
|
stylesheet, execution-state and processor. The normal usecase is:
|
||
|
<ol>
|
||
|
<li>Set up a stylesheet-loader to read a resource.
|
||
|
<li>Let it feed events to the stylesheet-compiler.
|
||
|
<li>The compiler creates a stylesheet.
|
||
|
<li>Init an execution-state with stylesheet, initial node, global
|
||
|
parameters and an outputhandler factory.
|
||
|
<li>Start the processor.
|
||
|
</ol>
|
||
|
</p>
|
||
|
|
||
|
<h2>Main classes</h2>
|
||
|
<h3>txStylesheet</h3>
|
||
|
<h4>Description:</h4>
|
||
|
<p>
|
||
|
This class represents a compiled stylesheet. If the stylesheet
|
||
|
contains imported and/or included stylesheets they are all compiled
|
||
|
into a single <code>txStylesheet</code>-object.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
The stylesheet contains functions for getting the different top-level
|
||
|
entities that exist in a stylesheet, such as attribute-sets, templates
|
||
|
and global variables. The <code>txStylesheet</code> owns all objects
|
||
|
in the stylesheet, including the instructions in templates and
|
||
|
variables.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
A single <code>txStylesheet</code>-object can be used for multiple
|
||
|
transformations, even running concurrently. Once a stylesheet is
|
||
|
compiled it is never changed, nor does it carry any state.
|
||
|
</p>
|
||
|
|
||
|
<h4>Typical functions:</h4>
|
||
|
<pre>
|
||
|
txInstruction* findTemplate(Node* aNode,
|
||
|
const txExpandedName& aMode,
|
||
|
txIMatchContext* aContext,
|
||
|
ImportFrame* aImportedBy,
|
||
|
ImportFrame** aImportFrame);
|
||
|
txDecimalFormat* getDecimalFormat(const txExpandedName& aName);
|
||
|
txInstruction* getAttributeSet(const txExpandedName& aName);
|
||
|
txOutputFormat* getOutputFormat();
|
||
|
</pre>
|
||
|
|
||
|
<h3>txStylesheetCompiler</h3>
|
||
|
<h4>Description:</h4>
|
||
|
<p>
|
||
|
This class gets "events" from a stylesheet loader and creates a
|
||
|
compiled stylesheet. The class calls back through a callback interface
|
||
|
to the stylesheet-loader to load included and imported stylesheets.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
The output from the <code>txStylesheetCompiler</code> is a
|
||
|
ready-to-use <code>txStylesheet</code> object.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
To load included and imported stylesheets the
|
||
|
<code>txStylesheetCompiler</code> calls the loader through a
|
||
|
<code>txIIncludeLoaderCallback</code> interface suppling the url to
|
||
|
load, and the <code>txStylesheetCompiler</code>-object that the loader
|
||
|
should use to notify its events to. There is a separate
|
||
|
<code>txStylesheetCompiler</code>-object for each sub-stylesheet,
|
||
|
however only the initial <code>txStylesheetCompiler</code> will create
|
||
|
a <code>txStylesheet</code>-object.
|
||
|
</p>
|
||
|
|
||
|
<p class="comment">
|
||
|
Do we want to refcount txIIncludeLoaderCallback? It might otherwise
|
||
|
be hairy to deal with loads being cancled or failing.
|
||
|
</p>
|
||
|
|
||
|
<h4>Typical functions:</h4>
|
||
|
<pre>
|
||
|
nsresult startElement(PRInt32 aNamespaceID, txAtom* aLocalName,
|
||
|
txAtom* aPrefix, txStylesheetAttr* aAttributes,
|
||
|
PRInt32 aAttrCount);
|
||
|
nsresult endElement();
|
||
|
nsresult characters(const String& aStr);
|
||
|
nsresult doneLoading();
|
||
|
void cancel(nsresult aError);
|
||
|
</pre>
|
||
|
|
||
|
<h3>txHandlerTable</h3>
|
||
|
<h4>Description:</h4>
|
||
|
<p>
|
||
|
To process the elements and textnodes in the stylesheet the
|
||
|
<code>txStylesheetCompiler</code> calls different
|
||
|
stylesheet-compile-handlers. Which handler to call is decided by two
|
||
|
things:
|
||
|
<ol>
|
||
|
<li>The "mode" of the compiler, i.e. is it processing a top-level
|
||
|
element? Is it processing the contents of a template? Is it
|
||
|
processing the children of a xsl:attribute-set element?
|
||
|
<li>The name and namespace of the element. (Of course, this doesn't
|
||
|
apply to textnodes).
|
||
|
</ol>
|
||
|
The handlers are global static C-style functions. The handlers
|
||
|
processes the elements and textnodes in the stylesheet and
|
||
|
creates instructions and toplevel-items.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
To find which handler to call the compiler uses
|
||
|
<code>txHandlerTable</code>-objects. The <code>txHandlerTable</code>
|
||
|
contains a list of these stylesheet-compile-handlers keyed on
|
||
|
element-name. It also contains a handler for text and a handler for
|
||
|
LRE-elements.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
There are different <code>txHandlerTable</code>-objects for different
|
||
|
"modes" of the compiler. There is one for handling top-level elements,
|
||
|
one for handling template-parameters, one for handling the contents of
|
||
|
a xsl:attribte-set element, one for handling the contents of
|
||
|
unsupported extension-elements etc. The
|
||
|
<code>txStylesheetCompiler</code> always has a current
|
||
|
<code>txHandlerTable</code> which is used to find the handler to call.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
The <code>txHandlerTable</code>s are initialized from static structs.
|
||
|
This is to avoid having large pieces of code containing very similar
|
||
|
code.
|
||
|
</p>
|
||
|
|
||
|
<h4>Typical functions:</h4>
|
||
|
<pre>
|
||
|
nsresult init(txHandlerTableData* aTableData);
|
||
|
txElementHandler* find(PRInt32 aNamespaceID, txAtom* aLocalName);
|
||
|
</pre>
|
||
|
|
||
|
<h3>txStylesheetCompilerState</h3>
|
||
|
<p class="comment">
|
||
|
Do we want to rename this txStylesheetCompilerInternal?
|
||
|
</p>
|
||
|
<h4>Description:</h4>
|
||
|
<p>
|
||
|
This class manages the internal state of the
|
||
|
<code>txStylesheetCompiler</code>. The reason that this is a separate
|
||
|
class is so that the <code>txStylesheetCompiler</code> can keep a clean
|
||
|
interface towards the stylesheet-loaders.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
The <code>txStylesheetCompilerState</code>-class is used both by the
|
||
|
<code>txStylesheetCompiler</code>-class and by the
|
||
|
stylesheet-compile-handlers.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
The class has three main purposes:
|
||
|
<ul>
|
||
|
<li>
|
||
|
Keep track of the current context. Such as:
|
||
|
<ul>
|
||
|
<li>Namespace mappings.
|
||
|
<li>Base-URI.
|
||
|
<li>Extension-element namespaces.
|
||
|
<li>Whitespace preservation mode.
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>
|
||
|
Store the state that the stylesheet-compile-handlers need. For
|
||
|
example the current xsl:for-each loop to add xsl:sort-elements to.
|
||
|
</li>
|
||
|
<li>
|
||
|
Keep track of the current <code>txHandlerTable</code>, so that the
|
||
|
right stylesheet-compile-handler is called for elements and text.
|
||
|
</li>
|
||
|
</ul>
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
This is the class that implements <code>txIParseContext</code> during
|
||
|
all stylesheet-compilation.
|
||
|
</p>
|
||
|
|
||
|
<h4>Typical functions:</h4>
|
||
|
<pre>
|
||
|
nsresult pushHandlerTable(txHandlerTable* aTable);
|
||
|
nsresult parsePattern(const String& aPattern, txPattern** aResult);
|
||
|
nsresult parseExpr(const String& aExpr, Expr** aResult);
|
||
|
nsresult addToplevelItem(txToplevelItem* aItem);
|
||
|
nsresult openInstructionContainer(txInstructionContainer* aContainer);
|
||
|
nsresult addInstruction(txInstruction* aInstruction);
|
||
|
</pre>
|
||
|
|
||
|
<h3>txExecutionState</h3>
|
||
|
<h4>Description:</h4>
|
||
|
<p>
|
||
|
This class manages all state during the execution of a stylesheet.
|
||
|
This includes
|
||
|
<ul>
|
||
|
<li>The current <code>txIEvalContext</code>.
|
||
|
<li>The next <code>txInstruction</code> to be executed.
|
||
|
<li>Variables that are in scope.
|
||
|
<li>Values of global variables and keys.
|
||
|
<li>Current result-handler.
|
||
|
<li>Stylesheet being executed.
|
||
|
</ul>
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
The <code>txExecutionState</code> also acts as a general-purpose stack
|
||
|
that instructions can use to communicate between each other. The class
|
||
|
is the owner of this data and will delete it as appropriate if the
|
||
|
execution aborts.
|
||
|
</p>
|
||
|
|
||
|
<h4>Typical functions:</h4>
|
||
|
<pre>
|
||
|
nsresult pushEvalContext(txIEvalContext* aContext);
|
||
|
txIEvalContext* popEvalContext();
|
||
|
nsresult pushString(const nsAString& aStr);
|
||
|
void popString(nsAString& aStr);
|
||
|
txInstruction* getNextInstruction();
|
||
|
nsresult runTemplate(txInstruction* aInstruction);
|
||
|
void gotoInstruction(txInstruction* aNext);
|
||
|
</pre>
|
||
|
|
||
|
<h3>txXSLTProcessor</h3>
|
||
|
<h4>Description:</h4>
|
||
|
<p>
|
||
|
This is a fully static class that contains the main loop for executing
|
||
|
a stylsheet.
|
||
|
</p>
|
||
|
|
||
|
<h4>Typical functions:</h4>
|
||
|
<pre>
|
||
|
nsresult execute(txExecutionState& aEs);
|
||
|
</pre>
|
||
|
|
||
|
</body>
|
||
|
</html>
|