render(): React.Node { const { block, children, contentState, decorator, decoratorKey, direction, leafSet, text, } = this.props; const blockKey = block.getKey(); const leavesForLeafSet = leafSet.get('leaves'); const DecoratorComponent = decorator.getComponentForKey(decoratorKey); const decoratorProps = decorator.getPropsForKey(decoratorKey); const decoratorOffsetKey = DraftOffsetKey.encode( blockKey, parseInt(decoratorKey, 10), 0, ); const decoratedText = text.slice( leavesForLeafSet.first().get('start'), leavesForLeafSet.last().get('end'), ); // Resetting dir to the same value on a child node makes Chrome/Firefox // confused on cursor movement. See http://jsfiddle.net/d157kLck/3/ const dir = UnicodeBidiDirection.getHTMLDirIfDifferent( UnicodeBidi.getDirection(decoratedText), direction, ); return ( <DecoratorComponent {...decoratorProps} contentState={contentState} decoratedText={decoratedText} dir={dir} key={decoratorOffsetKey} entityKey={block.getEntityAt(leafSet.get('start'))} offsetKey={decoratorOffsetKey}> {children} </DecoratorComponent> ); }
var leaves = leavesForLeafSet.map((leaf, jj) => { var offsetKey = DraftOffsetKey.encode(blockKey, ii, jj); var start = leaf.get('start'); var end = leaf.get('end'); return ( <DraftEditorLeaf key={offsetKey} offsetKey={offsetKey} block={block} start={start} selection={hasSelection ? this.props.selection : undefined} forceSelection={this.props.forceSelection} text={text.slice(start, end)} styleSet={block.getInlineStyleAt(start)} customStyleMap={this.props.customStyleMap} customStyleFn={this.props.customStyleFn} isLast={ii === lastLeafSet && jj === lastLeaf} /> ); }).toArray();
.map((leaf, jj) => { const offsetKey = DraftOffsetKey.encode(blockKey, ii, jj); const start = leaf.get('start'); const end = leaf.get('end'); return ( <DraftEditorLeaf key={offsetKey} offsetKey={offsetKey} block={block} start={start} selection={hasSelection ? selection : null} forceSelection={forceSelection} text={text.slice(start, end)} styleSet={block.getInlineStyleAt(start)} customStyleMap={customStyleMap} customStyleFn={customStyleFn} isLast={decoratorKey === lastLeafSet && jj === lastLeaf} /> ); })
render(): React.Element<any> { const { blockRenderMap, blockRendererFn, customStyleMap, editorState, } = this.props; const content = editorState.getCurrentContent(); const selection = editorState.getSelection(); const forceSelection = editorState.mustForceSelection(); const decorator = editorState.getDecorator(); const directionMap = nullthrows(editorState.getDirectionMap()); const blocksAsArray = content.getBlocksAsArray(); const blocks = []; let currentWrapperElement = null; let currentWrapperTemplate = null; let currentDepth = null; let currentWrappedBlocks; let block, key, blockType, child, childProps, wrapperTemplate; for (let ii = 0; ii < blocksAsArray.length; ii++) { block = blocksAsArray[ii]; key = block.getKey(); blockType = block.getType(); const customRenderer = blockRendererFn(block); let CustomComponent, customProps, customEditable; if (customRenderer) { CustomComponent = customRenderer.component; customProps = customRenderer.props; customEditable = customRenderer.editable; } const direction = directionMap.get(key); const offsetKey = DraftOffsetKey.encode(key, 0, 0); const componentProps = { block, blockProps: customProps, customStyleMap, decorator, direction, forceSelection, key, offsetKey, selection, tree: editorState.getBlockTree(key), }; // Block render map must have a configuration specified for this // block type. const configForType = nullthrows(blockRenderMap.get(blockType)); wrapperTemplate = configForType.wrapper; const useNewWrapper = wrapperTemplate !== currentWrapperTemplate; const Element = ( blockRenderMap.get(blockType).element || blockRenderMap.get('unstyled').element ); const depth = block.getDepth(); let className = this.props.blockStyleFn(block); // List items are special snowflakes, since we handle nesting and // counters manually. if (Element === 'li') { const shouldResetCount = ( useNewWrapper || currentDepth === null || depth > currentDepth ); className = joinClasses( className, getListItemClasses(blockType, depth, shouldResetCount, direction) ); } const Component = CustomComponent || DraftEditorBlock; childProps = { className, 'data-block': true, 'data-editor': this.props.editorKey, 'data-offset-key': offsetKey, key, }; if (customEditable !== undefined) { childProps = { ...childProps, contentEditable: customEditable, suppressContentEditableWarning: true, }; } child = React.createElement( Element, childProps, <Component {...componentProps} />, ); if (wrapperTemplate) { if (useNewWrapper) { currentWrappedBlocks = []; currentWrapperElement = React.cloneElement( wrapperTemplate, { key: key + '-wrap', 'data-offset-key': offsetKey, }, currentWrappedBlocks ); currentWrapperTemplate = wrapperTemplate; blocks.push(currentWrapperElement); } currentDepth = block.getDepth(); nullthrows(currentWrappedBlocks).push(child); } else { currentWrappedBlocks = null; currentWrapperElement = null; currentWrapperTemplate = null; currentDepth = null; blocks.push(child); } } return <div data-contents="true">{blocks}</div>; }
render(): React.Node { const { blockRenderMap, blockRendererFn, blockStyleFn, customStyleMap, customStyleFn, editorState, editorKey, textDirectionality, } = this.props; const content = editorState.getCurrentContent(); const selection = editorState.getSelection(); const forceSelection = editorState.mustForceSelection(); const decorator = editorState.getDecorator(); const directionMap = nullthrows(editorState.getDirectionMap()); const blocksAsArray = content.getBlocksAsArray(); const rootBlock = blocksAsArray[0]; const processedBlocks = []; let nodeBlock = rootBlock; while (nodeBlock) { const blockKey = nodeBlock.getKey(); const blockProps = { blockRenderMap, blockRendererFn, blockStyleFn, contentState: content, customStyleFn, customStyleMap, decorator, editorKey, editorState, forceSelection, selection, block: nodeBlock, direction: textDirectionality ? textDirectionality : directionMap.get(blockKey), tree: editorState.getBlockTree(blockKey), }; const configForType = blockRenderMap.get(nodeBlock.getType()) || blockRenderMap.get('unstyled'); const wrapperTemplate = configForType.wrapper; processedBlocks.push({ block: <DraftEditorBlockNode key={blockKey} {...blockProps} />, wrapperTemplate, key: blockKey, offsetKey: DraftOffsetKey.encode(blockKey, 0, 0), }); const nextBlockKey = nodeBlock.getNextSiblingKey(); nodeBlock = nextBlockKey ? content.getBlockForKey(nextBlockKey) : null; } // Group contiguous runs of blocks that have the same wrapperTemplate const outputBlocks = []; for (let ii = 0; ii < processedBlocks.length; ) { const info: any = processedBlocks[ii]; if (info.wrapperTemplate) { const blocks = []; do { blocks.push(processedBlocks[ii].block); ii++; } while ( ii < processedBlocks.length && processedBlocks[ii].wrapperTemplate === info.wrapperTemplate ); const wrapperElement = React.cloneElement( info.wrapperTemplate, { key: info.key + '-wrap', 'data-offset-key': info.offsetKey, }, blocks, ); outputBlocks.push(wrapperElement); } else { outputBlocks.push(info.block); ii++; } } return <div data-contents="true">{outputBlocks}</div>; }
return this.props.tree.map((leafSet, ii) => { var leavesForLeafSet = leafSet.get('leaves'); var lastLeaf = leavesForLeafSet.size - 1; var leaves = leavesForLeafSet.map((leaf, jj) => { var offsetKey = DraftOffsetKey.encode(blockKey, ii, jj); var start = leaf.get('start'); var end = leaf.get('end'); return ( <DraftEditorLeaf key={offsetKey} offsetKey={offsetKey} block={block} start={start} selection={hasSelection ? this.props.selection : undefined} forceSelection={this.props.forceSelection} text={text.slice(start, end)} styleSet={block.getInlineStyleAt(start)} customStyleMap={this.props.customStyleMap} customStyleFn={this.props.customStyleFn} isLast={ii === lastLeafSet && jj === lastLeaf} /> ); }).toArray(); var decoratorKey = leafSet.get('decoratorKey'); if (decoratorKey == null) { return leaves; } if (!this.props.decorator) { return leaves; } var decorator = nullthrows(this.props.decorator); var DecoratorComponent = decorator.getComponentForKey(decoratorKey); if (!DecoratorComponent) { return leaves; } var decoratorProps = decorator.getPropsForKey(decoratorKey); var decoratorOffsetKey = DraftOffsetKey.encode(blockKey, ii, 0); var decoratedText = text.slice( leavesForLeafSet.first().get('start'), leavesForLeafSet.last().get('end'), ); // Resetting dir to the same value on a child node makes Chrome/Firefox // confused on cursor movement. See http://jsfiddle.net/d157kLck/3/ var dir = UnicodeBidiDirection.getHTMLDirIfDifferent( UnicodeBidi.getDirection(decoratedText), this.props.direction, ); return ( <DecoratorComponent {...decoratorProps} contentState={this.props.contentState} decoratedText={decoratedText} dir={dir} key={decoratorOffsetKey} entityKey={block.getEntityAt(leafSet.get('start'))} offsetKey={decoratorOffsetKey}> {leaves} </DecoratorComponent> ); }).toArray();
render(): React.Node { const { block, contentState, customStyleFn, customStyleMap, decorator, direction, forceSelection, hasSelection, selection, tree, } = this.props; const blockKey = block.getKey(); const text = block.getText(); const lastLeafSet = tree.size - 1; const children = this.props.children || tree .map((leafSet, ii) => { const decoratorKey = leafSet.get('decoratorKey'); const leavesForLeafSet = leafSet.get('leaves'); const lastLeaf = leavesForLeafSet.size - 1; const Leaves = leavesForLeafSet .map((leaf, jj) => { const offsetKey = DraftOffsetKey.encode(blockKey, ii, jj); const start = leaf.get('start'); const end = leaf.get('end'); return ( <DraftEditorLeaf key={offsetKey} offsetKey={offsetKey} block={block} start={start} selection={hasSelection ? selection : null} forceSelection={forceSelection} text={text.slice(start, end)} styleSet={block.getInlineStyleAt(start)} customStyleMap={customStyleMap} customStyleFn={customStyleFn} isLast={decoratorKey === lastLeafSet && jj === lastLeaf} /> ); }) .toArray(); if (!decoratorKey || !decorator) { return Leaves; } return ( <DraftEditorDecoratedLeaves block={block} children={Leaves} contentState={contentState} decorator={decorator} decoratorKey={decoratorKey} direction={direction} leafSet={leafSet} text={text} key={ii} /> ); }) .toArray(); return ( <div data-offset-key={DraftOffsetKey.encode(blockKey, 0, 0)} className={cx({ 'public/DraftStyleDefault/block': true, 'public/DraftStyleDefault/ltr': direction === 'LTR', 'public/DraftStyleDefault/rtl': direction === 'RTL', })}> {children} </div> ); }
render(): React.Node { const { /* $FlowFixMe(>=0.53.0 site=www,mobile) This comment suppresses an error * when upgrading Flow's support for React. Common errors found when * upgrading Flow's React support are documented at * https://fburl.com/eq7bs81w */ blockRenderMap, blockRendererFn, /* $FlowFixMe(>=0.53.0 site=www,mobile) This comment suppresses an error * when upgrading Flow's support for React. Common errors found when * upgrading Flow's React support are documented at * https://fburl.com/eq7bs81w */ customStyleMap, /* $FlowFixMe(>=0.53.0 site=www,mobile) This comment suppresses an error * when upgrading Flow's support for React. Common errors found when * upgrading Flow's React support are documented at * https://fburl.com/eq7bs81w */ customStyleFn, editorState, } = this.props; const content = editorState.getCurrentContent(); const selection = editorState.getSelection(); const forceSelection = editorState.mustForceSelection(); const decorator = editorState.getDecorator(); const directionMap = nullthrows(editorState.getDirectionMap()); const blocksAsArray = content.getBlocksAsArray(); const processedBlocks = []; let currentDepth = null; let lastWrapperTemplate = null; for (let ii = 0; ii < blocksAsArray.length; ii++) { const block = blocksAsArray[ii]; const key = block.getKey(); const blockType = block.getType(); const customRenderer = blockRendererFn(block); let CustomComponent, customProps, customEditable; if (customRenderer) { CustomComponent = customRenderer.component; customProps = customRenderer.props; customEditable = customRenderer.editable; } const {textDirectionality} = this.props; const direction = textDirectionality ? textDirectionality : directionMap.get(key); const offsetKey = DraftOffsetKey.encode(key, 0, 0); const componentProps = { contentState: content, block, blockProps: customProps, customStyleMap, customStyleFn, decorator, direction, forceSelection, key, offsetKey, selection, tree: editorState.getBlockTree(key), }; const configForType = blockRenderMap.get(blockType); const wrapperTemplate = configForType.wrapper; const Element = ( configForType.element || blockRenderMap.get('unstyled').element ); const depth = block.getDepth(); let className = this.props.blockStyleFn(block); // List items are special snowflakes, since we handle nesting and // counters manually. if (Element === 'li') { const shouldResetCount = ( lastWrapperTemplate !== wrapperTemplate || currentDepth === null || depth > currentDepth ); className = joinClasses( className, getListItemClasses(blockType, depth, shouldResetCount, direction), ); } const Component = CustomComponent || DraftEditorBlock; let childProps = { className, 'data-block': true, /* $FlowFixMe(>=0.53.0 site=www,mobile) This comment suppresses an * error when upgrading Flow's support for React. Common errors found * when upgrading Flow's React support are documented at * https://fburl.com/eq7bs81w */ 'data-editor': this.props.editorKey, 'data-offset-key': offsetKey, key, }; if (customEditable !== undefined) { childProps = { ...childProps, contentEditable: customEditable, suppressContentEditableWarning: true, }; } const child = React.createElement( Element, childProps, /* $FlowFixMe(>=0.53.0 site=www,mobile) This comment suppresses an * error when upgrading Flow's support for React. Common errors found * when upgrading Flow's React support are documented at * https://fburl.com/eq7bs81w */ <Component {...componentProps} />, ); processedBlocks.push({ block: child, wrapperTemplate, key, offsetKey, }); if (wrapperTemplate) { currentDepth = block.getDepth(); } else { currentDepth = null; } lastWrapperTemplate = wrapperTemplate; } // Group contiguous runs of blocks that have the same wrapperTemplate const outputBlocks = []; for (let ii = 0; ii < processedBlocks.length; ) { const info = processedBlocks[ii]; if (info.wrapperTemplate) { const blocks = []; do { blocks.push(processedBlocks[ii].block); ii++; } while ( ii < processedBlocks.length && processedBlocks[ii].wrapperTemplate === info.wrapperTemplate ); const wrapperElement = React.cloneElement( info.wrapperTemplate, { key: info.key + '-wrap', 'data-offset-key': info.offsetKey, }, blocks, ); outputBlocks.push(wrapperElement); } else { outputBlocks.push(info.block); ii++; } } return <div data-contents="true">{outputBlocks}</div>; }
render(): React.Element { const {blockRendererFn, customStyleMap, editorState} = this.props; const content = editorState.getCurrentContent(); const selection = editorState.getSelection(); const forceSelection = editorState.mustForceSelection(); const decorator = editorState.getDecorator(); const directionMap = nullthrows(editorState.getDirectionMap()); const blocksAsArray = content.getBlocksAsArray(); const blocks = []; let currentWrapperElement = null; let currentWrapperTemplate = null; let currentDepth = null; let currentWrappedBlocks; let block, key, blockType, child, wrapperTemplate; for (let ii = 0; ii < blocksAsArray.length; ii++) { block = blocksAsArray[ii]; key = block.getKey(); blockType = block.getType(); const customRenderer = blockRendererFn(block); let CustomComponent, customProps; if (customRenderer) { CustomComponent = customRenderer.component; customProps = customRenderer.props; } const direction = directionMap.get(key); const offsetKey = DraftOffsetKey.encode(key, 0, 0); const componentProps = { block, blockProps: customProps, customStyleMap, decorator, direction, forceSelection, key, offsetKey, selection, tree: editorState.getBlockTree(key), }; wrapperTemplate = getWrapperTemplateForBlockType(blockType); const useNewWrapper = wrapperTemplate !== currentWrapperTemplate; if (CustomComponent) { child = <CustomComponent {...componentProps} />; } else { const Element = getElementForBlockType(blockType); const depth = block.getDepth(); let className = this.props.blockStyleFn(block); // List items are special snowflakes, since we handle nesting and // counters manually. if (Element === 'li') { const shouldResetCount = ( useNewWrapper || currentDepth === null || depth > currentDepth ); className = joinClasses( className, getListItemClasses(blockType, depth, shouldResetCount, direction) ); } // $FlowFixMe: Support DOM elements in React.createElement child = React.createElement( Element, { className, 'data-block': true, 'data-editor': this.props.editorKey, 'data-offset-key': offsetKey, key, }, <DraftEditorBlock {...componentProps} />, ); } if (wrapperTemplate) { if (useNewWrapper) { currentWrappedBlocks = []; currentWrapperElement = React.cloneElement( wrapperTemplate, { key: key + '-wrap', 'data-offset-key': offsetKey, }, currentWrappedBlocks ); currentWrapperTemplate = wrapperTemplate; blocks.push(currentWrapperElement); } currentDepth = block.getDepth(); nullthrows(currentWrappedBlocks).push(child); } else { currentWrappedBlocks = null; currentWrapperElement = null; currentWrapperTemplate = null; currentDepth = null; blocks.push(child); } } return <div data-contents="true">{blocks}</div>; }