Skip to content

Commit

Permalink
adding-support-for-paragraph - making blockTypes configurable
Browse files Browse the repository at this point in the history
Summary:
This fixes issue facebookarchive#204

- Including paragraph on converter
- Updating website and demo
- Updating example
Closes facebookarchive#205

Reviewed By: ezequiel

Differential Revision: D3147267

fb-gh-sync-id: ae51df9b838597066a699dced879b2795e59db26
fbshipit-source-id: ae51df9b838597066a699dced879b2795e59db26
  • Loading branch information
mitermayer authored and Quentin Gérome committed Jun 9, 2016
1 parent 59fefc4 commit 74ea5fe
Show file tree
Hide file tree
Showing 16 changed files with 410 additions and 213 deletions.
28 changes: 26 additions & 2 deletions examples/rich/rich.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,34 @@
<script type="text/babel">
'use strict';

const {Editor, EditorState, RichUtils} = Draft;
const {
Editor,
EditorState,
RichUtils,
DefaultDraftBlockRenderMap,
} = Draft;

const {Map} = immutable;

class RichEditorExample extends React.Component {
constructor(props) {
super(props);
this.state = {editorState: EditorState.createEmpty()};

const customBlockRendering = Map({
'paragraph': {
element: 'p',
},
'unstyled': {
element: 'p',
},
});

this.state = {
blockRenderMap: DefaultDraftBlockRenderMap.merge(
customBlockRenderMap,
),
editorState: EditorState.createEmpty(),
};

this.focus = () => this.refs.editor.focus();
this.onChange = (editorState) => this.setState({editorState});
Expand Down Expand Up @@ -101,6 +123,7 @@
/>
<div className={className} onClick={this.focus}>
<Editor
blockRenderMap={this.state.blockRenderMap}
blockStyleFn={getBlockStyle}
customStyleMap={styleMap}
editorState={editorState}
Expand Down Expand Up @@ -157,6 +180,7 @@
}

const BLOCK_TYPES = [
{label: 'P', style: 'paragraph'},
{label: 'H1', style: 'header-one'},
{label: 'H2', style: 'header-two'},
{label: 'H3', style: 'header-three'},
Expand Down
5 changes: 5 additions & 0 deletions src/Draft.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ const CharacterMetadata = require('CharacterMetadata');
const CompositeDraftDecorator = require('CompositeDraftDecorator');
const ContentBlock = require('ContentBlock');
const ContentState = require('ContentState');
const DefaultDraftBlockRenderMap = require('DefaultDraftBlockRenderMap');
const DefaultDraftInlineStyle = require('DefaultDraftInlineStyle');
const DraftEditor = require('DraftEditor.react');
const DraftEditorBlock = require('DraftEditorBlock.react');
const DraftModifier = require('DraftModifier');
Expand Down Expand Up @@ -55,6 +57,9 @@ const DraftPublic = {
Modifier: DraftModifier,
RichUtils: RichTextEditorUtil,

DefaultDraftBlockRenderMap,
DefaultDraftInlineStyle,

convertFromHTML: convertFromHTMLToContentBlocks,
convertFromRaw: convertFromRawToDraftState,
convertToRaw: convertFromDraftStateToRaw,
Expand Down
22 changes: 8 additions & 14 deletions src/component/base/DraftEditor.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

'use strict';

const DefaultDraftBlockRenderMap = require('DefaultDraftBlockRenderMap');
const DefaultDraftInlineStyle = require('DefaultDraftInlineStyle');
const DraftEditorCompositionHandler = require('DraftEditorCompositionHandler');
const DraftEditorContents = require('DraftEditorContents.react');
Expand All @@ -34,7 +35,6 @@ const nullthrows = require('nullthrows');
const getScrollPosition = require('getScrollPosition');

import type {BlockMap} from 'BlockMap';
import type ContentBlock from 'ContentBlock';
import type {DraftEditorModes} from 'DraftEditorModes';
import type {DraftEditorProps} from 'DraftEditorProps';
import type {DraftScrollPosition} from 'DraftScrollPosition';
Expand All @@ -55,15 +55,6 @@ const handlerMap = {
'render': null,
};

type DefaultProps = {
blockRendererFn?: (block: ContentBlock) => ?Object;
blockStyleFn?: (type: number) => string,
keyBindingFn?: (e: SyntheticKeyboardEvent) => ?string,
readOnly?: boolean,
spellCheck?: boolean,
stripPastedStyles?: boolean,
};

type State = {
containerKey: number,
};
Expand All @@ -73,11 +64,12 @@ type State = {
* div, and provides a wide variety of useful function props for managing the
* state of the editor. See `DraftEditorProps` for details.
*/
class DraftEditor
extends React.Component<DefaultProps, DraftEditorProps, State> {
class DraftEditor extends React.Component {
props: DraftEditorProps;
state: State;

static defaultProps = {
blockRenderMap: DefaultDraftBlockRenderMap,
blockRendererFn: emptyFunction.thatReturnsNull,
blockStyleFn: emptyFunction.thatReturns(''),
keyBindingFn: getDefaultKeyBinding,
Expand Down Expand Up @@ -216,6 +208,7 @@ class DraftEditor
/>
);
}
return null;
}

render(): React.Element {
Expand Down Expand Up @@ -283,8 +276,9 @@ class DraftEditor
suppressContentEditableWarning
tabIndex={this.props.tabIndex}>
<DraftEditorContents
blockRendererFn={nullthrows(this.props.blockRendererFn)}
blockStyleFn={nullthrows(this.props.blockStyleFn)}
blockRenderMap={this.props.blockRenderMap}
blockRendererFn={this.props.blockRendererFn}
blockStyleFn={this.props.blockStyleFn}
customStyleMap={
{...DefaultDraftInlineStyle, ...this.props.customStyleMap}
}
Expand Down
8 changes: 7 additions & 1 deletion src/component/base/DraftEditorProps.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
'use strict';

import type ContentBlock from 'ContentBlock';
import type {DraftEditorCommand} from 'DraftEditorCommand';
import type {DraftBlockRenderMap} from 'DraftBlockRenderMap';
import type {DraftDragType} from 'DraftDragType';
import type {DraftEditorCommand} from 'DraftEditorCommand';
import type {DraftTextAlignment} from 'DraftTextAlignment';
import type EditorState from 'EditorState';
import type SelectionState from 'SelectionState';
Expand Down Expand Up @@ -129,4 +130,9 @@ export type DraftEditorProps = {
// Provide a map of inline style names corresponding to CSS style objects
// that will be rendered for matching ranges.
customStyleMap?: Object,

// Provide a map of block rendering configurations. Each block type maps to
// an element tag and am optional react element wrapper. This configuration
// is used for both rendering and paste processing.
blockRenderMap: DraftBlockRenderMap,
};
23 changes: 18 additions & 5 deletions src/component/contents/DraftEditorContents.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ const EditorState = require('EditorState');
const React = require('React');

const cx = require('cx');
const getElementForBlockType = require('getElementForBlockType');
const getWrapperTemplateForBlockType = require('getWrapperTemplateForBlockType');
const joinClasses = require('joinClasses');
const nullthrows = require('nullthrows');

Expand Down Expand Up @@ -93,7 +91,13 @@ class DraftEditorContents extends React.Component {
}

render(): React.Element {
const {blockRendererFn, customStyleMap, editorState} = this.props;
const {
blockRenderMap,
blockRendererFn,
customStyleMap,
editorState,
} = this.props;

const content = editorState.getCurrentContent();
const selection = editorState.getSelection();
const forceSelection = editorState.mustForceSelection();
Expand Down Expand Up @@ -136,10 +140,19 @@ class DraftEditorContents extends React.Component {
tree: editorState.getBlockTree(key),
};

wrapperTemplate = getWrapperTemplateForBlockType(blockType);
// 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 = getElementForBlockType(blockType);
const Element = (
blockRenderMap.get(blockType).element ||
blockRenderMap.get('unstyled').element
);

const depth = block.getDepth();
let className = this.props.blockStyleFn(block);

Expand Down
5 changes: 4 additions & 1 deletion src/component/handlers/edit/editOnPaste.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,10 @@ function editOnPaste(e: SyntheticClipboardEvent): void {

// If there is html paste data, try to parse that.
if (html) {
var htmlFragment = DraftPasteProcessor.processHTML(html);
var htmlFragment = DraftPasteProcessor.processHTML(
html,
this.props.blockRenderMap
);
if (htmlFragment) {
var htmlMap = BlockMapBuilder.createFromArray(htmlFragment);
this.update(insertFragment(this.props.editorState, htmlMap));
Expand Down
43 changes: 0 additions & 43 deletions src/component/utils/getElementForBlockType.js

This file was deleted.

43 changes: 0 additions & 43 deletions src/component/utils/getWrapperTemplateForBlockType.js

This file was deleted.

31 changes: 31 additions & 0 deletions src/model/constants/DraftBlockTag.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule DraftBlockTag
* @flow
*/

'use strict';

/**
* The list of default valid block tags.
*/
export type DraftBlockTag = (
'div' |
'p' |
'h1' |
'h2' |
'h3' |
'h4' |
'h5' |
'h6' |
'li' |
'blockquote' |
'pre' |
'figure'
);
1 change: 0 additions & 1 deletion src/model/constants/DraftBlockType.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export type DraftBlockType = (
'unordered-list-item' |
'ordered-list-item' |
'blockquote' |
'pullquote' |
'code-block' |
'atomic'
);
Loading

0 comments on commit 74ea5fe

Please sign in to comment.