diff --git a/package.json b/package.json
index 3b3d3fc6..54868350 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-rte",
- "version": "0.16.5",
+ "version": "0.16.7",
"description": "React Rich Text Editor",
"main": "dist/react-rte.js",
"files": [
@@ -22,7 +22,7 @@
"babel-runtime": "^6.23.0",
"class-autobind": "^0.1.4",
"classnames": "^2.2.5",
- "draft-js": ">=0.10.0",
+ "draft-js": "^0.11.7",
"draft-js-export-html": ">=0.6.0",
"draft-js-export-markdown": ">=0.3.0",
"draft-js-import-html": ">=0.4.0",
diff --git a/src/EditorDemo.js b/src/EditorDemo.js
index 420696c9..3ac912a2 100644
--- a/src/EditorDemo.js
+++ b/src/EditorDemo.js
@@ -1,10 +1,15 @@
/* @flow */
import React, {Component} from 'react';
-import RichTextEditor, {createEmptyValue} from './RichTextEditor';
+import RichTextEditor, {getColorStyles} from './RichTextEditor';
import {convertToRaw} from 'draft-js';
import autobind from 'class-autobind';
-import {getTextAlignBlockMetadata, getTextAlignClassName, getTextAlignStyles} from './lib/blockStyleFunctions';
+import {
+ getColorEntity,
+ getTextAlignBlockMetadata,
+ getTextAlignClassName,
+ getTextAlignStyles,
+} from './lib/blockStyleFunctions';
import ButtonGroup from './ui/ButtonGroup';
import Dropdown from './ui/Dropdown';
import IconButton from './ui/IconButton';
@@ -26,7 +31,7 @@ export default class EditorDemo extends Component {
super(...arguments);
autobind(this);
this.state = {
- value: createEmptyValue(),
+ value: RichTextEditor.createValueFromString("
Hello world
", 'html', {customInlineFn: getColorEntity}),
format: 'html',
readOnly: false,
};
@@ -113,7 +118,7 @@ export default class EditorDemo extends Component {
diff --git a/src/RichTextEditor.js b/src/RichTextEditor.js
index 8af9d6a7..af16a996 100644
--- a/src/RichTextEditor.js
+++ b/src/RichTextEditor.js
@@ -2,7 +2,7 @@
import React, {Component} from 'react';
import {CompositeDecorator, Editor, EditorState, Modifier, RichUtils, Entity} from 'draft-js';
import getDefaultKeyBinding from 'draft-js/lib/getDefaultKeyBinding';
-import {getTextAlignBlockMetadata, getTextAlignClassName, getTextAlignStyles} from './lib/blockStyleFunctions';
+import {getTextAlignBlockMetadata, getTextAlignClassName, getTextAlignStyles, getColorStyles} from './lib/blockStyleFunctions';
import changeBlockDepth from './lib/changeBlockDepth';
import changeBlockType from './lib/changeBlockType';
import getBlocksInSelection from './lib/getBlocksInSelection';
@@ -13,6 +13,8 @@ import EditorToolbar from './lib/EditorToolbar';
import EditorValue from './lib/EditorValue';
import LinkDecorator from './lib/LinkDecorator';
import ImageDecorator from './lib/ImageDecorator';
+import ColorDecorator from './lib/ColorDecorator';
+import BackgroundColorDecorator from './lib/BackgroundColorDecorator';
import composite from './lib/composite';
import cx from 'classnames';
import autobind from 'class-autobind';
@@ -189,10 +191,8 @@ export default class RichTextEditor extends Component {
if (this._handleReturnEmptyListItem()) {
return true;
}
- if (this._handleReturnSpecialBlock()) {
- return true;
- }
- return false;
+ return this._handleReturnSpecialBlock();
+
}
// `shift + return` should insert a soft newline.
@@ -359,7 +359,7 @@ function defaultBlockStyleFn(block: ContentBlock): string {
}
}
-const decorator = new CompositeDecorator([LinkDecorator, ImageDecorator]);
+const decorator = new CompositeDecorator([LinkDecorator, ImageDecorator, ColorDecorator, BackgroundColorDecorator]);
function createEmptyValue(): EditorValue {
return EditorValue.createEmpty(decorator);
@@ -388,6 +388,7 @@ export {
getTextAlignBlockMetadata,
getTextAlignClassName,
getTextAlignStyles,
+ getColorStyles,
ButtonGroup,
Button,
Dropdown,
diff --git a/src/lib/BackgroundColorDecorator.js b/src/lib/BackgroundColorDecorator.js
new file mode 100644
index 00000000..bb95e196
--- /dev/null
+++ b/src/lib/BackgroundColorDecorator.js
@@ -0,0 +1,35 @@
+/* @flow */
+import React from 'react';
+
+import type {ContentBlock, ContentState} from 'draft-js';
+
+type Props = {
+ children: ReactNode,
+ entityKey: string,
+ contentState: ContentState,
+};
+
+type EntityRangeCallback = (start: number, end: number) => void;
+
+function BackgroundColoredText(props: Props) {
+ const {backgroundColor} = props.contentState.getEntity(props.entityKey).getData();
+ return (
+ {props.children}
+ );
+}
+
+function findBackgroundColoredTextEntities(contentBlock: ContentBlock, callback: EntityRangeCallback, contentState: ?ContentState) {
+ contentBlock.findEntityRanges((character) => {
+ const entityKey = character.getEntity();
+ if (entityKey != null) {
+ let entity = contentState ? contentState.getEntity(entityKey) : null;
+ return entity != null && entity.getType() === 'backgroundColor';
+ }
+ return false;
+ }, callback);
+}
+
+export default {
+ strategy: findBackgroundColoredTextEntities,
+ component: BackgroundColoredText,
+};
diff --git a/src/lib/ColorDecorator.js b/src/lib/ColorDecorator.js
new file mode 100644
index 00000000..a721116c
--- /dev/null
+++ b/src/lib/ColorDecorator.js
@@ -0,0 +1,35 @@
+/* @flow */
+import React from 'react';
+
+import type {ContentBlock, ContentState} from 'draft-js';
+
+type Props = {
+ children: ReactNode,
+ entityKey: string,
+ contentState: ContentState,
+};
+
+type EntityRangeCallback = (start: number, end: number) => void;
+
+function ColoredText(props: Props) {
+ const {color} = props.contentState.getEntity(props.entityKey).getData();
+ return (
+ {props.children}
+ );
+}
+
+function findColoredTextEntities(contentBlock: ContentBlock, callback: EntityRangeCallback, contentState: ?ContentState) {
+ contentBlock.findEntityRanges((character) => {
+ const entityKey = character.getEntity();
+ if (entityKey != null) {
+ let entity = contentState ? contentState.getEntity(entityKey) : null;
+ return entity != null && entity.getType() === 'color';
+ }
+ return false;
+ }, callback);
+}
+
+export default {
+ strategy: findColoredTextEntities,
+ component: ColoredText,
+};
diff --git a/src/lib/EditorToolbar.js b/src/lib/EditorToolbar.js
index e6189943..8f82ed57 100644
--- a/src/lib/EditorToolbar.js
+++ b/src/lib/EditorToolbar.js
@@ -33,11 +33,14 @@ type Props = {
customControls: Array;
rootStyle?: Object;
isOnBottom?: boolean;
+ customStyleMap?: Object;
};
type State = {
showLinkInput: boolean;
showImageInput: boolean;
+ showBackgroundColorInput: boolean;
+ showTextColorInput: boolean;
customControlState: {[key: string]: string};
};
@@ -52,6 +55,8 @@ export default class EditorToolbar extends Component {
this.state = {
showLinkInput: false,
showImageInput: false,
+ showTextColorInput: false,
+ showBackgroundColorInput: false,
customControlState: {},
};
}
@@ -96,6 +101,9 @@ export default class EditorToolbar extends Component {
case 'HISTORY_BUTTONS': {
return this._renderUndoRedo(groupName, toolbarConfig);
}
+ case 'COLOR_BUTTONS': {
+ return this._renderBlockColorButtons(groupName, toolbarConfig);
+ }
}
});
return (
@@ -219,6 +227,39 @@ export default class EditorToolbar extends Component {
);
}
+ _renderBlockColorButtons(name: string, toolbarConfig: ToolbarConfig) {
+ let {editorState} = this.props;
+ let content = editorState.getCurrentContent();
+ let selection = editorState.getSelection();
+ let blockKey = selection.getStartKey();
+ let block = content.getBlockForKey(blockKey);
+ let textColor = block.getData().get('textColor');
+
+ let entity = this._getEntityAtCursor();
+ let isCursorOnLink = (entity != null && entity.type === ENTITY_TYPE.LINK);
+ let defaultTextColorValue = (entity && isCursorOnLink) ? entity.getData().url : '';
+
+ const config = toolbarConfig.BLOCK_COLOR_BUTTONS || {};
+ const textColorConfig = config.textColor || {};
+ const textColorLabel = textColorConfig.label || 'Text color';
+
+ return (
+
+
+
+ );
+ }
+
_renderLinkButtons(name: string, toolbarConfig: ToolbarConfig) {
let {editorState} = this.props;
let selection = editorState.getSelection();
@@ -320,9 +361,16 @@ export default class EditorToolbar extends Component {
}
}
- _toggleShowLinkInput(event: ?Object) {
- let isShowing = this.state.showLinkInput;
- // If this is a hide request, decide if we should focus the editor.
+ _toggleShowColorInput(inputType: 'showTextColorInput' | 'showBackgroundColorInput') {
+ return (event: ?Object) => {
+ let isShowing = this.state[inputType];
+ // If this is a hide request, decide if we should focus the editor.
+ this._handlePopOverShow(isShowing, event);
+ this.setState({[inputType]: !isShowing});
+ };
+ }
+
+ _handlePopOverShow(isShowing, event) {
if (isShowing) {
let shouldFocusEditor = true;
if (event && event.type === 'click') {
@@ -338,27 +386,19 @@ export default class EditorToolbar extends Component {
this.props.focusEditor();
}
}
+ }
+
+ _toggleShowLinkInput(event: ?Object) {
+ let isShowing = this.state.showLinkInput;
+ // If this is a hide request, decide if we should focus the editor.
+ this._handlePopOverShow(isShowing, event);
this.setState({showLinkInput: !isShowing});
}
_toggleShowImageInput(event: ?Object) {
let isShowing = this.state.showImageInput;
// If this is a hide request, decide if we should focus the editor.
- if (isShowing) {
- let shouldFocusEditor = true;
- if (event && event.type === 'click') {
- // TODO: Use a better way to get the editor root node.
- let editorRoot = ReactDOM.findDOMNode(this).parentNode;
- let {activeElement} = document;
- let wasClickAway = (activeElement == null || activeElement === document.body);
- if (!wasClickAway && !editorRoot.contains(activeElement)) {
- shouldFocusEditor = false;
- }
- }
- if (shouldFocusEditor) {
- this.props.focusEditor();
- }
- }
+ this._handlePopOverShow(isShowing, event);
this.setState({showImageInput: !isShowing});
}
@@ -376,6 +416,33 @@ export default class EditorToolbar extends Component {
this._focusEditor();
}
+ _setColor(toggledColor: string) {
+ this._setColorWithType(toggledColor, 'color', 'showTextColorInput');
+ }
+
+ _setBackgroundColor(toggledColor: string) {
+ this._setColorWithType(toggledColor, 'backgroundColor', 'showBackgroundColorInput');
+ }
+
+ _setColorWithType(toggledColor: string, type: string, inputKey: string) {
+ let {editorState} = this.props;
+ let contentState = editorState.getCurrentContent();
+ let selection = editorState.getSelection();
+
+ let origSelection = selection;
+
+ this.setState({[inputKey]: false});
+ contentState = contentState.createEntity(type, 'MUTABLE', {[type]: toggledColor});
+ let entityKey = contentState.getLastCreatedEntityKey();
+
+ editorState = EditorState.push(editorState, contentState);
+ editorState = RichUtils.toggleLink(editorState, selection, entityKey);
+ editorState = EditorState.acceptSelection(editorState, origSelection);
+
+ this.props.onChange(editorState);
+ this._focusEditor();
+ }
+
_setLink(url: string, checkOptions: {[key: string]: boolean}) {
let {editorState} = this.props;
let contentState = editorState.getCurrentContent();
diff --git a/src/lib/EditorToolbarConfig.js b/src/lib/EditorToolbarConfig.js
index 4d91389f..c73e0e0a 100644
--- a/src/lib/EditorToolbarConfig.js
+++ b/src/lib/EditorToolbarConfig.js
@@ -15,7 +15,7 @@ export type CustomControlList = Array;
export type StyleConfigList = Array;
-export type GroupName = 'INLINE_STYLE_BUTTONS' | 'BLOCK_ALIGNMENT_BUTTONS' | 'BLOCK_TYPE_BUTTONS' | 'LINK_BUTTONS' | 'BLOCK_TYPE_DROPDOWN' | 'HISTORY_BUTTONS' | 'IMAGE_BUTTON';
+export type GroupName = 'INLINE_STYLE_BUTTONS' | 'BLOCK_ALIGNMENT_BUTTONS' | 'BLOCK_TYPE_BUTTONS' | 'LINK_BUTTONS' | 'BLOCK_TYPE_DROPDOWN' | 'HISTORY_BUTTONS' | 'IMAGE_BUTTON' | 'COLOR_BUTTONS';
export type ToolbarConfig = {
display: Array;
@@ -24,6 +24,7 @@ export type ToolbarConfig = {
BLOCK_ALIGNMENT_BUTTONS: StyleConfigList;
BLOCK_TYPE_DROPDOWN: StyleConfigList;
BLOCK_TYPE_BUTTONS: StyleConfigList;
+ BLOCK_COLOR_BUTTONS: StyleConfigList;
};
export const INLINE_STYLE_BUTTONS: StyleConfigList = [
@@ -54,12 +55,18 @@ export const BLOCK_TYPE_BUTTONS: StyleConfigList = [
{label: 'Blockquote', style: 'blockquote'},
];
+export const BLOCK_COLOR_BUTTONS: StyleConfigList = [
+ {label: 'Text color', style: 'TEXT_COLOR'},
+ {label: 'Background color', style: 'BACKGROUND_COLOR'},
+];
+
let EditorToolbarConfig: ToolbarConfig = {
- display: ['INLINE_STYLE_BUTTONS', 'BLOCK_ALIGNMENT_BUTTONS', 'BLOCK_TYPE_BUTTONS', 'LINK_BUTTONS', 'IMAGE_BUTTON', 'BLOCK_TYPE_DROPDOWN', 'HISTORY_BUTTONS'],
+ display: ['INLINE_STYLE_BUTTONS', 'BLOCK_ALIGNMENT_BUTTONS', 'COLOR_BUTTONS', 'BLOCK_TYPE_BUTTONS', 'LINK_BUTTONS', 'IMAGE_BUTTON', 'BLOCK_TYPE_DROPDOWN', 'HISTORY_BUTTONS'],
INLINE_STYLE_BUTTONS,
BLOCK_ALIGNMENT_BUTTONS,
BLOCK_TYPE_DROPDOWN,
BLOCK_TYPE_BUTTONS,
+ BLOCK_COLOR_BUTTONS,
};
export default EditorToolbarConfig;
diff --git a/src/lib/blockStyleFunctions.js b/src/lib/blockStyleFunctions.js
index fcd2e2fe..a9a977d7 100644
--- a/src/lib/blockStyleFunctions.js
+++ b/src/lib/blockStyleFunctions.js
@@ -1,5 +1,6 @@
/* @flow */
-import type {BlockStyleFn, CustomBlockFn} from 'draft-js-import-html';
+import type {BlockStyleFn, CustomBlockFn, CustomInlineFn} from 'draft-js-import-html';
+import {EntityStyleFn} from 'draft-js-export-html';
export const getTextAlignClassName: BlockStyleFn = (contentBlock) => {
switch (contentBlock.getData().get('textAlign')) {
@@ -89,3 +90,23 @@ export const getTextAlignBlockMetadata: CustomBlockFn = (element) => {
return {};
}
};
+
+export const getColorStyles: EntityStyleFn = (contentBlock) => {
+ if ((contentBlock.get('data') && contentBlock.get('data')['color'])
+ || (contentBlock.get('data') && contentBlock.get('data')['backgroundColor'])) {
+ return {
+ style: {...contentBlock.get('data')},
+ };
+ }
+ return null;
+};
+
+export const getColorEntity: CustomInlineFn = (element, inlineCreators) => {
+ if (element && element.style && element.style.color) {
+ return inlineCreators.Entity('color', {color: element.style.color});
+ }
+ if (element && element.style && element.style.backgroundColor) {
+ return inlineCreators.Entity('backgroundColor', {backgroundColor: element.style.backgroundColor});
+ }
+ return element;
+};
diff --git a/src/ui/IconButton.css b/src/ui/IconButton.css
index fb28a87d..a5bf7b13 100644
--- a/src/ui/IconButton.css
+++ b/src/ui/IconButton.css
@@ -110,4 +110,14 @@
.icon-align_justify {
composes: icon;
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDE2IDE2Ij4KPHBhdGggZD0iTTEuOCw4LjdoMTIuM1YxMEgxLjhWOC43eiBNMS44LDEyLjdoMTIuM3YtMS4zSDEuOFYxMi43eiBNMS44LDcuM2gxMi4zVjZIMS44VjcuM3ogTTEuOCwzLjN2MS4zaDEyLjNWMy4zSDEuOHoiLz4KPC9zdmc+Cg==");
-}
\ No newline at end of file
+}
+
+.icon-textColor {
+ composes: icon;
+ background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNnB4IiBoZWlnaHQ9IjE2cHgiIHZpZXdCb3g9IjAgMCAxNiAxNiIgdmVyc2lvbj0iMS4xIj4NCjxwYXRoIHN0eWxlPSIgc3Ryb2tlOm5vbmU7ZmlsbC1ydWxlOm5vbnplcm87ZmlsbDpyZ2IoMCUsMCUsMCUpO2ZpbGwtb3BhY2l0eToxOyIgZD0iTSA3LjMzMjAzMSAyIEwgMy42Njc5NjkgMTEuMzMyMDMxIEwgNS4xNjc5NjkgMTEuMzMyMDMxIEwgNS45MTQwNjIgOS4zMzIwMzEgTCAxMC4wNzgxMjUgOS4zMzIwMzEgTCAxMC44MjgxMjUgMTEuMzMyMDMxIEwgMTIuMzI4MTI1IDExLjMzMjAzMSBMIDguNjY3OTY5IDIgWiBNIDYuNDE0MDYyIDggTCA4IDMuNzgxMjUgTCA5LjU4NTkzOCA4IFogTSA2LjQxNDA2MiA4ICIvPg0KPC9zdmc+");
+}
+
+.icon-backgroundColor {
+ composes: icon;
+ background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNnB4IiBoZWlnaHQ9IjE2cHgiIHZpZXdCb3g9IjAgMCAxNiAxNiIgdmVyc2lvbj0iMS4xIj4NCjxwYXRoIGQ9Ik0gMTEuMDM5MDYyIDUuOTYwOTM4IEwgNS4wNzgxMjUgMCBMIDQuMTQwNjI1IDAuOTQxNDA2IEwgNS43MjY1NjIgMi41MjczNDQgTCAyLjI5Mjk2OSA1Ljk2MDkzOCBDIDEuODk4NDM4IDYuMzUxNTYyIDEuODk4NDM4IDYuOTg4MjgxIDIuMjkyOTY5IDcuMzc1IEwgNS45NjA5MzggMTEuMDM5MDYyIEMgNi4xNTIzNDQgMTEuMjM0Mzc1IDYuNDE0MDYyIDExLjMzMjAzMSA2LjY2Nzk2OSAxMS4zMzIwMzEgQyA2LjkyMTg3NSAxMS4zMzIwMzEgNy4xNzk2ODggMTEuMjM0Mzc1IDcuMzc1IDExLjAzOTA2MiBMIDExLjAzOTA2MiA3LjM3NSBDIDExLjQzMzU5NCA2Ljk4ODI4MSAxMS40MzM1OTQgNi4zNTE1NjIgMTEuMDM5MDYyIDUuOTYwOTM4IFogTSAzLjQ3MjY1NiA2LjY2Nzk2OSBMIDYuNjY3OTY5IDMuNDcyNjU2IEwgOS44NTkzNzUgNi42Njc5NjkgWiBNIDEyLjY2Nzk2OSA3LjY2Nzk2OSBDIDEyLjY2Nzk2OSA3LjY2Nzk2OSAxMS4zMzIwMzEgOS4xMTMyODEgMTEuMzMyMDMxIDEwIEMgMTEuMzMyMDMxIDEwLjczNDM3NSAxMS45MzM1OTQgMTEuMzMyMDMxIDEyLjY2Nzk2OSAxMS4zMzIwMzEgQyAxMy4zOTg0MzggMTEuMzMyMDMxIDE0IDEwLjczNDM3NSAxNCAxMCBDIDE0IDkuMTEzMjgxIDEyLjY2Nzk2OSA3LjY2Nzk2OSAxMi42Njc5NjkgNy42Njc5NjkgWiBNIDEyLjY2Nzk2OSA3LjY2Nzk2OSAiLz4NCjxwYXRoIGQ9Ik0gMCAxMy4zMzIwMzEgTCAxNiAxMy4zMzIwMzEgTCAxNiAxNiBMIDAgMTYgWiBNIDAgMTMuMzMyMDMxICIvPg0KPC9zdmc+DQo=");
+}
diff --git a/src/ui/InputPopover.js b/src/ui/InputPopover.js
index 114ed92a..172bcceb 100644
--- a/src/ui/InputPopover.js
+++ b/src/ui/InputPopover.js
@@ -18,6 +18,7 @@ type Props = {
checkOptions?: {
[key: string]: { label: string, defaultValue: boolean };
};
+ type?: 'button' | 'checkbox' | 'color' | 'date' | 'datetime' | 'email' | 'file' | 'hidden' | 'image' | 'month' | 'number' | 'password' | 'radio' | 'range' | 'reset' | 'search' | 'submit' | 'tel' | 'text' | 'time' | 'url' | 'week';
onCancel: () => any;
onSubmit: (value: string, checkOptionValues: CheckOptionValues) => any;
};
@@ -69,7 +70,7 @@ export default class InputPopover extends Component {
);
}
diff --git a/yarn.lock b/yarn.lock
index 69d8d479..63df2e76 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1357,6 +1357,11 @@ core-js@^2.4.0, core-js@^2.5.0:
version "2.5.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b"
+core-js@^3.6.4:
+ version "3.21.0"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.21.0.tgz#f479dbfc3dffb035a0827602dd056839a774aa71"
+ integrity sha512-YUdI3fFu4TF/2WykQ2xzSiTQdldLB4KVuL9WeAy5XONZYt5Cun/fpQvctoKbCgvPhmzADeesTk/j2Rdx77AcKQ==
+
core-util-is@1.0.2, core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
@@ -1388,6 +1393,13 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
+cross-fetch@^3.0.4:
+ version "3.1.5"
+ resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f"
+ integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==
+ dependencies:
+ node-fetch "2.6.7"
+
cross-spawn@^5.0.1:
version "5.1.0"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
@@ -1707,13 +1719,14 @@ draft-js-utils@>=0.2.0, draft-js-utils@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/draft-js-utils/-/draft-js-utils-1.1.0.tgz#652876abdd4910a7996b1fdb64c8d771e4397f75"
-draft-js@>=0.10.0:
- version "0.10.1"
- resolved "https://registry.yarnpkg.com/draft-js/-/draft-js-0.10.1.tgz#6f1219d8095729691429ca6fd7a58d2a8be5cb67"
+draft-js@^0.11.7:
+ version "0.11.7"
+ resolved "https://registry.yarnpkg.com/draft-js/-/draft-js-0.11.7.tgz#be293aaa255c46d8a6647f3860aa4c178484a206"
+ integrity sha512-ne7yFfN4sEL82QPQEn80xnADR8/Q6ALVworbC5UOSzOvjffmYfFsr3xSZtxbIirti14R7Y33EZC5rivpLgIbsg==
dependencies:
- fbjs "^0.8.7"
+ fbjs "^2.0.0"
immutable "~3.7.4"
- object-assign "^4.1.0"
+ object-assign "^4.1.1"
ecc-jsbn@~0.1.1:
version "0.1.1"
@@ -2100,6 +2113,11 @@ faye-websocket@~0.11.0:
dependencies:
websocket-driver ">=0.5.1"
+fbjs-css-vars@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8"
+ integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==
+
fbjs@^0.8.16:
version "0.8.16"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
@@ -2112,17 +2130,19 @@ fbjs@^0.8.16:
setimmediate "^1.0.5"
ua-parser-js "^0.7.9"
-fbjs@^0.8.7:
- version "0.8.15"
- resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.15.tgz#4f0695fdfcc16c37c0b07facec8cb4c4091685b9"
+fbjs@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-2.0.0.tgz#01fb812138d7e31831ed3e374afe27b9169ef442"
+ integrity sha512-8XA8ny9ifxrAWlyhAbexXcs3rRMtxWcs3M0lctLfB49jRDHiaxj+Mo0XxbwE7nKZYzgCFoq64FS+WFd4IycPPQ==
dependencies:
- core-js "^1.0.0"
- isomorphic-fetch "^2.1.1"
+ core-js "^3.6.4"
+ cross-fetch "^3.0.4"
+ fbjs-css-vars "^1.0.0"
loose-envify "^1.0.0"
object-assign "^4.1.0"
promise "^7.1.1"
setimmediate "^1.0.5"
- ua-parser-js "^0.7.9"
+ ua-parser-js "^0.7.18"
figures@^1.3.5:
version "1.7.0"
@@ -3366,6 +3386,13 @@ negotiator@0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
+node-fetch@2.6.7:
+ version "2.6.7"
+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
+ integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
+ dependencies:
+ whatwg-url "^5.0.0"
+
node-fetch@^1.0.1:
version "1.7.3"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
@@ -4894,6 +4921,11 @@ tough-cookie@~2.3.0:
dependencies:
punycode "^1.4.1"
+tr46@~0.0.3:
+ version "0.0.3"
+ resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
+ integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
+
trim-newlines@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613"
@@ -4937,6 +4969,11 @@ typedarray@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
+ua-parser-js@^0.7.18:
+ version "0.7.31"
+ resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6"
+ integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==
+
ua-parser-js@^0.7.9:
version "0.7.14"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.14.tgz#110d53fa4c3f326c121292bbeac904d2e03387ca"
@@ -5086,6 +5123,11 @@ wbuf@^1.1.0, wbuf@^1.7.2:
dependencies:
minimalistic-assert "^1.0.0"
+webidl-conversions@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
+ integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=
+
webpack-dev-middleware@^1.11.0:
version "1.12.0"
resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.12.0.tgz#d34efefb2edda7e1d3b5dbe07289513219651709"
@@ -5172,6 +5214,14 @@ whatwg-fetch@>=0.10.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"
+whatwg-url@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
+ integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0=
+ dependencies:
+ tr46 "~0.0.3"
+ webidl-conversions "^3.0.0"
+
whet.extend@~0.9.9:
version "0.9.9"
resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1"