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:
β
contentModelHow should this tag be translated? See next chapter.
β
isVoidWill be
truefor void elements , e.g. DOM elements which can't have children.β
isOpaqueWill 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, forβText, β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.β
<script>, comments and β<style>DOM nodes will be ignored.
note
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:
note
Hoisting#
The hoisting phase consists in enforcing a basic constraint:
The Hoisting 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):
β
attributesThe list of attributes attached to the underlying DOM Node.
β
idThe id attached to the underlying DOM Node.
β
classesAn array of classes associated with the underlying DOM Node.
β
domNodeThe underlying DOM Node, if present.
β
tagNameThe tag name attached to the underlying DOM Node.
β
parentThe parent β
TNode, if present, determined before hoisting.β
nodeIndexThe position of this element relative to its parent, after hoisting and collapsing.
β
childrenAn array of β
TNodedescendents to this node.β
typeThe type of this β
TNode. Either text, phrasing, block, document or empty.β
markersA registry of markers for this β
TNode. See explaination in below section.β
hasClassA utility function to check if this node has the provided CSS class.
β
snapshotA utility function to create a JSX-like string representation of this node and its children. Very handy for debugging.
warning
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.