/* eslint-disable @typescript-eslint/no-unused-vars */ import React from 'react'; import Page from '../Page'; import ListItemCode from '../components/ListItemCode'; import useToolkit from '../toolkit/useToolkit'; import { TRenderEngine } from '@native-html/transient-render-engine'; const translateEngine = new TRenderEngine({ dangerouslyDisableHoisting: true, dangerouslyDisableWhitespaceCollapsing: true }); const hoistingEngine = new TRenderEngine({ dangerouslyDisableHoisting: false, dangerouslyDisableWhitespaceCollapsing: true }); const collapsingEngine = new TRenderEngine({ dangerouslyDisableHoisting: false, dangerouslyDisableWhitespaceCollapsing: false }); const source = ` This is phrasing content and this is too. `; export default function PageConceptTRE() { const { Acronym, Admonition, Bold, DList, DListItem, DListTitle, Header, Paragraph, Chapter, SourceDisplay, RefLibrary, RefRNSymbol, RefHtmlElement, RefCssProperty, RefRenderHtmlProp, RefRenderHTMLExport, RefHtmlAttr, RefDoc, RefTRE, RenderHtmlCard, Section, InlineCode, Hyperlink, List, ListItem, TNodeTransformDisplay, SvgFigure } = useToolkit(); return (
This article is an introduction to the {' '} architecture.
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.
To each standard tag is attached an element model, instance of the 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{' '} method. You can access default models via{' '} ; When registering a new tag with the{' '} {' '} static method. You will have to register custom and extended models with the{' '} prop, please refer to{' '} {' '} 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 true for{' '} void elements {' '} , e.g. DOM elements which can't have children. Will be true for those elements which children should not be translated. Useful for{' '} 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{' '} and a DOM . An object with three fields, text,{' '} view and native. Each field value is a props object that will be passed to the underlying native component at render time. Respecively, for , and all (catch-all). Serves the same purpose as{' '} reactNativeProps, but it's a function taking a as first argument, pre-generated props as second argument (such as{' '} accessibilityLabel derived from{' '} ) and the DOM{' '} as a third argument.
There are 4 content models that can be attached to a tag: For elements which can be translated to or{' '} . Examples:{' '} , {' '} ... For elements which can only be translated to{' '} . Examples: ,{' '} , ... (rare) for elements which can be translated to{' '} , or{' '} . The sole mixed elements are{' '} , and{' '} . For element which shall not be rendered and will be translated to{' '} . Examples:{' '} , {' '} ... A powerful feature of the Foundry engine is that the models attached to a tag name can be customized! See the{' '} page.
The construction is broadly comprised of three steps.
Each DOM element is translated to a . The translation will obide by the following rules: The root of the document will be translated to a{' '} node. This node has a special{' '} context field which holds metadata harvested in the DOM element (see{' '} ). Text nodes will be translated to , 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{' '} will be merged into a{' '} with tagName set to "span". DOM elements which content model is textual with multiple children will be translated to{' '} nodes. DOM elements with children which content model is{' '} mixed will be translated to{' '} if they only have{' '} or children,{' '} otherwise. DOM elements which content model is{' '} block will be translated to {' '} nodes. Finally, DOM elements which content model is{' '} none will be translated to . , comments and{' '} DOM nodes will be ignored. 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{' '} for more details. Below is an example of a translation transformation from HTML to : You will notice that a has been added, and the root is an instance of . This process is called normalization, and is also performed by Web browsers.
The hoisting phase consists in enforcing a basic constraint: A node should only have{' '} , and{' '} nodes as children. Therefore, any child of a{' '} node will be recursively{' '} hoisted to the parent, until it meets that constraint. This constraint must be enforced to insure that a React Native{' '} elements have no{' '} children, since it will break the default box model and might lead to bugs and inconsistencies. This constraint is depicted below: React Native elements should not have{' '} elements as children. On one hand will be translated to{' '} elements and on the other hand{' '} and nodes will be translated to elements. Therefore, enforcing The Hoisting Constraint in the{' '} results in enforcing{' '} The View Constraint at render time. You can disable{' '} hoisting via{' '} prop, but be advised this is yet experimental. Below is an example of translation + hoisting{' '} transformation from HTML to :
The whitespace collapsing phase consists in implementing the algorithm associated with the{' '} CSS property, depicted in the{' '} CSS Text Module Level 3 {' '} standard, by which unsignificant white-spaces are removed from the{' '} . You can disable hoisting via{' '} {' '} prop, but be advised this is yet experimental. Below is an example of{' '} translating + hoisting + collapsing transformation from HTML to :
A has the following relevant fields (see{' '} for a reference): The list of attributes attached to the underlying DOM Node. The 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 , if present, determined{' '} before hoisting. The position of this element relative to its parent,{' '} after hoisting and collapsing. An array of descendents to this node. The type of this . Either{' '} text, phrasing, block,{' '} document or empty. A registry of markers for this . 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. form an abstraction in which one{' '} provides semantic information to itself and all its descendants. For example, {' '} 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,{' '} , and{' '} 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{' '} and attributes. Finally, you can customize the markers extraction logic with{' '} prop and the eponym HTML model field.
); }