Skip to content

Instantly share code, notes, and snippets.

@DominikStyp
Last active February 11, 2022 12:17
Show Gist options
  • Save DominikStyp/6e4ca44d96dbcae78514edd5b484b914 to your computer and use it in GitHub Desktop.
Save DominikStyp/6e4ca44d96dbcae78514edd5b484b914 to your computer and use it in GitHub Desktop.
React + WYSIWYG: wrapper to 'draft-js' + JEST test
import { ContentState, convertFromHTML, convertFromRaw, convertToRaw, EditorState as DraftEditorState } from 'draft-js';
import draftToHtml from 'draftjs-to-html';
class EditorState {
constructor(state: DraftEditorState = null) {
this.use(state);
}
static loadFromHtml(htmlContent: String): DraftEditorState {
const blocks = convertFromHTML(htmlContent);
const contentState = ContentState.createFromBlockArray(blocks);
return DraftEditorState.createWithContent(contentState);
}
static loadFromText(plainTextContent: String): DraftEditorState {
const contentState = ContentState.createFromText(plainTextContent);
return DraftEditorState.createWithContent(contentState);
}
static loadFromJson(jsonContent: String): DraftEditorState {
const parsed = JSON.parse(jsonContent);
const contentState = convertFromRaw(parsed);
return DraftEditorState.createWithContent(contentState);
}
static createNew() {
return DraftEditorState.createEmpty();
}
use(state: DraftEditorState): EditorState {
this.state = state;
return this;
}
toHtml(): String {
if (this.state === null) {
return null;
}
const contentState = this.state.getCurrentContent();
const rawDraft = convertToRaw(contentState);
return draftToHtml(rawDraft);
}
toText(): String {
const html = this.toHtml();
if (html === null) {
return null;
}
const blocks = convertFromHTML(html);
const content = blocks.contentBlocks.map((block) => block.getText());
return content.join(' ');
}
toJson(): String {
return JSON.stringify(convertToRaw(this.state.getCurrentContent()));
}
}
export default EditorState;
import EditorState from '../EditorState';
describe('Editor State', () => {
describe('loadFromText() method', () => {
it('check the toHtml() and toText() output', () => {
const draftState = EditorState.loadFromText('plain text');
const state = new EditorState(draftState);
expect(state.toHtml().trim()).toEqual('<p>plain text</p>');
expect(state.toText().trim()).toEqual('plain text');
});
});
describe('loadFromHTML() method', () => {
it('check the toHtml() and toText() output', () => {
const inputHTML = '<p><h2>Header 2</h2></p><p><b>Bolded</b></p>';
const expectedOutputHTML = '<h2>Header 2</h2>\n<p><strong>Bolded</strong></p>';
const draftState = EditorState.loadFromHtml(inputHTML);
const state = new EditorState(draftState);
expect(state.toHtml().trim()).toEqual(expectedOutputHTML);
expect(state.toText().trim()).toEqual('Header 2 Bolded');
});
});
describe('loadFromJSON() method', () => {
it('check the toHtml() and toText() output', () => {
// output taken from the previous test: console.log(state.toJson());
const inputJSON =
'{"blocks":[{"key":"aiic7","text":"Header 2","type":"header-two","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}},{"key":"7jlvb","text":"Bolded","type":"unstyled","depth":0,"inlineStyleRanges":[{"offset":0,"length":6,"style":"BOLD"}],"entityRanges":[],"data":{}}],"entityMap":{}}';
const expectedOutputHTML = '<h2>Header 2</h2>\n<p><strong>Bolded</strong></p>';
const draftState = EditorState.loadFromJson(inputJSON);
const state = new EditorState(draftState);
expect(state.toHtml().trim()).toEqual(expectedOutputHTML);
expect(state.toText().trim()).toEqual('Header 2 Bolded');
expect(state.toJson()).toEqual(inputJSON);
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment