Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/HubSpot/draft-convert

Extensibly serialize & deserialize Draft.js ContentState with HTML.
https://github.com/HubSpot/draft-convert

draft draft-js javascript react rich-text-editor

Last synced: about 2 months ago
JSON representation

Extensibly serialize & deserialize Draft.js ContentState with HTML.

Lists

README

        

# **draft-convert**

[![npm version](https://badge.fury.io/js/draft-convert.svg)](https://www.npmjs.com/package/draft-convert) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

*Extensibly serialize & deserialize [**Draft.js**](http://draftjs.org/) content with HTML*

*See [**draft-extend**](http://github.com/HubSpot/draft-extend) for more on how to use draft-convert with plugins*

## Installation

`npm install draft-convert --save` or `yarn add draft-convert`

Jump to:

- [convertToHTML](#converttohtml)
- [convertFromHTML](#convertfromhtml)
- [Middleware functions](#middleware-functions)

## convertToHTML

**Extensibly serialize Draft.js [`ContentState`](http://facebook.github.io/draft-js/docs/api-reference-content-state.html#content) to HTML.**

**Basic usage:**
```javascript
const html = convertToHTML(editorState.getCurrentContent());
```
**Advanced usage:**
```javascript
// convert to HTML with blue text, paragraphs, and links
const html = convertToHTML({
styleToHTML: (style) => {
if (style === 'BOLD') {
return ;
}
},
blockToHTML: (block) => {
if (block.type === 'PARAGRAPH') {
return

;
}
},
entityToHTML: (entity, originalText) => {
if (entity.type === 'LINK') {
return {originalText};
}
return originalText;
}
})(editorState.getCurrentContent());

// convert content state to HTML with functionality defined in the plugins applied
const html = compose(
FirstPlugin,
SecondPlugin,
ThirdPlugin
)(convertToHTML)(editorState.getCurrentContent());
```

`styleToHTML`, `blockToHtml`, and `entityToHTML` are functions that take Draft content data and may return a `ReactElement` or an object of shape `{start, end}` defining strings for the beginning and end tags of the style, block, or entity. `entityToHTML` may return either a string with or without HTML if the use case demands it. `blockToHTML` also may return an optional `empty` property to handle alternative behavior for empty blocks. To use this along with a `ReactElement` return value an object of shape `{element: ReactElement, empty: ReactElement}` may be returned. If no additional functionality is necessary `convertToHTML` can be invoked with just a `ContentState` to serialize using just the default Draft functionality. `convertToHTML` can be passed as an argument to a plugin to modularly augment its functionality.

**Legacy alternative conversion options**
`styleToHTML` and `blockToHTML` options may be plain objects keyed by style or block type with values of `ReactElement` s or `{start, end}` objects. These objects will eventually be removed in favor of the functions described above.

**Type info:**
```javascript
type ContentStateConverter = (contentState: ContentState) => string

type Tag =
ReactElement |
{start: string, end: string, empty?: string} |
{element: ReactElement, empty?: ReactElement}

type RawEntity = {
type: string,
mutability: DraftEntityMutability,
data: Object
}

type RawBlock = {
type: string,
depth: number,
data?: object,
text: string
}

type convertToHTML = ContentStateConverter | ({
styleToHTML?: (style: string) => Tag,
blockToHTML?: (block: RawBlock) => Tag),
entityToHTML?: (entity: RawEntity, originalText: string) => Tag | string
}) => ContentStateConverter
```

## convertFromHTML

**Extensibly deserialize HTML to Draft.js [`ContentState`](http://facebook.github.io/draft-js/docs/api-reference-content-state.html#content).**

**Basic usage:**
```javascript
const editorState = EditorState.createWithContent(convertFromHTML(html));
```

**Advanced usage:**
```javascript
// convert HTML to ContentState with blue text, links, and at-mentions
const contentState = convertFromHTML({
htmlToStyle: (nodeName, node, currentStyle) => {
if (nodeName === 'span' && node.style.color === 'blue') {
return currentStyle.add('BLUE');
} else {
return currentStyle;
}
},
htmlToEntity: (nodeName, node, createEntity) => {
if (nodeName === 'a') {
return createEntity(
'LINK',
'MUTABLE',
{url: node.href}
)
}
},
textToEntity: (text, createEntity) => {
const result = [];
text.replace(/\@(\w+)/g, (match, name, offset) => {
const entityKey = createEntity(
'AT-MENTION',
'IMMUTABLE',
{name}
);
result.push({
entity: entityKey,
offset,
length: match.length,
result: match
});
});
return result;
},
htmlToBlock: (nodeName, node) => {
if (nodeName === 'blockquote') {
return {
type: 'blockquote',
data: {}
};
}
}
})(html);

// convert HTML to ContentState with functionality defined in the draft-extend plugins applied
const fromHTML = compose(
FirstPlugin,
SecondPlugin,
ThirdPlugin
)(convertFromHTML);
const contentState = fromHTML(html);
```

If no additional functionality is necessary `convertToHTML` can be invoked with just an HTML string to deserialize using just the default Draft functionality. Any `convertFromHTML` can be passed as an argument to a plugin to modularly augment its functionality. A `flat` option may be provided to force nested block elements to split into flat, separate blocks. For example, the HTML input `

line one
linetwo

` will produce two `unstyled` blocks in `flat` mode.

**Type info:**
```javascript
type HTMLConverter = (html: string, {flat: ?boolean}, DOMBuilder: ?Function, generateKey: ?Function) => ContentState

type EntityKey = string

type convertFromHTML = HTMLConverter | ({
htmlToStyle: ?(nodeName: string, node: Node) => DraftInlineStyle,
htmlToBlock: ?(nodeName: string, node: Node) => ?(DraftBlockType | {type: DraftBlockType, data: object} | false),
htmlToEntity: ?(
nodeName: string,
node: Node,
createEntity: (type: string, mutability: string, data: object) => EntityKey,
getEntity: (key: EntityKey) => Entity,
mergeEntityData: (key: string, data: object) => void,
replaceEntityData: (key: string, data: object) => void
): ?EntityKey,
textToEntity: ?(
text: string,
createEntity: (type: string, mutability: string, data: object) => EntityKey,
getEntity: (key: EntityKey) => Entity,
mergeEntityData: (key: string, data: object) => void,
replaceEntityData: (key: string, data: object) => void
) => Array<{entity: EntityKey, offset: number, length: number, result: ?string}>
}) => HTMLConverter
```

## Middleware functions

Any conversion option for `convertToHTML` or `convertFromHTML` may also accept a middleware function of shape `(next) => (…args) => result` , where `…args` are the normal configuration function paramaters and `result` is the expected return type for that function. These functions can transform results of the default conversion included in `convertToHTML` or `convertFromHTML` by leveraging the result of `next(...args)`. These middleware functions are most useful when passed as the result of composition of [`draft-extend`](http://github.com/HubSpot/draft-extend) plugins. If you choose to use them independently, a `__isMiddleware` property must be set to `true` on the function for `draft-convert` to properly handle it.