Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 10 additions & 14 deletions packages/element/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ Concatenate two or more React children objects.

_Parameters_

- _childrenArguments_ `...?Object`: Array of children arguments (array of arrays/strings/objects) to concatenate.
- _childrenArguments_ `ReactNode[][]`: - Array of children arguments (array of arrays/strings/objects) to concatenate.

_Returns_

- `Array`: The concatenated value.
- `ReactNode[]`: The concatenated value.

### createContext

Expand Down Expand Up @@ -110,11 +110,11 @@ You would have something like this as the conversionMap value:
_Parameters_

- _interpolatedString_ `string`: The interpolation string to be parsed.
- _conversionMap_ `Record<string, Element>`: The map used to convert the string to a react element.
- _conversionMap_ `Record< string, ReactElement >`: The map used to convert the string to a react element.

_Returns_

- `Element`: A wp element.
- `ReactElement`: A wp element.

### createPortal

Expand Down Expand Up @@ -209,7 +209,7 @@ Checks if the provided WP element is empty.

_Parameters_

- _element_ `*`: WP element to check.
- _element_ `unknown`: WP element to check.

_Returns_

Expand Down Expand Up @@ -312,13 +312,9 @@ Serializes a React element to string.

_Parameters_

- _element_ `import('react').ReactNode`: Element to serialize.
- _context_ `[Object]`: Context object.
- _legacyContext_ `[Object]`: Legacy context object.

_Returns_

- `string`: Serialized element.
- _element_ `React.ReactNode`:
- _context_ `any`:
- _legacyContext_ `Record< string, any >`:

### startTransition

Expand All @@ -342,12 +338,12 @@ Switches the nodeName of all the elements in the children object.

_Parameters_

- _children_ `?Object`: Children object.
- _children_ `ReactNode`: Children object.
- _nodeName_ `string`: Node name.

_Returns_

- `?Object`: The updated children object.
- `ReactNode`: The updated children object.

### unmountComponentAtNode

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
/**
* Internal dependencies
*/
import { createElement, cloneElement, Fragment, isValidElement } from './react';
import {
createElement,
cloneElement,
Fragment,
isValidElement,
type Element as ReactElement,
} from './react';

/**
* Object containing a React element.
*
* @typedef {import('react').ReactElement} Element
*/

let indoc, offset, output, stack;
let indoc: string;
let offset: number;
let output: ( string | ReactElement )[];
let stack: Frame[];

/**
* Matches tags in the localized string
Expand All @@ -23,28 +26,40 @@ let indoc, offset, output, stack;
* isClosing: The closing slash, if it exists.
* name: The name portion of the tag (strong, br) (if )
* isSelfClosed: The slash on a self closing tag, if it exists.
*
* @type {RegExp}
*/
const tokenizer = /<(\/)?(\w+)\s*(\/)?>/g;

/**
* The stack frame tracking parse progress.
*
* @typedef Frame
*
* @property {Element} element A parent element which may still have
* @property {number} tokenStart Offset at which parent element first
* appears.
* @property {number} tokenLength Length of string marking start of parent
* element.
* @property {number} [prevOffset] Running offset at which parsing should
* continue.
* @property {number} [leadingTextStart] Offset at which last closing element
* finished, used for finding text between
* elements.
* @property {Element[]} children Children.
*/
interface Frame {
/**
* A parent element which may still have nested children not yet parsed.
*/
element: ReactElement;

/**
* Offset at which parent element first appears.
*/
tokenStart: number;

/**
* Length of string marking start of parent element.
*/
tokenLength: number;

/**
* Running offset at which parsing should continue.
*/
prevOffset?: number;

/**
* Offset at which last closing element finished, used for finding text between elements.
*/
leadingTextStart?: number | null;

/**
* Children.
*/
children: ( string | ReactElement )[];
}

/**
* Tracks recursive-descent parse state.
Expand All @@ -53,27 +68,27 @@ const tokenizer = /<(\/)?(\w+)\s*(\/)?>/g;
* parsed.
*
* @private
* @param {Element} element A parent element which may still have
* nested children not yet parsed.
* @param {number} tokenStart Offset at which parent element first
* appears.
* @param {number} tokenLength Length of string marking start of parent
* element.
* @param {number} [prevOffset] Running offset at which parsing should
* continue.
* @param {number} [leadingTextStart] Offset at which last closing element
* finished, used for finding text between
* elements.
* @param element A parent element which may still have
* nested children not yet parsed.
* @param tokenStart Offset at which parent element first
* appears.
* @param tokenLength Length of string marking start of parent
* element.
* @param prevOffset Running offset at which parsing should
* continue.
* @param leadingTextStart Offset at which last closing element
* finished, used for finding text between
* elements.
*
* @return {Frame} The stack frame tracking parse progress.
* @return The stack frame tracking parse progress.
*/
function createFrame(
element,
tokenStart,
tokenLength,
prevOffset,
leadingTextStart
) {
element: ReactElement,
tokenStart: number,
tokenLength: number,
prevOffset?: number,
leadingTextStart?: number | null
): Frame {
return {
element,
tokenStart,
Expand Down Expand Up @@ -105,13 +120,16 @@ function createFrame(
* }
* ```
*
* @param {string} interpolatedString The interpolation string to be parsed.
* @param {Record<string, Element>} conversionMap The map used to convert the string to
* a react element.
* @param interpolatedString The interpolation string to be parsed.
* @param conversionMap The map used to convert the string to
* a react element.
* @throws {TypeError}
* @return {Element} A wp element.
* @return A wp element.
*/
const createInterpolateElement = ( interpolatedString, conversionMap ) => {
const createInterpolateElement = (
interpolatedString: string,
conversionMap: Record< string, ReactElement >
): ReactElement => {
indoc = interpolatedString;
offset = 0;
output = [];
Expand All @@ -138,35 +156,48 @@ const createInterpolateElement = ( interpolatedString, conversionMap ) => {
*
* @private
*
* @param {Object} conversionMap The map being validated.
* @param conversionMap The map being validated.
*
* @return {boolean} True means the map is valid.
* @return True means the map is valid.
*/
const isValidConversionMap = ( conversionMap ) => {
const isObject = typeof conversionMap === 'object';
const isValidConversionMap = (
conversionMap: Record< string, ReactElement >
): boolean => {
const isObject =
typeof conversionMap === 'object' && conversionMap !== null;
const values = isObject && Object.values( conversionMap );
return (
isObject &&
values.length &&
values.length > 0 &&
values.every( ( element ) => isValidElement( element ) )
);
};

type TokenType = 'no-more-tokens' | 'self-closed' | 'opener' | 'closer';
type TokenResult =
| [ TokenType & 'no-more-tokens' ]
| [
TokenType & ( 'self-closed' | 'opener' | 'closer' ),
string,
number,
number,
];

/**
* This is the iterator over the matches in the string.
*
* @private
*
* @param {Object} conversionMap The conversion map for the string.
* @param conversionMap The conversion map for the string.
*
* @return {boolean} true for continuing to iterate, false for finished.
* @return true for continuing to iterate, false for finished.
*/
function proceed( conversionMap ) {
function proceed( conversionMap: Record< string, ReactElement > ): boolean {
const next = nextToken();
const [ tokenType, name, startOffset, tokenLength ] = next;
const stackDepth = stack.length;
const leadingTextStart = startOffset > offset ? offset : null;
if ( ! conversionMap[ name ] ) {
if ( name && ! conversionMap[ name ] ) {
addText();
return false;
}
Expand Down Expand Up @@ -254,9 +285,9 @@ function proceed( conversionMap ) {
*
* @private
*
* @return {Array} An array of details for the token matched.
* @return An array of details for the token matched.
*/
function nextToken() {
function nextToken(): TokenResult {
const matches = tokenizer.exec( indoc );
// We have no more tokens.
if ( null === matches ) {
Expand All @@ -281,7 +312,7 @@ function nextToken() {
*
* @private
*/
function addText() {
function addText(): void {
const length = indoc.length - offset;
if ( 0 === length ) {
return;
Expand All @@ -298,7 +329,7 @@ function addText() {
* @param {Frame} frame The Frame containing the child element and it's
* token information.
*/
function addChild( frame ) {
function addChild( frame: Frame ): void {
const { element, tokenStart, tokenLength, prevOffset, children } = frame;
const parent = stack[ stack.length - 1 ];
const text = indoc.substr(
Expand Down Expand Up @@ -326,7 +357,7 @@ function addChild( frame ) {
* helps capture any remaining nested text nodes in
* the element.
*/
function closeOuterElement( endOffset ) {
function closeOuterElement( endOffset: number ): void {
const { element, leadingTextStart, prevOffset, tokenStart, children } =
stack.pop();

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@
* Copyright (c) 2015-present, Facebook, Inc.
*
*/
const Platform = {
OS: 'web',
select: ( spec ) => ( 'web' in spec ? spec.web : spec.default ),
isWeb: true,

/**
* Specification for platform-specific value selection.
*/
type PlatformSelectSpec< T > = {
web?: T;
default?: T;
};

/**
* Component used to detect the current Platform being used.
* Use Platform.OS === 'web' to detect if running on web environment.
Expand All @@ -30,4 +34,23 @@ const Platform = {
* } );
* ```
*/
const Platform = {
/** Platform identifier. Will always be `'web'` in this module. */
OS: 'web' as const,

/**
* Select a value based on the platform.
*
* @template T
* @param spec - Object with optional platform-specific values.
* @return The selected value.
*/
select< T >( spec: PlatformSelectSpec< T > ): T | undefined {
return 'web' in spec ? spec.web : spec.default;
},

/** Whether the platform is web */
isWeb: true,
};

export default Platform;
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
*/
import { Children, createElement } from './react';

/** @typedef {{children: string} & import('react').ComponentPropsWithoutRef<'div'>} RawHTMLProps */
/**
* Props for the RawHTML component.
*/
export type RawHTMLProps = {
children: string | string[];
} & React.ComponentPropsWithoutRef< 'div' >;

/**
* Component used to render unescaped HTML.
Expand All @@ -24,9 +29,12 @@ import { Children, createElement } from './react';
* of strings. Other props will be passed through
* to the div wrapper.
*
* @return {JSX.Element} Dangerously-rendering component.
* @return Dangerously-rendering component.
*/
export default function RawHTML( { children, ...props } ) {
export default function RawHTML( {
children,
...props
}: RawHTMLProps ): JSX.Element {
let rawHtml = '';

// Cast children as an array, and concatenate each element if it is a string.
Expand Down
Loading
Loading