sstur / draft-js-utils

DraftJS: import/export ContentState to and from HTML/Markdown
ISC License
883 stars 234 forks source link

Could draft-js-export-html close all tags? #180

Closed trevordmiller closed 5 years ago

trevordmiller commented 5 years ago

First off, thanks for the wonderful library! I have a question that is perhaps a bug or feature request. Currently, if this code is run...

import { convertFromRaw } from "draft-js";
import { stateToHTML } from "draft-js-export-html";

const content = {
      blocks: [
      {
        key: "39deu",
        text: "Some example content",
        type: "unstyled",
        depth: 0,
        inlineStyleRanges: [],
        entityRanges: [],
        data: {}
      },
      {
        key: "gddj",
        text: "",
        type: "unstyled",
        depth: 0,
        inlineStyleRanges: [],
        entityRanges: [],
        data: {}
      },
      {
        key: "76g7b",
        text: "With empty lines",
        type: "unstyled",
        depth: 0,
        inlineStyleRanges: [],
        entityRanges: [],
        data: {}
      }
    ],
    entityMap: {}
}

const contentState = convertFromRaw(content);
const htmlString = stateToHTML(contentState);

htmlString will be:

<p>Some example content</p><p><br></p><p>With empty lines</p>

Can the library be updated to always output closed tags so that the HTML is fully valid? For this example, that would be with closed <br/> instead of <br> like this:

<p>Some example content</p><p><br/></p><p>With empty lines</p>

Otherwise, JSX throws the following error when you try to render the HTML output:

SyntaxError: Expected corresponding JSX closing tag for <br>

Since JSX is more strict than HTML.

sstur commented 5 years ago

"always output closed tags so that the HTML is fully valid"

Just to be clear, the HTML5 standard in general does NOT support the extra / character (although it does allow it for historical reasons on certain "void" elements), so the reason that we don't add it is really about trying to follow the spec and thus the current behavior results in valid HTML.

Secondly, JSX is not the same as HTML for many reasons including self-closing elements and non-standard attribute names. For example <div className="foo" /> is valid JSX but not valid HTML.

It is not a goal of this library to produce JSX, although one suggestion for your use case might be to use an HTML to JSX converter.

All that being said, I'd actually be OK with adding an option to support this "self-closing" style that you mentioned, but not for JSX reasons, rather for XHTML. So I'd be OK for this feature if you or someone else were to make a PR as long as it's optional and not turned on by default.

trevordmiller commented 5 years ago

@sstur Gotcha, thanks for the info! Since the HTML output of this library is valid, I'll try to solve the problem at my consuming layer where I render the HTML inside JSX. If anyone does want to work on adding optional XHTML support feel free to reopen.