Skip to content

Commit

Permalink
feat: experimental dangerouslyDisableHoisting prop
Browse files Browse the repository at this point in the history
And `dangerouslyDisableWhitespaceCollapsing`.
  • Loading branch information
jsamr committed Jun 4, 2021
1 parent 31bbff7 commit e6c7328
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 6 deletions.
75 changes: 70 additions & 5 deletions doc-tools/doc-pages/src/pages/PageConceptTRE.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import React from 'react';
import React, { PropsWithChildren } from 'react';
import Page from '../Page';
import useToolkit from '../toolkit/useToolkit';

function ListItemCode({ name, children }: PropsWithChildren<{ name: string }>) {
const { ListItem, InlineCode } = useToolkit();
return (
<ListItem>
<InlineCode>{name}</InlineCode>
{': '}
{children}
</ListItem>
);
}

export default function PageConceptTRE() {
const {
Acronym,
Expand Down Expand Up @@ -114,8 +125,8 @@ export default function PageConceptTRE() {
<Bold>The Hoisting Constraint</Bold> in the <Acronym name="TRT" />{' '}
results in enforcing <Bold>The View Constraint</Bold> at render
time. You can disable <Bold>hoisting</Bold> via{' '}
<Bold>TODO MAKE PROP AVAIL</Bold> prop, but be advised this is yet
experimental.
<RefRenderHtmlProp name="dangerouslyDisableHoisting" /> prop, but be
advised this is yet experimental.
</Paragraph>
</Section>
<Section title="Whitespace Collapsing">
Expand All @@ -127,12 +138,66 @@ export default function PageConceptTRE() {
CSS Text Module Level 3
</Hyperlink>{' '}
standard, by which unsignificant white-spaces are removed from the{' '}
<Acronym name="TRT" />.
<Acronym name="TRT" />. You can disable <Bold>hoisting</Bold> via{' '}
<RefRenderHtmlProp name="dangerouslyDisableWhitespaceCollapsing" />{' '}
prop, but be advised this is yet experimental.
</Paragraph>
</Section>
</Chapter>
<Chapter title="Anatomy of a TNode">
<Paragraph>Blah blah blah</Paragraph>
<Paragraph>
A <InlineCode>TNode</InlineCode> has the following fields:
</Paragraph>
<List>
<ListItemCode name="attributes">
The list of attributes attached to the underlying DOM Node.
</ListItemCode>
<ListItemCode name="id">
The id attached to the underlying DOM Node.
</ListItemCode>
<ListItemCode name="classes">
An array of classes associated with the underlying DOM Node.
</ListItemCode>
<ListItemCode name="domNode">
The underlying DOM Node, if present.
</ListItemCode>
<ListItemCode name="styles">
A <InlineCode>TStylesShape</InlineCode> record of styles grouped by
scopes.
</ListItemCode>
<ListItemCode name="tagName">
The tag name attached to the underlying DOM Node.
</ListItemCode>
<ListItemCode name="parent">
The parent <InlineCode>TNode</InlineCode>, if present, determined{' '}
<Bold>before hoisting</Bold>.
</ListItemCode>
<ListItemCode name="nodeIndex">
The position of this element relative to its parent,{' '}
<Bold>before hoisting</Bold> and{' '}
<Bold>after whitespace collapsing</Bold>.
</ListItemCode>
<ListItemCode name="children">
An array of <InlineCode>TNode</InlineCode> descendents to this node.
</ListItemCode>
<ListItemCode name="type">
The <Bold>type</Bold> of this <InlineCode>TNode</InlineCode>. Either{' '}
<Bold>text</Bold>, <Bold>phrasing</Bold>, <Bold>block</Bold>,{' '}
<Bold>document</Bold> or <Bold>empty</Bold>.
</ListItemCode>
<ListItemCode name="markers">
A registry of markers for this <InlineCode>TNode</InlineCode>.
</ListItemCode>
<ListItemCode name="snapshot()">
A utility function to create a JSX-like string representation of
this node and its children. <Bold>Very handy for debugging.</Bold>
</ListItemCode>
</List>
<Admonition type="warning">
The <InlineCode>styles</InlineCode> field <Bold>is not</Bold>{' '}
consumable as a React Native component <InlineCode>style</InlineCode>{' '}
prop.
</Admonition>
</Chapter>
<Chapter title="CSS Processing and Styles">
<Paragraph>Blah blah blah</Paragraph>
Expand Down
97 changes: 97 additions & 0 deletions doc-tools/doc-pages/src/pages/PageGuideCustomRenderers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default function PageGuideDomTampering() {
const {
Acronym,
Admonition,
Bold,
Header,
Paragraph,
Chapter,
Expand All @@ -27,6 +28,102 @@ export default function PageGuideDomTampering() {
<Header>
<Paragraph>How to implement custom renderers?</Paragraph>
</Header>
<Chapter title="Prerequisites">
<Paragraph>
The renderer API shipped since v6 is at the same time more strict and
more flexible. To get ready for this new API, you must understands
some basics of the transient render tree produced by the transient
render engine:
</Paragraph>
<List>
<ListItem>
During the transient render tree generation, every DOM node is
translated to a TNode.
</ListItem>
<ListItem>
TText nodes correspond to DOM text nodes (<Bold>anonymous</Bold>{' '}
TText nodes) or DOM elements which children are DOM text nodes (
<Bold>named</Bold> TText nodes). So a TText node cannot have
children, and its content is a string.
</ListItem>
<ListItem>
TPhrasing nodes can only have TText and TPhrasing nodes as children.
</ListItem>
<ListItem>TBlock nodes can have any children.</ListItem>
</List>
</Chapter>
<Chapter title="Options for Custom Rendering">
<Paragraph>
You can customize rendering at two steps of the flow:
</Paragraph>
</Chapter>
<Chapter title="Model-based Custom Rendering">
<List>
<ListItem>
<Bold>textual</Bold> for elements which can be translated to TText
or TPhrasing. Examples: &lt;Bold&gt;, &lt;Bold&gt; ...
</ListItem>
<ListItem>
<Bold>block</Bold> for elements which can only be translated to
TBlock. Examples: &lt;div&gt;, &lt;p&gt; ...
</ListItem>
<ListItem>
<Bold>mixed</Bold> (rare) for elements which can be translated to
TText, TPhrasing or TBlock. The sole mixed elements are &lt;a&gt;,
&lt;ins&gt; and &lt;del&gt;.
</ListItem>
<ListItem>
<Bold>none</Bold> for element which shall not be rendered.
</ListItem>
</List>
<Admonition type="tip">
<InlineCode>TDefaultRenderer</InlineCode> can receive{' '}
<InlineCode>onPress</InlineCode> prop,{' '}
<InlineCode>textProps</InlineCode> when rendering a{' '}
<InlineCode>Text</InlineCode> element, and{' '}
<InlineCode>viewProps</InlineCode> when rendering a{' '}
<InlineCode>View</InlineCode> element.
</Admonition>
</Chapter>
<Chapter title="Component-based Custom Rendering">
<List>
<ListItem>
<InlineCode>tnode</InlineCode>: the <InlineCode>TNode</InlineCode>{' '}
to render;
</ListItem>
<ListItem>
<InlineCode>TDefaultRenderer</InlineCode>: the default renderer for
this TNode;
</ListItem>
<ListItem>
<InlineCode>InternalRenderer</InlineCode>: the internal renderer for
this tagName;
</ListItem>
<ListItem>
<InlineCode>style</InlineCode>: the flatten style object which
should be passed to the root element returned by this component;
</ListItem>
<ListItem>
<InlineCode>key</InlineCode>: the key which shall be passed to the
root element returned by this component;
</ListItem>
<ListItem>
<InlineCode>textProps</InlineCode> to use when you render a{' '}
<InlineCode>Text</InlineCode>
-based element;
</ListItem>
<ListItem>
<InlineCode>viewProps</InlineCode> to use when you render a{' '}
<InlineCode>View</InlineCode>
-based element.
</ListItem>
<ListItem>
<InlineCode>type</InlineCode> to check if a{' '}
<InlineCode>Text</InlineCode> or <InlineCode>View</InlineCode> is
expected as the root element returned by this component.
</ListItem>
</List>
</Chapter>
</Page>
);
}
3 changes: 3 additions & 0 deletions packages/render-html/src/TRenderEngineProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ export const tRenderEngineProviderPropTypes: Record<
monospace: PropTypes.string
}),
setMarkersForTNode: PropTypes.func,
dangerouslyDisableHoisting: PropTypes.bool,
dangerouslyDisableWhitespaceCollapsing: PropTypes.bool,
selectDomRoot: PropTypes.func,
triggerTREInvalidationPropNames: PropTypes.arrayOf(PropTypes.string)
};

Expand Down
6 changes: 5 additions & 1 deletion packages/render-html/src/hooks/useTRenderEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export default function useTRenderEngine(props: TransientRenderEngineConfig) {
emSize,
setMarkersForTNode,
selectDomRoot,
dangerouslyDisableHoisting,
dangerouslyDisableWhitespaceCollapsing,
triggerTREInvalidationPropNames
} = props;
const isFontSupported = useMemo(() => {
Expand Down Expand Up @@ -76,7 +78,9 @@ export default function useTRenderEngine(props: TransientRenderEngineConfig) {
ignoreDomNode,
domVisitors,
setMarkersForTNode,
selectDomRoot
selectDomRoot,
dangerouslyDisableHoisting,
dangerouslyDisableWhitespaceCollapsing
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[...tbuilderDeps, isFontSupported]
Expand Down
18 changes: 18 additions & 0 deletions packages/render-html/src/shared-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,24 @@ export interface TransientRenderEngineConfig {
* @defaultValue `() => null`
*/
setMarkersForTNode?: SetMarkersForTNode;
/**
* **Experimental**
*
* Disable hoisting. Especially useful for rendering with react-native-web.
* Note that your layout might break in native!
*
* @defaultValue false
*/
dangerouslyDisableHoisting?: boolean;
/**
* **Experimental**
*
* Disable whitespace collapsing. Especially useful if your html is
* being pre-processed server-side with a minifier.
*
* @defaultValue false
*/
dangerouslyDisableWhitespaceCollapsing?: boolean;
/**
* Name of props which should trigger a rebuild of the Transient Render
* Engine (TRE).
Expand Down

0 comments on commit e6c7328

Please sign in to comment.