jpuri / jpuri/html-to-draftjs

Incorrectly displayed RawDraftEntity

Open
#90 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
HTML
Stars
163
Forks
104
PR merge metrics
No merged PRs in 30d

Description

In my editor, I provided custom HTML code. In this code, I have some tags that have specific data attribute. In my example, you can see var tag. For that, I use the htmlToDraft method, with a customChunkRenderer for my personal tag

constructor(props: TMyEditorProps) {
        super(props);

        const html = '<p><span style="font-size: 16px;font-family: Georgia, serif;">test with default style <var data-name="$test"></span></p>'
            + '<p><span style="font-size: 16px;font-family: Georgia, serif;"><strong>test bold</strong></span></p>'
            + '<p><span style="font-size: 16px;font-family: Georgia, serif;"><em>test italic</em></span></p>'
            + '<p><span style="font-size: 16px;font-family: Georgia, serif;"><ins>test underline</ins></span></p>'
            + '<p><span style="font-size: 16px;font-family: Georgia, serif;"><strong><em><ins>test bold &amp; italic &amp; underline</ins></em></strong></span></p>'
            + '<p><span style="font-size: 17px;font-family: Georgia, serif;">test 17px</span></p>'
            + '<p><span style="font-size: 16px;font-family: cursive;">test cursive</span></p>'
            + '<p><span style="font-size: 17px;font-family: cursive;">test 17px &amp; </span><span style="color: rgb(0,0,0);font-size: 17px;font-family: cursive;">cursive</span></p>'
            + '<p><span style="color: rgb(255,0,0);font-size: 16px;font-family: Georgia, serif;">red font</span></p>'
            + '<p><span style="color: rgb(0,0,0);background-color: rgb(0,128,255);font-size: 16px;font-family: Georgia, serif;">blue background</span></p>'
            + '<p><span style="color: rgb(255,0,0);background-color: rgb(255,255,0);font-size: 16px;font-family: Georgia, serif;">red font &amp; yellow background</span></p>'
            + '<p><span style="color: rgb(255,0,0);background-color: rgb(255,255,0);font-size: 20px;font-family: cursive;">font &amp; yellow background &amp; 20px &amp; cursive</span></p>',
            contentBlock = htmlToDraft(html, MyEditor.customChunkRenderer),
            compositeDecorator = MyEditor.getCompositeDecorator();
        let editorState: EditorState;
        if (contentBlock) {
            const contentState = ContentState.createFromBlockArray(contentBlock.contentBlocks);
            editorState = EditorState.createWithContent(contentState, compositeDecorator);
        } else {
            editorState = EditorState.createEmpty(compositeDecorator);
        }

        extractInlineStyle(editorState);

        this.state = {
            editorState
        };
        this.onChangeEditor = this.onChangeEditor.bind(this);
        this.onChangeBold = this.onChangeBold.bind(this);
        this.onChangeItalic = this.onChangeItalic.bind(this);
        this.onChangeUnderline = this.onChangeUnderline.bind(this);
        this.onChangeFontFamily = this.onChangeFontFamily.bind(this);
        this.onChangeFontSize = this.onChangeFontSize.bind(this);
        this.onChangeColor = this.onChangeColor.bind(this);
        this.onChangeBGColor = this.onChangeBGColor.bind(this);
        this.onSelectAll = this.onSelectAll.bind(this);
        this.onClickRemoveAllInlineStyle = this.onClickRemoveAllInlineStyle.bind(this);
        this.onAddVariable = this.onAddVariable.bind(this);
    }

    private static customChunkRenderer(nodeName: string, node: HTMLElement): RawDraftEntity | undefined {
        let draftEntity: RawDraftEntity | undefined;
        if (nodeName === 'var') {
            const data = {
                name: node.dataset.name
            };
            draftEntity = {
                type: 'VARIABLE',
                mutability: 'IMMUTABLE',
                data: data
            };
        }
        return draftEntity;
    }
...
private static getCompositeDecorator(): CompositeDecorator {
        const compositeDecorator: CompositeDecorator = new CompositeDecorator([
            {
                strategy: MyEditor.findLinkEntities,
                component: MyEditor.variableComponent
            }
        ]);

        return compositeDecorator;
    }

    private static findLinkEntities(contentBlock: ContentBlock, callback: FStrategyCallback) {
        contentBlock.findEntityRanges(
            (character) => {
                const entityKey = character.getEntity();
                return (
                    entityKey !== null &&
                    Entity.get(entityKey).getType() === VariableType
                );
            },
            callback
        );
    }

    private static variableComponent(props): JSX.Element {
        const data: TVariableData = props.contentState.getEntity(props.entityKey).getData();
        return <span style={{ textDecoration: 'underline' }}>{data.name}</span>;
    }
...

Unfortunately, when displaying my var tag in my editor, it does not display correctly. The displayed text does not seem to be in the span that contains all of the style I want to associate with it anymore.

Capture1

I would like my var tag to display with the style of the span that contains it and on the same line as the previous text.
When I get the html code from the editor state, with the draftToHtml method (git draftjs-to-html project), we see that my var tag is outside the starting span. You can see it in the textarea below the editor.

Thank you very much

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the example through htmlToDraft with customChunkRenderer, then inspect how the var entity is represented alongside the surrounding span and how draftToHtml serializes it. The fix is done when the variable keeps the enclosing span's styling, remains on the same line, and the generated HTML places it correctly.

Written by the indexing model from the issue text.

Assessment

Tech stack
html, react, typescript
Domain
frontend, web-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.