constructor(props) { super(props); this.state = { editorState: props.editorState ? EditorState.createWithContent(convertFromRaw(props.editorState)) : EditorState.createWithContent(ContentState.createFromText('Insert text ...')) }; }
createEntity(type: string, data: DataMap<string>, mutability: EntityMutability = 'MUTABLE') { this.contentStateForEntities = this.contentStateForEntities.createEntity( type, mutability, data, ); return this.contentStateForEntities.getLastCreatedEntityKey(); }
/** * This function merges contentBlocks into existing article * @param {*} contentBlocks - draft ContentBlock * @param {*} article - Article to merge data */ export default function DraftToJSON(contentState: ContentState, srcCover: LdJsonDocument) { const blockMap = contentState.getBlockMap(); const filteredBlockMap = filterBlockMap(blockMap); const cover = mkCoverJson(srcCover.getElementOfType('ImageObject'), filteredBlockMap); // first pass const order = getOrderOffset(cover); // second pass to create links images and socials filteredBlockMap.forEach((element, i) => { let entity; const findEntityOfType = type => (char) => { const entityKey = char.getEntity(); entity = entityKey ? Entity.get(entityKey) : null; return !!entity && entity.getType() === type; }; const mkLink = block => (anchorOffset, focusOffset) => { const data = entity.getData(); const url = data.linkUrl; const name = data.linkTitle || ''; const linkText = block.getText().substring(anchorOffset, focusOffset); cover.mentions.push(getMention(name, '', formatMention(url, linkText, order + i, anchorOffset))); }; element.el.findEntityRanges(findEntityOfType('LINK'), mkLink(element.el)); }); return cover; }
it('should get selected block key', () => { const contentState = ContentState.createFromText('we need to connect the bluetooth SSL capacitor!'); const block = contentState.getFirstBlock(); const blockKey = block.getKey(); const editorState = EditorState.createWithContent(contentState); expect(getSelectedBlockKey(editorState)).toEqual(blockKey); });
describe('ImageRenderer', () => { const contentBlocks = convertFromHTML('<div>test</div>'); const contentState = ContentState.createFromBlockArray(contentBlocks); const editorState = EditorState.createWithContent(contentState); const entityKey = contentState .createEntity('IMAGE', 'MUTABLE', { src: 'testing' }) .getLastCreatedEntityKey(); const newEditorState = AtomicBlockUtils.insertAtomicBlock(editorState, entityKey, ' '); it('should have state initialized correctly', () => { const Image = getImageRender({ isReadOnly: () => false, isImageAlignmentEnabled: () => true, }); const control = shallow( <Image block={getAllBlocks(newEditorState).get(1)} contentState={contentState} />, ); expect(control.state().hovered).toBeFalsy(); }); it('should have 1 child element by default', () => { const Image = getImageRender({ isReadOnly: () => false, isImageAlignmentEnabled: () => true, }); const control = shallow( <Image block={getAllBlocks(newEditorState).get(1)} contentState={contentState} />, ); expect(control.children().length).toEqual(1); }); });
it('should not change depth if block is not a list', () => { const { contentBlocks } = convertFromHTML('<h1>aaaaaaaaaa</h1>'); const contentState = ContentState.createFromBlockArray(contentBlocks); let editorState = EditorState.createWithContent(contentState); editorState = changeDepth(editorState, 1, 4); assert.equal(getSelectedBlock(editorState).getDepth(), 0); });
export const removeDisallowedBlocks = (editorState, blocks, layout, hasFeatures, keepExisting) => { const allowedBlocks = blockRenderMapArray(layout, hasFeatures) const currentContent = editorState.getCurrentContent() const selection = editorState.getSelection() let newState const cleanedBlocks = blocks.map((contentBlock) => { const unstyled = stripCharacterStyles(contentBlock, true) const isAllowedBlock = allowedBlocks.includes(unstyled.getType()) const isLink = unstyled.getType() === 'LINK' if (isAllowedBlock || isLink) { return unstyled } else { return unstyled.set('type', 'unstyled') } }) const newBlocks = ContentState.createFromBlockArray(cleanedBlocks, blocks) if (keepExisting) { const newContent = Modifier.replaceWithFragment(currentContent, selection, newBlocks.blockMap) newState = EditorState.push(editorState, newContent, null) } else { newState = EditorState.push(editorState, newBlocks, null) } return newState }
export default (text, plugins) => { const compositeDecorator = createCompositeDecorator(plugins); return EditorState.createWithContent( ContentState.createFromText(text), compositeDecorator, ); };
describe('<FontFamily />', () => { const contentBlocks = convertFromHTML('<div>test</div>'); const contentState = ContentState.createFromBlockArray(contentBlocks); const editorState = EditorState.createWithContent(contentState); it('should have a div when rendered', () => { const wrapper = mount( <FontFamily onChange={() => {}} editorState={editorState} config={defaultToolbar.fontFamily} modalHandler={new ModalHandler()} />, ); expect(wrapper.find('.be-ctrl__group').length).toBe(1); }); // it('should have a dropdown child component well defined', () => { // const control = mount( // <FontFamily // onChange={() => {}} // editorState={editorState} // config={defaultToolbar.fontFamily} // modalHandler={new ModalHandler()} // />, // ); // expect(control.childAt(0).props().children.length).toBe(2); // expect(control.childAt(0).props().onChange).toBeDefined(); // }); });
EditorCore.prototype.Reset = function Reset() { var defaultValue = this.props.defaultValue; var contentState = defaultValue ? defaultValue.getCurrentContent() : _draftJs.ContentState.createFromText(''); var updatedEditorState = _draftJs.EditorState.push(this.state.editorState, contentState, 'remove-range'); this.setEditorState(_draftJs.EditorState.forceSelection(updatedEditorState, contentState.getSelectionBefore())); };
rehydrate: function (state) { this.activity = state.activity this.volunteers = state.volunteers this.updates = state.updates _.forEach(state.activityState.entityMap, function(val, key) { val.data.mention = fromJS(val.data.mention) }) var contentState = Draft.convertFromRaw(state.activityState) this.activityState = Draft.EditorState.push(this.activityState, Draft.ContentState.createFromBlockArray(contentState.getBlocksAsArray())) // Formularz aktualizacji do zadania var contentState2 = Draft.convertFromRaw(state.newUpdateState) this.newUpdateState = Draft.EditorState.push(this.newUpdateState, Draft.ContentState.createFromBlockArray(contentState2.getBlocksAsArray())) }
const getCell = (i, j) => { const cellContentState = cells[i] && cells[i][j] ? convertFromRaw(cells[i][j]) : ContentState.createFromText(''); return new HTMLGenerator(cellContentState, ['table']).html(); };
it('should correctly get inline styles', () => { const { contentBlocks } = convertFromHTML('<h1>aaaaaaaaaa</h1><ul><li>test</li></ul>'); const contentState = ContentState.createFromBlockArray(contentBlocks); let editorState = EditorState.createWithContent(contentState); const updatedSelection = editorState.getSelection().merge({ anchorOffset: 0, focusOffset: 10, }); editorState = EditorState.acceptSelection( editorState, updatedSelection, ); editorState = RichUtils.toggleInlineStyle( editorState, 'BOLD', ); assert.equal(getSelectionInlineStyle(editorState).BOLD, true); editorState = RichUtils.toggleInlineStyle( editorState, 'STRIKETHROUGH', ); assert.equal(getSelectionInlineStyle(editorState).STRIKETHROUGH, true); editorState = RichUtils.toggleInlineStyle( editorState, 'CODE', ); assert.equal(getSelectionInlineStyle(editorState).CODE, true); });
export function condenseBlocks (editorState, blocks, options) { blocks = blocks || editorState.getCurrentContent().getBlocksAsArray() let text = List() let characterList = List() // Gather all the text/characterList and concat them blocks.forEach((block) => { // Atomic blocks should be ignored (stripped) if (block.getType() !== 'atomic') { text = text.push(replaceNewlines(block.getText())) characterList = characterList.concat(block.getCharacterList()) } }) // Strip entities? if (options.stripEntities) { characterList = characterList.map(stripEntityFromCharacterMetadata) } // Create a new content block const contentBlock = new ContentBlock({ key: genKey(), text: text.join(''), type: 'unstyled', characterList: characterList, depth: 0, }) // Update the editor state with the compressed version const newContentState = ContentState.createFromBlockArray([contentBlock]) // Create the new state as an undoable action editorState = EditorState.push(editorState, newContentState, 'remove-range') // Move the selection to the end return EditorState.moveFocusToEnd(editorState) }
export default (rawContent, plugins) => { const compositeDecorator = createCompositeDecorator(plugins); const blocks = convertFromRaw(rawContent); return EditorState.createWithContent( ContentState.createFromBlockArray(blocks), compositeDecorator, ); };
it('should clear editor content', () => { expect.assertions(1); const { contentBlocks } = convertFromHTML('<h1>aaaaaaaaaa</h1><h1>aaaaaaaaaa</h1>'); const contentState = ContentState.createFromBlockArray(contentBlocks); let editorState = EditorState.createWithContent(contentState); editorState = clearEditorContent(editorState); expect(editorState.getCurrentContent().getPlainText().length).toEqual(0); });
componentWillMount () { this.props.dispatch(openFile(this.props.filename)) this.setState({ editorState: this.props.content ? EditorState.createWithContent( ContentState.createFromText(this.props.content) ) : EditorState.createEmpty() }) }
const convertHTMLToEditorState = (html: string): Object => { const blocksFromHTML = convertFromHTML(html) const contentState = ContentState.createFromBlockArray( blocksFromHTML.contentBlocks, blocksFromHTML.entityMap ) return EditorState.createWithContent(contentState) }
}) => ( html, DOMBuilder = getSafeBodyFromHTML ) => { return ContentState.createFromBlockArray( convertFromHTMLtoContentBlocks(html, htmlToStyle, htmlToEntity, textToEntity, htmlToBlock, DOMBuilder) ); };
/** * This function merges contentBlocks into existing article * @param {*} contentBlocks - draft ContentBlock * @param {*} article - Article to merge data */ export default function DraftToJSON(contentState: ContentState, srcArticle: LdJsonDocument) { const blockMap = contentState.getBlockMap(); const filteredBlockMap = filterBlockMap(blockMap); const article = mkArticleJson(srcArticle.getElementOfType('Article'), filteredBlockMap); // first pass const order = getOrderOffset(article); // second pass to create links images and socials filteredBlockMap.forEach((element, i) => { let entity; const findEntityOfType = type => (char) => { const entityKey = char.getEntity(); entity = entityKey ? Entity.get(entityKey) : null; return !!entity && entity.getType() === type; }; const mkLink = block => (anchorOffset, focusOffset) => { const data = entity.getData(); const url = data.href; const name = data.linkTitle || ''; const linkText = block.getText().substring(anchorOffset, focusOffset); article.mentions.push(getMention(name, '', formatMention(url, linkText, order + i, anchorOffset))); }; const mkImage = block => (anchorOffset) => { const data = entity.getData(); const url = data.src; const name = data.title || ''; const desc = data.description || ''; article.image.push(getImageObject(`${url}?${order + i},${anchorOffset}`, name, desc)); }; const mkSocial = block => (anchorOffset) => { const data = entity.getData(); const url = data.src; const desc = data.description || ''; const title = data.title || ''; article.hasPart.push(getSocialMediaPosting(url, desc, title)); }; const mkTicket = block => (anchorOffset) => { const data = entity.getData(); const url = data.src; const desc = data.description || ''; const title = data.title || ''; const image = data.image || ''; article.hasPart.push(getTicket(url, image, desc, title)); }; element.el.findEntityRanges(findEntityOfType('LINK'), mkLink(element.el)); element.el.findEntityRanges(findEntityOfType('IMAGE'), mkImage(element.el)); element.attached.forEach(e => e.findEntityRanges(findEntityOfType('IMAGE'), mkImage(e))); element.el.findEntityRanges(findEntityOfType('SOCIAL'), mkSocial(element.el)); element.attached.forEach(e => e.findEntityRanges(findEntityOfType('SOCIAL'), mkSocial(e))); element.el.findEntityRanges(findEntityOfType('TICKET'), mkTicket(element.el)); element.attached.forEach(e => e.findEntityRanges(findEntityOfType('TICKET'), mkTicket(e))); }); return article; }
const getContentState = () => { if (rawId) { const raw = Collections.RawDraftContentStates.findOne(rawId); const contentBlocks = convertFromRaw(raw); const contentState = ContentState.createFromBlockArray(contentBlocks); return contentState; } return undefined; };
constructor(props) { super(props); const blocks = convertFromRaw(this.props.content); this.state = {editorState: EditorState.createWithContent( ContentState.createFromBlockArray(blocks) )}; this.onChange = (editorState) => this.setState({editorState}); }
componentWillReceiveProps (nextProps) { if (nextProps.filename !== this.props.filename) { this.props.dispatch(openFile(nextProps.filename)) } this.setState({ editorState: nextProps.content ? EditorState.createWithContent( ContentState.createFromText(nextProps.content) ) : EditorState.createEmpty() }) }
process(element: DOMElement): ContentState { this.processBlockElement(element); let contentBlocks = []; this.blockList.forEach((block) => { let {text, characterMeta} = concatFragments(block.textFragments); let includeEmptyBlock = false; // If the block contains only a soft break then don't discard the block, // but discard the soft break. if (text === SOFT_BREAK_PLACEHOLDER) { includeEmptyBlock = true; text = ''; } if (block.tagName === 'pre') { ({text, characterMeta} = trimLeadingNewline(text, characterMeta)); } else { ({text, characterMeta} = collapseWhiteSpace(text, characterMeta)); } // Previously we were using a placeholder for soft breaks. Now that we // have collapsed whitespace we can change it back to normal line breaks. text = text.split(SOFT_BREAK_PLACEHOLDER).join('\n'); // Discard empty blocks (unless otherwise specified). if (text.length || includeEmptyBlock) { contentBlocks.push( new ContentBlock({ key: genKey(), text: text, type: block.type, characterList: characterMeta.toList(), depth: block.depth, data: block.data ? Map(block.data) : Map(), }), ); } }); if (!contentBlocks.length) { contentBlocks = [EMPTY_BLOCK]; } return ContentState.createFromBlockArray( contentBlocks, this.contentStateForEntities.getEntityMap(), ); }
constructor (props) { super(props) this.state = { editorState: EditorState.createWithContent( ContentState.createFromText(this.props.nodeId), createHighlightDecorator() ), suggestions: mentions } }
constructor(options: Options = {}) { this.options = options; this.contentStateForEntities = ContentState.createFromBlockArray([]); // This represents the hierarchy as we traverse nested elements; for // example [body, ul, li] where we must know li's parent type (ul or ol). this.blockStack = []; // This is a linear list of blocks that will form the output; for example // [p, li, li, blockquote]. this.blockList = []; this.depth = 0; }
constructor(props) { super(props); this.state = { editorState: EditorState.createWithContent(ContentState.createFromText(props.content)) }; this.focus = () => this.refs.editor.focus(); this.onChange = (editorState) => this.setState({ editorState }); this.handleKeyCommand = (command) => this.onHandleKeyCommand(command); this.toggleBlockType = (type) => this.onToggleBlockType(type); this.toggleInlineStyle = (style) => this.onToggleInlineStyle(style); this.saveContent = () => this.onSaveContent(); }
/** * @name getInitialContent * @param {Object} ctrl Controller hosting the editor * @returns {ContentState} DraftJS ContentState object. * @description Gets the initial content state of the editor based on available information. * If an editor state is available as saved in the DB, we use that, otherwise we attempt to * use available HTML. If none are available, an empty ContentState is created. */ function getInitialContent(ctrl) { // we have an editor state stored in the DB if (typeof ctrl.editorState === 'object') { return convertFromRaw(ctrl.editorState); } // we have only HTML (possibly legacy editor2 or ingested item) if (ctrl.value) { return fromHTML(ctrl.value); } return ContentState.createFromText(''); }
test('should add new unstyles block when insertNewUnstyledBlock is called', () => { expect.assertions(1); const contentBlocks = convertFromHTML('<h1>aaaaaaaaaa</h1>'); const contentState = ContentState.createFromBlockArray(contentBlocks); let editorState = EditorState.createWithContent(contentState); const updatedSelection = editorState.getSelection().merge({ anchorOffset: 0, focusOffset: 10, }); editorState = EditorState.acceptSelection(editorState, updatedSelection); editorState = insertNewUnstyledBlock(editorState); expect(getAllBlocks(editorState).size).toEqual(2); });
constructor(props) { super(props); this.handleSubmit = this.handleSubmit.bind(this); this.onImageDrop = this.onImageDrop.bind(this); this.handleImageUpload = this.handleImageUpload.bind(this); let pkey = this.props.match.params.pkey; let providers = this.props.providers; let objectKey = Object.keys(providers).filter((current) => providers[current].id === pkey); let provider = providers[objectKey]; let desc = provider.desc; let state; if ( desc ) { const blocksFromHTML = htmlToDraft(desc); state = ContentState.createFromBlockArray( blocksFromHTML.contentBlocks, blocksFromHTML.entityMap, ); } else { const blocksFromHTML = htmlToDraft('<p>Provider Description</p>'); state = ContentState.createFromBlockArray( blocksFromHTML.contentBlocks, blocksFromHTML.entityMap, ); } this.state = { uploadedFileCloudinaryUrl: '', editorState: EditorState.createWithContent( state, ), } this.focus = () => this.refs.editor.focus(); this.onChange = (editorState) => this.setState({editorState}); }