Skip to content

Commit

Permalink
remove capital i from interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
pokornyd committed Jan 12, 2024
1 parent 434037e commit 8070231
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 88 deletions.
32 changes: 16 additions & 16 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,33 @@ This module also allows you to manipulate the intermediate JSON structure prior
Output of `nodeParse` and `browserParse` methods is a simple tree structure, defined by the following interface.

```ts
interface IOutputResult {
children: IDomNode[];
interface ParseResult {
children: DomNode[];
}
```

`IDomNode` is a union of `IDomHtmlNode` and `IDomTextNode`, which together define the full HTML tree structure:
`DomNode` is a union of `DomHtmlNode` and `DomTextNode`, which together define the full HTML tree structure:

![Resolved DOMTree](../media/domtree.jpg)

The structure can be modified using `transformToJson` method which accepts `IOutputResult` as the first argument and an optional `customResolvers` object, which can contain two methods `resolveIDomTextNode` and `resolveIDomHtmlNode`. Each method is responsible for manipulating its respective node type, allowing you to transform the output as per your requirements.
The structure can be modified using `transformToJson` method which accepts `ParseResult` as the first argument and an optional `customResolvers` object, which can contain two methods `resolveDomTextNode` and `resolveDomHtmlNode`. Each method is responsible for manipulating its respective node type, allowing you to transform the output as per your requirements.

Example use of the `transformToJson` method:

```ts
const transformJsonWithCustomResolvers = (result: IOutputResult) => transformToJson(result, {
resolveIDomTextNode: customResolveIDomTextNode,
resolveIDomHtmlNode: customResolveIDomHtmlNode
const transformJsonWithCustomResolvers = (result: ParseResult) => transformToJson(result, {
resolveDomTextNode: customResolveDomTextNode,
resolveDomHtmlNode: customResolveDomHtmlNode
})


const customResolveIDomTextNode: ResolveIDomTextNodeType = node => {
const customResolveDomTextNode: ResolveDomTextNodeType = node => {
return {
text: node.content
};
}

const customResolveIDomHtmlNode: ResolveIDomHtmlNodeType = (node, traverse) => {
const customResolveDomHtmlNode: ResolveDomHtmlNodeType = (node, traverse) => {
let result = {
tag: node.tagName
};
Expand Down Expand Up @@ -99,14 +99,14 @@ const transformedTree = transformJsonWithCustomResolvers(originalTree);
```

## Resolution
If you prefer working with a tree structure, rather than Portable text, you can implement resolution around the `IOutputResult` tree. See examples below.
If you prefer working with a tree structure, rather than Portable text, you can implement resolution around the `ParseResult` tree. See examples below.

#### HTML string (TypeScript)

```ts
const parsedTree = browserParse(richTextValue);

const resolve = (domNode: IDomNode): string => {
const resolve = (domNode: DomNode): string => {
switch (node.type) {
case "tag": {
if (isLinkedItem(node)) {
Expand Down Expand Up @@ -137,7 +137,7 @@ const resolvedHtml = parsedTree.children.map(resolve).join("");
Resolution method implementation varies based on the use cases. This is just a showcase to present how to get information for node specific data.

```ts
const resolveHtmlElement = (node: IDomHtmlNode): string => {
const resolveHtmlElement = (node: DomHtmlNode): string => {
const attributes = Object.entries(node.attributes)
.map(([key, value]) => `${key}="${value}"`)
.join(" ");
Expand All @@ -152,7 +152,7 @@ const resolveHtmlElement = (node: IDomHtmlNode): string => {
[Image attributes](https://kontent.ai/learn/reference/openapi/delivery-api/#section/Images-in-rich-text) contain just the information parsed from HTML. Image context is being returned as a [part of the Delivery API response](https://kontent.ai/learn/reference/openapi/delivery-api/#section/Rich-text-element) - in the sample below being loaded by `getImage` method.

```ts
resolveImage = (node: IDomHtmlNode): string => {
resolveImage = (node: DomHtmlNode): string => {
const imageId = node.attributes["data-asset-id"];

const image = getImage(imageId);
Expand All @@ -163,7 +163,7 @@ resolveImage = (node: IDomHtmlNode): string => {
[Link attributes](https://kontent.ai/learn/reference/openapi/delivery-api/#section/Links-in-rich-text) contain just the information parsed from HTML. Link context is being returned as a [part of the Delivery API response](https://kontent.ai/learn/reference/openapi/delivery-api/#section/Rich-text-element) - in the sample below being loaded by `getLink` method.

```ts
const resolveItemLink = (node: IDomHtmlNode): string => {
const resolveItemLink = (node: DomHtmlNode): string => {
const linkId = node.attributes["data-item-id"];

const link = getLink(linkId);
Expand All @@ -175,7 +175,7 @@ const resolveItemLink = (node: IDomHtmlNode): string => {
[Linked item attributes](https://kontent.ai/learn/reference/openapi/delivery-api/#section/Content-items-and-components-in-rich-text) contain just the information parsed from HTML. Linked item context is being returned as a [part of the Delivery API response](https://kontent.ai/learn/reference/openapi/delivery-api/#section/Rich-text-element) - in the sample below being loaded by `getLinkedContentItem` method.

```ts
const resolveLinkedItem = (node: IDomHtmlNode): string => {
const resolveLinkedItem = (node: DomHtmlNode): string => {
const itemCodeName = node.attributes["data-codename"];

const item = getLinkedContentItem(itemCodeName);
Expand Down Expand Up @@ -204,7 +204,7 @@ const RichText: React.FC<Props> = ({element, className}) => {

useEffect(() => {
const parsedTree = browserParse(element.value);
const resolve = (domNode: IDomNode, index: number): JSX.Element => {
const resolve = (domNode: DomNode, index: number): JSX.Element => {
switch (domNode.type) {
case 'tag': {
// traverse tree recursively
Expand Down
6 changes: 3 additions & 3 deletions src/parser/browser/rich-text-browser-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ isElementNode,
isRootNode,
isTextNode
} from "../../utils/index.js"
import { IDomNode, IOutputResult } from "../parser-models.js";
import { DomNode, ParseResult } from "../parser-models.js";

export const parse = (input: string): IOutputResult => {
export const parse = (input: string): ParseResult => {
const parser = new DOMParser();
const sanitizedInput = input.replaceAll(getAllNewLineAndWhiteSpace, '');

Expand All @@ -24,7 +24,7 @@ export const parse = (input: string): IOutputResult => {
}
}

const parseInternal = (document: Node): IDomNode => {
const parseInternal = (document: Node): DomNode => {
if (isElementNode(document)) {
return {
tagName: document.tagName.toLowerCase(),
Expand Down
6 changes: 3 additions & 3 deletions src/parser/node/rich-text-node-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { Node } from "node-html-parser";

import { getAllNewLineAndWhiteSpace } from '../../utils/index.js';
import { isElementNode, isRootNode, isTextNode } from "../../utils/node-parser-utils.js";
import { IDomNode, IOutputResult } from '../parser-models.js';
import { DomNode, ParseResult } from '../parser-models.js';


export const parse = (input: string): IOutputResult => {
export const parse = (input: string): ParseResult => {
const node = NodeHtmlParser.parse(input.replaceAll(getAllNewLineAndWhiteSpace, ''));

if (!isRootNode(node)) {
Expand All @@ -18,7 +18,7 @@ export const parse = (input: string): IOutputResult => {
}
};

const parseInternal = (node: Node): IDomNode => {
const parseInternal = (node: Node): DomNode => {
if (isElementNode(node)) {
return {
tagName: node.tagName.toLowerCase(),
Expand Down
12 changes: 6 additions & 6 deletions src/parser/parser-models.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/**
* Union type of tags and text nodes.
*/
export type IDomNode = IDomHtmlNode | IDomTextNode;
export type DomNode = DomHtmlNode | DomTextNode;

/**
* Represents a text node.
*/
export interface IDomTextNode {
export interface DomTextNode {
type: "text";
/**
* Text content.
Expand All @@ -17,7 +17,7 @@ export interface IDomTextNode {
/**
* Represents a HTML tag.
*/
export interface IDomHtmlNode {
export interface DomHtmlNode {
type: "tag";
/**
* Name of the HTML tag.
Expand All @@ -30,12 +30,12 @@ export interface IDomHtmlNode {
/**
* Array of childnodes.
*/
children: IDomNode[];
children: DomNode[];
}

/**
* A tree structure representing a result of the `parse` method.
*/
export interface IOutputResult {
children: IDomNode[];
export interface ParseResult {
children: DomNode[];
}
30 changes: 15 additions & 15 deletions src/transformers/json-transformer/json-transformer.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
import { IDomHtmlNode, IDomNode, IDomTextNode, IOutputResult } from "../../parser/index.js"
import { DomHtmlNode, DomNode, DomTextNode, ParseResult } from "../../parser/index.js"
import { isText } from "../../utils/index.js"

export type ResolveIDomTextNodeType = ((node: IDomTextNode) => unknown) | null
export type ResolveIDomHtmlNodeType = ((node: IDomHtmlNode, traverse: (node: IDomNode) => unknown) => unknown) | null
export type ResolveDomTextNodeType = ((node: DomTextNode) => unknown) | null
export type ResolveDomHtmlNodeType = ((node: DomHtmlNode, traverse: (node: DomNode) => unknown) => unknown) | null

type CustomResolversType = {
resolveIDomTextNode: ResolveIDomTextNodeType
resolveIDomHtmlNode: ResolveIDomHtmlNodeType
resolveDomTextNode: ResolveDomTextNodeType
resolveDomHtmlNode: ResolveDomHtmlNodeType
}

export type TransformIDomNodeType = (
node: IDomNode,
export type TransformDomNodeType = (
node: DomNode,
customResolvers: CustomResolversType
) => unknown;

export const transformToJson = (
result: IOutputResult,
result: ParseResult,
customResolvers?: CustomResolversType
) => {
if (!customResolvers) {
return result.children
}

return result.children.map(node => transformIDomNode(node, customResolvers))
return result.children.map(node => transformDomNode(node, customResolvers))
}

const nodeIdentity = (node: IDomNode) => node
const nodeIdentity = (node: DomNode) => node

const transformIDomNode: TransformIDomNodeType = (
node: IDomNode,
const transformDomNode: TransformDomNodeType = (
node: DomNode,
customResolvers: CustomResolversType
) => {
const {resolveIDomHtmlNode, resolveIDomTextNode} = customResolvers;
const {resolveDomHtmlNode, resolveDomTextNode} = customResolvers;
if (isText(node)) {
return resolveIDomTextNode ? resolveIDomTextNode(node) : nodeIdentity(node);
return resolveDomTextNode ? resolveDomTextNode(node) : nodeIdentity(node);
}
return resolveIDomHtmlNode ? resolveIDomHtmlNode(node, (node) => transformIDomNode(node, customResolvers)) : nodeIdentity(node)
return resolveDomHtmlNode ? resolveDomHtmlNode(node, (node) => transformDomNode(node, customResolvers)) : nodeIdentity(node)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { PortableTextBlock,PortableTextListItemType } from '@portabletext/types'

import { IDomHtmlNode, IDomNode, IOutputResult } from "../../parser/index.js"
import { DomHtmlNode, DomNode, ParseResult } from "../../parser/index.js"
import {
PortableTextItem,
PortableTextLink,
Expand Down Expand Up @@ -56,10 +56,10 @@ import {
* This function takes the parsed tree of a rich text content, flattens it to an array of intermediate
* Portable Text Objects, and then composes and merges these objects into an array of Portable Text Blocks.
*
* @param {IOutputResult} parsedTree The parsed tree structure representing the rich text content.
* @param {ParseResult} parsedTree The parsed tree structure representing the rich text content.
* @returns {PortableTextObject[]} An array of Portable Text Blocks representing the structured content.
*/
export const transformToPortableText = (parsedTree: IOutputResult): PortableTextObject[] => {
export const transformToPortableText = (parsedTree: ParseResult): PortableTextObject[] => {
const flattened = flatten(parsedTree.children);

return composeAndMerge(flattened) as PortableTextObject[];
Expand Down Expand Up @@ -195,20 +195,20 @@ const mergeRowsAndCells: MergePortableTextItemsFunction = (itemsToMerge) => {
const composeAndMerge = compose(mergeTablesAndRows, mergeRowsAndCells, mergeBlocksAndSpans, mergeSpansAndMarks);

/**
* Flattens a tree of IDomNodes into an array of PortableTextObjects.
* Flattens a tree of DomNodes into an array of PortableTextObjects.
*
* This function recursively processes a tree structure, transforming each node to its corresponding
* PortableTextItem, picking a suitable method using `transformNode`. The resulting array is flat, to be
* processed with subsequent merge methods.
*
* @param {IDomNode[]} nodes - The array of IDomNodes to be flattened.
* @param {DomNode[]} nodes - The array of DomNodes to be flattened.
* @param {number} [depth=0] - The current depth in the tree, used for list items.
* @param {IDomHtmlNode} [lastListElement] - The last processed list element, used for tracking nested lists.
* @param {DomHtmlNode} [lastListElement] - The last processed list element, used for tracking nested lists.
* @param {PortableTextListItemType} [listType] - The type of the current list being processed (bullet or number).
* @returns {PortableTextItem[]} The flattened array of PortableTextItems.
*/
const flatten = (nodes: IDomNode[], depth = 0, lastListElement?: IDomHtmlNode, listType?: PortableTextListItemType): PortableTextItem[] => {
return nodes.flatMap((node: IDomNode): PortableTextItem[] => {
const flatten = (nodes: DomNode[], depth = 0, lastListElement?: DomHtmlNode, listType?: PortableTextListItemType): PortableTextItem[] => {
return nodes.flatMap((node: DomNode): PortableTextItem[] => {
let currentListType = listType;

if (isElement(node)) {
Expand Down Expand Up @@ -243,22 +243,22 @@ const flatten = (nodes: IDomNode[], depth = 0, lastListElement?: IDomHtmlNode, l
});
};

const transformNode = (node: IDomNode, depth: number, listType?: PortableTextListItemType): PortableTextItem[] => {
const transformNode = (node: DomNode, depth: number, listType?: PortableTextListItemType): PortableTextItem[] => {
if (isText(node)) {
return [transformText(node)];
} else {
return transformElement(node, depth, listType);
}
}

const transformElement = (node: IDomHtmlNode, depth: number, listType?: PortableTextListItemType): PortableTextItem[] => {
const transformElement = (node: DomHtmlNode, depth: number, listType?: PortableTextListItemType): PortableTextItem[] => {
const transformFunction = transformMap[node.tagName as ValidElement];

return transformFunction(node, depth, listType!);
}

const transformImage: TransformElementFunction = (node) => {
const imageTag = node.children[0] as IDomHtmlNode;
const imageTag = node.children[0] as DomHtmlNode;
const block = createImageBlock(uid().toString());

block.asset._ref = node.attributes['data-image-id'];
Expand Down Expand Up @@ -322,8 +322,8 @@ const transformExternalLink: TransformLinkFunction = (node) => {
}

const transformTable: TransformElementFunction = (node) => {
const tableBody = node.children[0] as IDomHtmlNode;
const tableRow = tableBody.children[0] as IDomHtmlNode;
const tableBody = node.children[0] as DomHtmlNode;
const tableRow = tableBody.children[0] as DomHtmlNode;
const numCols = tableRow.children.length;

return [createTable(uid().toString(), numCols)];
Expand Down
28 changes: 14 additions & 14 deletions src/utils/common-utils.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,52 @@
import { IDomHtmlNode, IDomNode, IDomTextNode } from "../index.js";
import { DomHtmlNode, DomNode, DomTextNode } from "../index.js";

export const isOrderedListBlock = (node: IDomHtmlNode): boolean =>
export const isOrderedListBlock = (node: DomHtmlNode): boolean =>
node.tagName === 'ol';

export const isUnorderedListBlock = (node: IDomHtmlNode): boolean =>
export const isUnorderedListBlock = (node: DomHtmlNode): boolean =>
node.tagName === 'ul';

export const isListBlock = (node: IDomHtmlNode): boolean =>
export const isListBlock = (node: DomHtmlNode): boolean =>
isUnorderedListBlock(node) || isOrderedListBlock(node)

export const isListItem = (node: IDomHtmlNode): boolean =>
export const isListItem = (node: DomHtmlNode): boolean =>
node.tagName === 'li';

export const isExternalLink = (node: IDomHtmlNode): boolean =>
export const isExternalLink = (node: DomHtmlNode): boolean =>
isAnchor(node) && !node.attributes['data-item-id'];

export const isAnchor = (node: IDomHtmlNode): boolean =>
export const isAnchor = (node: DomHtmlNode): boolean =>
node.tagName === 'a';

/**
* Returns `true` for text nodes and type guards the node as `IDomTextNode`.
* Returns `true` for text nodes and type guards the node as `DomTextNode`.
*/
export const isText = (node: IDomNode): node is IDomTextNode =>
export const isText = (node: DomNode): node is DomTextNode =>
node.type === 'text';

/**
* Returns `true` for HTML nodes and type guards the node as `IDomHtmlNode`.
* Returns `true` for HTML nodes and type guards the node as `DomHtmlNode`.
*/
export const isElement = (node: IDomNode): node is IDomHtmlNode =>
export const isElement = (node: DomNode): node is DomHtmlNode =>
node.type === 'tag';

/**
* Returns `true` if the node is a linked item node (`<object></object>`).
*/
export const isLinkedItem = (node: IDomNode): boolean =>
export const isLinkedItem = (node: DomNode): boolean =>
isElement(node) &&
node.tagName === 'object' &&
node.attributes['type'] === 'application/kenticocloud';
/**
* Returns `true` if the node is a rich text image node (`<figure></figure>`).
*/
export const isImage = (node: IDomNode): boolean =>
export const isImage = (node: DomNode): boolean =>
isElement(node) &&
node.tagName === 'figure' &&
node.attributes['data-image-id'] ? true : false;

/**
* Returns `true` if the node is a link to a content item.
*/
export const isItemLink = (node: IDomHtmlNode): boolean =>
export const isItemLink = (node: DomHtmlNode): boolean =>
isAnchor(node) && !isExternalLink(node);
Loading

0 comments on commit 8070231

Please sign in to comment.