Transient Render Engine
This article is an introduction to the TRE architecture.
Element Models
Element models form the building block of the engine. These models specify how a DOM element of a peculiar tag should be translated. You can tamper with those models and add you own models, making this library extremely customizable.
HTMLElementModel
To each standard tag is attached an element model, instance of the HTMLElementModel class. Such model has multiple fields describing different behaviors related to translation of those DOM elements. There are two ways to instantiate an element model:
When changing an existing tag model with the
HTMLElementModel.extendmethod. You can access default models via defaultHTMLElementModels;When registering a new tag with the
HTMLElementModel.fromCustomModelstatic method.
You will have to register custom and extended models with the customHTMLElementModels prop, please refer to Custom Rendering for examples. Below is a list of fields that can be set when defining or extending HTML element models:
How should this tag be translated? See next chapter.
Will be
truefor void elements , e.g. DOM elements which can't have children.Will be
truefor those elements which children should not be translated. Useful for <svg>and other custom markups.Mixed User-Agent styles, e.g. default styles for this element. This is how default styles are set for tags.
A function which returns mixed UA styles given a minimal
TNodeDescriptorand a DOM Node.An object with three fields,
text,viewandnative. Each field value is a props object that will be passed to the underlying native component at render time. Respecively, forText, Viewand all (catch-all).Serves the same purpose as
reactNativeProps, but it's a function taking a TNodeas first argument, pre-generated props as second argument (such asaccessibilityLabelderived from aria-label) and the DOM Elementas a third argument.
HTMLContentModel
There are 4 content models that can be attached to a tag:
For elements which can be translated to
TTextor TPhrasing. Examples: <span>, <strong>...For elements which can only be translated to
TBlock. Examples: <div>, <p>, <article>...(rare) for elements which can be translated to
TText, TPhrasingor TBlock. The sole mixed elements are <a>, <ins>and <del>.For element which shall not be rendered and will be translated to
TEmpty. Examples: <button>, <map>...
A powerful feature of the Foundry engine is that the models attached to a tag name can be customized! See the Custom Rendering page.
Steps
The TRT construction is broadly comprised of three steps.
Translation
Each DOM element is translated to a TNode. The translation will obide by the following rules:
The root of the document will be translated to a
TDocumentnode. This node has a specialcontextfield which holds metadata harvested in the <head>DOM element (see DocumentMetadata).Text nodes will be translated to
TText, and will be merged with a parent DOM element if the parent's content model is textual or mixed when they are its only child. For example, a Text node with no siblings which parent is a <span>will be merged into a TTextwithtagNameset to "span".DOM elements which content model is textual with multiple children will be translated to
TPhrasingnodes.DOM elements with children which content model is mixed will be translated to
TPhrasingif they only have TPhrasingor TTextchildren, TBlockotherwise.DOM elements which content model is block will be translated to
TBlocknodes.Finally, DOM elements which content model is none will be translated to
TEmpty.
A DOM element might be untranslatable for a variety of reasons. For example, its name is not a standard HTML5 element and there is no custom HTML element model registered for it. An other reason is that it is an interactive element such as a form, input or button.
In addition, inline styles, User Agent styles and mixed styles are processed by the CSS Processor, see CSS Processing for more details.
Below is an example of a translation transformation from HTML to TRT:
Hoisting
The hoisting phase consists in enforcing a basic constraint:
Therefore, any TBlock child of a TPhrasing node will be recursively hoisted to the parent, until it meets that constraint. This constraint must be enforced to insure that a React Native Text elements have no View children, since it will break the default box model and might lead to bugs and inconsistencies. This constraint is depicted below:
On one hand TBlock will be translated to View elements and on the other hand TPhrasing and TText nodes will be translated to Text elements. Therefore, enforcing The Hoisting Constraint in the TRT results in enforcing The View Constraint at render time. You can disable hoisting via dangerouslyDisableHoisting prop, but be advised this is yet experimental.
Below is an example of translation + hoisting transformation from HTML to TRT:
Whitespace Collapsing
The whitespace collapsing phase consists in implementing the algorithm associated with the white-space CSS property, depicted in the CSS Text Module Level 3 standard, by which unsignificant white-spaces are removed from the TRT. You can disable hoisting via dangerouslyDisableWhitespaceCollapsing prop, but be advised this is yet experimental.
Below is an example of translating + hoisting + collapsing transformation from HTML to TRT:
Anatomy of a TNode
A TNode has the following relevant fields (see TNodeShape for a reference):
The list of attributes attached to the underlying DOM Node.
idThe id attached to the underlying DOM Node.
An array of classes associated with the underlying DOM Node.
The underlying DOM Node, if present.
The tag name attached to the underlying DOM Node.
The parent
TNode, if present, determined before hoisting.The position of this element relative to its parent, after hoisting and collapsing.
An array of
TNodedescendents to this node.
typeThe type of this
TNode. Either text, phrasing, block, document or empty.A registry of markers for this
TNode. See explaination in below section.A utility function to check if this node has the provided CSS class.
A utility function to create a JSX-like string representation of this node and its children. Very handy for debugging.
The styles field which is not listed here is not consumable as a React Native component style prop.
Markers
Markers form an abstraction in which one TNode provides semantic information to itself and all its descendants. For example, <ins> elements, which stand for "insertion" of content in the context of an edit will provide the edits marker with value "ins" to all its descendants. Similarly, <a>, <ol> and <ul> elements will set their own markers. List markers such as olNestLevel are integers which are incremented each time a list is nested.
Markers can also be derived from attributes. This is the case with dir and lang attributes. Finally, you can customize the markers extraction logic with setMarkersForTNode prop and the eponym HTML model field.