diff --git a/packages/draft-js-export-html/README.md b/packages/draft-js-export-html/README.md index 95282c8f..3827b98c 100644 --- a/packages/draft-js-export-html/README.md +++ b/packages/draft-js-export-html/README.md @@ -165,6 +165,11 @@ let options = { let html = stateToHTML(contentState, options); ``` +### `entityRenderFn` + +It is passed an [`entity`](https://draftjs.org/docs/api-reference-entity.html) object +and should return a string representing the entity in the html output. + ## Contributing If you want to help out, please open an issue to discuss or join us on [Slack](https://draftjs.herokuapp.com/). diff --git a/packages/draft-js-export-html/src/stateToHTML.js b/packages/draft-js-export-html/src/stateToHTML.js index d90b7fac..d95f5a86 100644 --- a/packages/draft-js-export-html/src/stateToHTML.js +++ b/packages/draft-js-export-html/src/stateToHTML.js @@ -37,14 +37,17 @@ type StyleMap = {[styleName: string]: RenderConfig}; type BlockStyleFn = (block: ContentBlock) => ?RenderConfig; type EntityStyleFn = (entity: Entity) => ?RenderConfig; +type EntityRenderFn = (entity: Entity, text: string) => ?string; type InlineStyleFn = (style: DraftInlineStyle) => ?RenderConfig; + type Options = { inlineStyles?: StyleMap; inlineStyleFn?: InlineStyleFn; blockRenderers?: BlockRendererMap; blockStyleFn?: BlockStyleFn; entityStyleFn?: EntityStyleFn; + entityRenderFn?: EntityRenderFn; defaultBlockTag?: ?string; }; @@ -372,7 +375,9 @@ class MarkupGenerator { .map(([entityKey, stylePieces]) => { let content = stylePieces .map(([text, styleSet]) => { - let content = encodeContent(text); + let content = (entityKey && + this.options.entityRenderFn && this.options.entityRenderFn(this.contentState.getEntity(entityKey), text)) + || encodeContent(text); for (let styleName of this.styleOrder) { // If our block type is CODE then don't wrap inline code elements. if (styleName === CODE && blockType === BLOCK_TYPE.CODE) { diff --git a/packages/draft-js-export-html/typings/index.d.ts b/packages/draft-js-export-html/typings/index.d.ts index ec40b149..3bc45cd8 100644 --- a/packages/draft-js-export-html/typings/index.d.ts +++ b/packages/draft-js-export-html/typings/index.d.ts @@ -5,6 +5,7 @@ declare module 'draft-js-export-html' { type BlockStyleFn = (block: draftjs.ContentBlock) => RenderConfig|undefined; type EntityStyleFn = (entity: draftjs.EntityInstance) => RenderConfig|undefined; + type EntityRenderFn = (entity: draftjs.EntityInstance, text: string) => string|undefined; type BlockRenderer = (block: draftjs.ContentBlock) => string; type RenderConfig = { element?: string; @@ -18,6 +19,7 @@ declare module 'draft-js-export-html' { blockRenderers?: { [blockType: string]: BlockRenderer }; blockStyleFn?: BlockStyleFn; entityStyleFn?: EntityStyleFn; + entityRenderFn?: EntityRenderFn; } export function stateToHTML(content: draftjs.ContentState, options?: Options): string; diff --git a/packages/draft-js-import-element/README.md b/packages/draft-js-import-element/README.md index 9ecf69bb..2932993c 100644 --- a/packages/draft-js-import-element/README.md +++ b/packages/draft-js-import-element/README.md @@ -65,6 +65,13 @@ stateFromElement(element, { }); ``` +- `inlineElements`: Array of (lowercase) tag names which should be handled as inline tags. Example: +```js +stateFromElement(element, { + inlineElements: ['my-first-custom-tag', 'my-second-custom-tag'] +}); +``` + ## License This software is [BSD Licensed](/LICENSE). diff --git a/packages/draft-js-import-element/src/stateFromElement.js b/packages/draft-js-import-element/src/stateFromElement.js index 2f2b546c..cc245369 100644 --- a/packages/draft-js-import-element/src/stateFromElement.js +++ b/packages/draft-js-import-element/src/stateFromElement.js @@ -83,6 +83,7 @@ type Options = { blockTypes?: {[key: string]: string}; customBlockFn?: CustomBlockFn; customInlineFn?: CustomInlineFn; + inlineElements?: string[]; }; type DataMap = {[key: string]: T}; @@ -403,10 +404,12 @@ class ContentGenerator { processNode(node: DOMNode) { if (node.nodeType === NODE_TYPE_ELEMENT) { + let {inlineElements} = this.options; // $FlowIssue let element: DOMElement = node; let tagName = element.nodeName.toLowerCase(); - if (INLINE_ELEMENTS.hasOwnProperty(tagName)) { + if (INLINE_ELEMENTS.hasOwnProperty(tagName) + || (inlineElements && inlineElements.find((el) => el === tagName))) { this.processInlineElement(element); } else { this.processBlockElement(element); diff --git a/packages/draft-js-import-html/src/stateFromHTML.js b/packages/draft-js-import-html/src/stateFromHTML.js index f3df9704..b21fce0c 100644 --- a/packages/draft-js-import-html/src/stateFromHTML.js +++ b/packages/draft-js-import-html/src/stateFromHTML.js @@ -12,6 +12,7 @@ type Options = { blockTypes?: {[key: string]: string}; customBlockFn?: CustomBlockFn; customInlineFn?: CustomInlineFn; + inlineElements?: string[]; }; const defaultOptions: Options = {}; diff --git a/packages/draft-js-import-html/typings/index.d.ts b/packages/draft-js-import-html/typings/index.d.ts index e3edd157..eae8534f 100644 --- a/packages/draft-js-import-html/typings/index.d.ts +++ b/packages/draft-js-import-html/typings/index.d.ts @@ -26,6 +26,7 @@ declare module 'draft-js-import-html' { elementStyles?: { [styleName: string]: string }; customBlockFn?: CustomBlockFn; customInlineFn?: CustomInlineFn; + inlineElements?: string [] } export function stateFromHTML(html: string, options?: Options): draftjs.ContentState; diff --git a/packages/draft-js-import-markdown/src/stateFromMarkdown.js b/packages/draft-js-import-markdown/src/stateFromMarkdown.js index f447f42f..de7cc2cf 100644 --- a/packages/draft-js-import-markdown/src/stateFromMarkdown.js +++ b/packages/draft-js-import-markdown/src/stateFromMarkdown.js @@ -12,6 +12,7 @@ type Options = { customBlockFn?: CustomBlockFn; customInlineFn?: CustomInlineFn; parserOptions?: {[key: string]: mixed}; // TODO: Be more explicit + inlineElements?: string[]; }; let defaultOptions: Options = {};