Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

draft-js

Package Overview
Dependencies
Maintainers
5
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

draft-js - npm Package Compare versions

Comparing version 0.9.1 to 0.10.0

lib/addEntityToContentState.js

27

CHANGELOG.md

@@ -7,4 +7,31 @@ # Changelog

## 0.10.0 (Dec. 16, 2016)
### Added
* Add improved API for entity manipulation to contentState
* Add deprecation warnings to old Entity module API
* Add image support to convertFromHTML
* Add option of 'aliasedElements' in block render map
### Changed
* This version supports both the old and new Entity API; we
are deprecating the Entity module in favor of
using contentState.
### Fixed
* Fix bug where block data was not removed when deleting atomic block
* Fix bug preventing pasting from clipboard
* Fix dead key deletion and deletion in 2-Set Korean
* Fix ContentState.createFromBlockArray to allow taking an empty array
* Improve typing in Korean on Windows
## 0.9.1 (September 16, 2016)
### Added
* `customStyleFn` for more control over inline style ranges
### Fixed

@@ -11,0 +38,0 @@

4

lib/BlockTree.js

@@ -49,3 +49,3 @@ /**

*/
generate: function generate(block, decorator) {
generate: function generate(contentState, block, decorator) {
var textLength = block.getLength();

@@ -62,3 +62,3 @@ if (!textLength) {

var leafSets = [];
var decorations = decorator ? decorator.getDecorations(block) : List(Repeat(null, textLength));
var decorations = decorator ? decorator.getDecorations(block, contentState) : List(Repeat(null, textLength));

@@ -65,0 +65,0 @@ var chars = block.getCharacterList();

@@ -28,2 +28,4 @@ /**

// Immutable.map is typed such that the value for every key in the map
// must be the same type

@@ -88,4 +90,6 @@ var EMPTY_SET = OrderedSet();

var defaultConfig = { style: EMPTY_SET, entity: null };
// Fill in unspecified properties, if necessary.
var configMap = Map({ style: EMPTY_SET, entity: null }).merge(config);
var configMap = Map(defaultConfig).merge(config);

@@ -92,0 +96,0 @@ var existing = pool.get(configMap);

@@ -18,5 +18,6 @@ /**

'TOKEN': true,
'PHOTO': true
'PHOTO': true,
'IMAGE': true
};
module.exports = ComposedEntityType;

@@ -55,3 +55,3 @@ /**

CompositeDraftDecorator.prototype.getDecorations = function getDecorations(block) {
CompositeDraftDecorator.prototype.getDecorations = function getDecorations(block, contentState) {
var decorations = Array(block.getText().length).fill(null);

@@ -62,3 +62,3 @@

var strategy = decorator.strategy;
strategy(block, function ( /*number*/start, /*number*/end) {
var callback = function callback( /*number*/start, /*number*/end) {
// Find out if any of our matching range is already occupied

@@ -71,3 +71,4 @@ // by another decorator. If so, discard the match. Otherwise, store

}
});
};
strategy(block, callback, contentState);
});

@@ -74,0 +75,0 @@

@@ -25,2 +25,3 @@ /**

var ContentBlock = require('./ContentBlock');
var DraftEntity = require('./DraftEntity');
var Immutable = require('immutable');

@@ -38,2 +39,3 @@ var SelectionState = require('./SelectionState');

var defaultRecord = {
entityMap: null,
blockMap: null,

@@ -55,2 +57,7 @@ selectionBefore: null,

ContentState.prototype.getEntityMap = function getEntityMap() {
// TODO: update this when we fully remove DraftEntity
return DraftEntity;
};
ContentState.prototype.getBlockMap = function getBlockMap() {

@@ -115,2 +122,7 @@ return this.get('blockMap');

ContentState.prototype.getLastCreatedEntityKey = function getLastCreatedEntityKey() {
// TODO: update this when we fully remove DraftEntity
return DraftEntity.__getLastCreatedEntityKey();
};
ContentState.prototype.hasText = function hasText() {

@@ -121,7 +133,41 @@ var blockMap = this.getBlockMap();

ContentState.createFromBlockArray = function createFromBlockArray(blocks) {
var blockMap = BlockMapBuilder.createFromArray(blocks);
var selectionState = SelectionState.createEmpty(blockMap.first().getKey());
ContentState.prototype.createEntity = function createEntity(type, mutability, data) {
// TODO: update this when we fully remove DraftEntity
DraftEntity.__create(type, mutability, data);
return this;
};
ContentState.prototype.mergeEntityData = function mergeEntityData(key, toMerge) {
// TODO: update this when we fully remove DraftEntity
DraftEntity.__mergeData(key, toMerge);
return this;
};
ContentState.prototype.replaceEntityData = function replaceEntityData(key, newData) {
// TODO: update this when we fully remove DraftEntity
DraftEntity.__replaceData(key, newData);
return this;
};
ContentState.prototype.addEntity = function addEntity(instance) {
// TODO: update this when we fully remove DraftEntity
DraftEntity.__add(instance);
return this;
};
ContentState.prototype.getEntity = function getEntity(key) {
// TODO: update this when we fully remove DraftEntity
return DraftEntity.__get(key);
};
ContentState.createFromBlockArray = function createFromBlockArray(
// TODO: update flow type when we completely deprecate the old entity API
blocks, entityMap) {
// TODO: remove this when we completely deprecate the old entity API
var theBlocks = Array.isArray(blocks) ? blocks : blocks.contentBlocks;
var blockMap = BlockMapBuilder.createFromArray(theBlocks);
var selectionState = blockMap.isEmpty() ? new SelectionState() : SelectionState.createEmpty(blockMap.first().getKey());
return new ContentState({
blockMap: blockMap,
entityMap: entityMap || DraftEntity,
selectionBefore: selectionState,

@@ -128,0 +174,0 @@ selectionAfter: selectionState

@@ -15,3 +15,2 @@ /**

var DraftEntity = require('./DraftEntity');
var DraftStringKey = require('./DraftStringKey');

@@ -54,3 +53,3 @@

entityKeys.forEach(function (key, jj) {
var entity = DraftEntity.get(DraftStringKey.unstringify(key));
var entity = contentState.getEntity(DraftStringKey.unstringify(key));
flippedStorageMap[jj] = {

@@ -57,0 +56,0 @@ type: entity.getType(),

@@ -29,2 +29,5 @@ /**

var _require = require('immutable');
var Set = _require.Set;
var List = Immutable.List;

@@ -67,2 +70,4 @@ var OrderedSet = Immutable.OrderedSet;

var imgAttr = ['alt', 'className', 'height', 'src', 'width'];
var lastBlock;

@@ -122,5 +127,15 @@

var unstyledElement = blockRenderMap.get('unstyled').element;
return blockRenderMap.map(function (config) {
return config.element;
}).valueSeq().toSet().filter(function (tag) {
var tags = new Set([]);
blockRenderMap.forEach(function (draftBlock) {
if (draftBlock.aliasedElements) {
draftBlock.aliasedElements.forEach(function (tag) {
tags = tags.add(tag);
});
}
tags = tags.add(draftBlock.element);
});
return tags.filter(function (tag) {
return tag && tag !== unstyledElement;

@@ -142,4 +157,6 @@ }).toArray().sort();

function getBlockTypeForTag(tag, lastList, blockRenderMap) {
var matchedTypes = blockRenderMap.filter(function (config) {
return config.element === tag || config.wrapper === tag;
var matchedTypes = blockRenderMap.filter(function (draftBlock) {
return draftBlock.element === tag || draftBlock.wrapper === tag || draftBlock.aliasedElements && draftBlock.aliasedElements.some(function (alias) {
return alias === tag;
});
}).keySeq().toSet().toArray().sort();

@@ -249,3 +266,3 @@

function genFragment(node, inlineStyle, lastList, inBlock, blockTags, depth, blockRenderMap, inEntity) {
function genFragment(entityMap, node, inlineStyle, lastList, inBlock, blockTags, depth, blockRenderMap, inEntity) {
var nodeName = node.nodeName.toLowerCase();

@@ -255,2 +272,3 @@ var newBlock = false;

var lastLastBlock = lastBlock;
var newEntityMap = entityMap;

@@ -261,3 +279,3 @@ // Base Case

if (text.trim() === '' && inBlock !== 'pre') {
return getWhitespaceChunk(inEntity);
return { chunk: getWhitespaceChunk(inEntity), entityMap: entityMap };
}

@@ -273,6 +291,9 @@ if (inBlock !== 'pre') {

return {
text: text,
inlines: Array(text.length).fill(inlineStyle),
entities: Array(text.length).fill(inEntity),
blocks: []
chunk: {
text: text,
inlines: Array(text.length).fill(inlineStyle),
entities: Array(text.length).fill(inEntity),
blocks: []
},
entityMap: entityMap
};

@@ -287,7 +308,27 @@ }

if (lastLastBlock === 'br' && (!inBlock || getBlockTypeForTag(inBlock, lastList, blockRenderMap) === 'unstyled')) {
return getBlockDividerChunk('unstyled', depth);
return { chunk: getBlockDividerChunk('unstyled', depth), entityMap: entityMap };
}
return getSoftNewlineChunk();
return { chunk: getSoftNewlineChunk(), entityMap: entityMap };
}
// IMG tags
if (nodeName === 'img' && node instanceof HTMLImageElement && node.attributes.getNamedItem('src') && node.attributes.getNamedItem('src').value) {
(function () {
var image = node;
var entityConfig = {};
imgAttr.forEach(function (attr) {
var imageAttribute = image.getAttribute(attr);
if (imageAttribute) {
entityConfig[attr] = imageAttribute;
}
});
var imageURI = new URI(entityConfig.src).toString();
node.textContent = imageURI; // Output src if no decorator
// TODO: update this when we remove DraftEntity entirely
inEntity = DraftEntity.__create('IMAGE', 'MUTABLE', entityConfig || {});
})();
}
var chunk = getEmptyChunk();

@@ -341,4 +382,4 @@ var newChunk = null;

entityConfig.url = new URI(anchor.href).toString();
entityId = DraftEntity.create('LINK', 'MUTABLE', entityConfig);
// TODO: update this when we remove DraftEntity completely
entityId = DraftEntity.__create('LINK', 'MUTABLE', entityConfig || {});
})();

@@ -349,4 +390,11 @@ } else {

newChunk = genFragment(child, inlineStyle, lastList, inBlock, blockTags, depth, blockRenderMap, entityId || inEntity);
var _genFragment = genFragment(newEntityMap, child, inlineStyle, lastList, inBlock, blockTags, depth, blockRenderMap, entityId || inEntity);
var generatedChunk = _genFragment.chunk;
var maybeUpdatedEntityMap = _genFragment.entityMap;
newChunk = generatedChunk;
newEntityMap = maybeUpdatedEntityMap;
chunk = joinChunks(chunk, newChunk);

@@ -369,6 +417,6 @@ var sibling = child.nextSibling;

return chunk;
return { chunk: chunk, entityMap: newEntityMap };
}
function getChunkForHTML(html, DOMBuilder, blockRenderMap) {
function getChunkForHTML(html, DOMBuilder, blockRenderMap, entityMap) {
html = html.trim().replace(REGEX_CR, '').replace(REGEX_NBSP, SPACE).replace(REGEX_CARRIAGE, '').replace(REGEX_ZWS, '');

@@ -391,5 +439,10 @@

// UL block to start with.
var chunk = genFragment(safeBody, OrderedSet(), 'ul', null, workingBlocks, -1, blockRenderMap);
var _genFragment2 = genFragment(entityMap, safeBody, OrderedSet(), 'ul', null, workingBlocks, -1, blockRenderMap);
var chunk = _genFragment2.chunk;
var newEntityMap = _genFragment2.entityMap;
// join with previous block to prevent weirdness on paste
if (chunk.text.indexOf('\r') === 0) {

@@ -424,3 +477,3 @@ chunk = {

return chunk;
return { chunk: chunk, entityMap: newEntityMap };
}

@@ -436,33 +489,42 @@

var chunk = getChunkForHTML(html, DOMBuilder, blockRenderMap);
// TODO: replace DraftEntity with an OrderedMap here
var chunkData = getChunkForHTML(html, DOMBuilder, blockRenderMap, DraftEntity);
if (chunk == null) {
if (chunkData == null) {
return null;
}
var chunk = chunkData.chunk;
var newEntityMap = chunkData.entityMap;
var start = 0;
return chunk.text.split('\r').map(function (textBlock, ii) {
// Make absolutely certain that our text is acceptable.
textBlock = sanitizeDraftText(textBlock);
var end = start + textBlock.length;
var inlines = nullthrows(chunk).inlines.slice(start, end);
var entities = nullthrows(chunk).entities.slice(start, end);
var characterList = List(inlines.map(function (style, ii) {
var data = { style: style, entity: null };
if (entities[ii]) {
data.entity = entities[ii];
}
return CharacterMetadata.create(data);
}));
start = end + 1;
return {
contentBlocks: chunk.text.split('\r').map(function (textBlock, ii) {
// Make absolutely certain that our text is acceptable.
textBlock = sanitizeDraftText(textBlock);
var end = start + textBlock.length;
var inlines = nullthrows(chunk).inlines.slice(start, end);
var entities = nullthrows(chunk).entities.slice(start, end);
var characterList = List(inlines.map(function (style, ii) {
var data = { style: style, entity: null };
if (entities[ii]) {
data.entity = entities[ii];
}
return CharacterMetadata.create(data);
}));
start = end + 1;
return new ContentBlock({
key: generateRandomKey(),
type: nullthrows(chunk).blocks[ii].type,
depth: nullthrows(chunk).blocks[ii].depth,
text: textBlock,
characterList: characterList
});
});
return new ContentBlock({
key: generateRandomKey(),
type: nullthrows(chunk).blocks[ii].type,
depth: nullthrows(chunk).blocks[ii].depth,
text: textBlock,
characterList: characterList
});
}),
entityMap: newEntityMap
};
}
module.exports = convertFromHTMLtoContentBlocks;

@@ -22,3 +22,2 @@ /**

var DraftEntity = require('./DraftEntity');
var Immutable = require('immutable');

@@ -29,2 +28,3 @@ var createCharacterList = require('./createCharacterList');

var generateRandomKey = require('./generateRandomKey');
var Immutable = require('immutable');

@@ -40,2 +40,4 @@ var Map = Immutable.Map;

var fromStorageToLocal = {};
// TODO: Update this once we completely remove DraftEntity
Object.keys(entityMap).forEach(function (storageKey) {

@@ -47,3 +49,3 @@ var encodedEntity = entityMap[storageKey];

var newKey = DraftEntity.create(type, mutability, data || {});
var newKey = DraftEntity.__create(type, mutability, data || {});
fromStorageToLocal[storageKey] = newKey;

@@ -50,0 +52,0 @@ });

@@ -27,3 +27,3 @@ /**

module.exports = Map({
var DefaultDraftBlockRenderMap = Map({
'header-one': {

@@ -66,4 +66,7 @@ element: 'h1'

'unstyled': {
element: 'div'
element: 'div',
aliasedElements: ['p']
}
});
});
module.exports = DefaultDraftBlockRenderMap;

@@ -24,4 +24,4 @@ /**

var DraftEditorBlock = require('./DraftEditorBlock.react');
var DraftEntity = require('./DraftEntity');
var DraftModifier = require('./DraftModifier');
var DraftEntity = require('./DraftEntity');
var DraftEntityInstance = require('./DraftEntityInstance');

@@ -28,0 +28,0 @@ var EditorState = require('./EditorState');

@@ -12,2 +12,3 @@ /**

*
* @preventMunge
*/

@@ -79,3 +80,2 @@

_this._clipboard = null;
_this._guardAgainstRender = false;
_this._handler = null;

@@ -85,2 +85,3 @@ _this._dragCount = 0;

_this._placeholderAccessibilityID = 'placeholder-' + _this._editorKey;
_this._latestEditorState = props.editorState;

@@ -114,4 +115,2 @@ _this._onBeforeInput = _this._buildHandler('onBeforeInput');

_this.restoreEditorDOM = _this._restoreEditorDOM.bind(_this);
_this.setRenderGuard = _this._setRenderGuard.bind(_this);
_this.removeRenderGuard = _this._removeRenderGuard.bind(_this);
_this.setClipboard = _this._setClipboard.bind(_this);

@@ -149,3 +148,3 @@ _this.getClipboard = _this._getClipboard.bind(_this);

var method = _this2._handler && _this2._handler[eventName];
method && method.call(_this2, e);
method && method(_this2, e);
}

@@ -276,4 +275,5 @@ };

DraftEditor.prototype.componentWillUpdate = function componentWillUpdate() {
DraftEditor.prototype.componentWillUpdate = function componentWillUpdate(nextProps) {
this._blockSelectEvents = true;
this._latestEditorState = nextProps.editorState;
};

@@ -368,17 +368,2 @@

/**
* Guard against rendering. Intended for use when we need to manually
* reset editor contents, to ensure that no outside influences lead to
* React reconciliation when we are in an uncertain state.
*/
DraftEditor.prototype._setRenderGuard = function _setRenderGuard() {
this._guardAgainstRender = true;
};
DraftEditor.prototype._removeRenderGuard = function _removeRenderGuard() {
this._guardAgainstRender = false;
};
/**
* Used via `this.setClipboard(...)`.

@@ -417,2 +402,3 @@ *

DraftEditor.prototype._update = function _update(editorState) {
this._latestEditorState = editorState;
this.props.onChange(editorState);

@@ -419,0 +405,0 @@ };

@@ -27,2 +27,3 @@ /**

var ContentBlock = require('./ContentBlock');
var ContentState = require('./ContentState');
var DraftEditorLeaf = require('./DraftEditorLeaf.react');

@@ -167,2 +168,3 @@ var DraftOffsetKey = require('./DraftOffsetKey');

_extends({}, decoratorProps, {
contentState: _this2.props.contentState,
decoratedText: decoratedText,

@@ -169,0 +171,0 @@ dir: dir,

@@ -45,3 +45,3 @@ /**

var DraftEditorCompositionHandler = {
onBeforeInput: function onBeforeInput(e) {
onBeforeInput: function onBeforeInput(editor, e) {
textInputData = (textInputData || '') + e.data;

@@ -54,3 +54,3 @@ },

*/
onCompositionStart: function onCompositionStart() {
onCompositionStart: function onCompositionStart(editor) {
stillComposing = true;

@@ -73,5 +73,3 @@ },

*/
onCompositionEnd: function onCompositionEnd() {
var _this = this;
onCompositionEnd: function onCompositionEnd(editor) {
resolved = false;

@@ -81,3 +79,3 @@ stillComposing = false;

if (!resolved) {
DraftEditorCompositionHandler.resolveComposition.call(_this);
DraftEditorCompositionHandler.resolveComposition(editor);
}

@@ -92,3 +90,12 @@ }, RESOLVE_DELAY);

*/
onKeyDown: function onKeyDown(e) {
onKeyDown: function onKeyDown(editor, e) {
if (!stillComposing) {
// If a keydown event is received after compositionend but before the
// 20ms timer expires (ex: type option-E then backspace, or type A then
// backspace in 2-Set Korean), we should immediately resolve the
// composition and reinterpret the key press in edit mode.
DraftEditorCompositionHandler.resolveComposition(editor);
editor._onKeyDown(e);
return;
}
if (e.which === Keys.RIGHT || e.which === Keys.LEFT) {

@@ -105,3 +112,3 @@ e.preventDefault();

*/
onKeyPress: function onKeyPress(e) {
onKeyPress: function onKeyPress(editor, e) {
if (e.which === Keys.RETURN) {

@@ -127,3 +134,3 @@ e.preventDefault();

*/
resolveComposition: function resolveComposition() {
resolveComposition: function resolveComposition(editor) {
if (stillComposing) {

@@ -137,3 +144,3 @@ return;

var editorState = EditorState.set(this.props.editorState, {
var editorState = EditorState.set(editor._latestEditorState, {
inCompositionMode: false

@@ -148,7 +155,6 @@ });

if (mustReset) {
this.restoreEditorDOM();
editor.restoreEditorDOM();
}
this.exitCurrentMode();
this.removeRenderGuard();
editor.exitCurrentMode();

@@ -159,3 +165,3 @@ if (composedChars) {

var contentState = DraftModifier.replaceText(editorState.getCurrentContent(), editorState.getSelection(), composedChars, currentStyle, entityKey);
this.update(EditorState.push(editorState, contentState, 'insert-characters'));
editor.update(EditorState.push(editorState, contentState, 'insert-characters'));
return;

@@ -165,3 +171,3 @@ }

if (mustReset) {
this.update(EditorState.set(editorState, {
editor.update(EditorState.set(editorState, {
nativelyRenderedContent: null,

@@ -168,0 +174,0 @@ forceSelection: true

@@ -128,2 +128,3 @@ /**

var componentProps = {
contentState: content,
block: _block,

@@ -130,0 +131,0 @@ blockProps: customProps,

@@ -56,4 +56,4 @@ /**

*/
onDragEnd: function onDragEnd() {
this.exitCurrentMode();
onDragEnd: function onDragEnd(editor) {
editor.exitCurrentMode();
},

@@ -64,12 +64,10 @@

*/
onDrop: function onDrop(e) {
var _this = this;
onDrop: function onDrop(editor, e) {
var data = new DataTransfer(e.nativeEvent.dataTransfer);
var editorState = this.props.editorState;
var editorState = editor._latestEditorState;
var dropSelection = getSelectionForEvent(e.nativeEvent, editorState);
e.preventDefault();
this.exitCurrentMode();
editor.exitCurrentMode();

@@ -82,3 +80,3 @@ if (dropSelection == null) {

if (files.length > 0) {
if (this.props.handleDroppedFiles && isEventHandled(this.props.handleDroppedFiles(dropSelection, files))) {
if (editor.props.handleDroppedFiles && isEventHandled(editor.props.handleDroppedFiles(dropSelection, files))) {
return;

@@ -88,3 +86,3 @@ }

getTextContentFromFiles(files, function (fileText) {
fileText && _this.update(insertTextAtSelection(editorState, nullthrows(dropSelection), // flow wtf
fileText && editor.update(insertTextAtSelection(editorState, nullthrows(dropSelection), // flow wtf
fileText));

@@ -95,13 +93,13 @@ });

var dragType = this._internalDrag ? 'internal' : 'external';
if (this.props.handleDrop && isEventHandled(this.props.handleDrop(dropSelection, data, dragType))) {
var dragType = editor._internalDrag ? 'internal' : 'external';
if (editor.props.handleDrop && isEventHandled(editor.props.handleDrop(dropSelection, data, dragType))) {
return;
}
if (this._internalDrag) {
this.update(moveText(editorState, dropSelection));
if (editor._internalDrag) {
editor.update(moveText(editorState, dropSelection));
return;
}
this.update(insertTextAtSelection(editorState, dropSelection, data.getText()));
editor.update(insertTextAtSelection(editorState, dropSelection, data.getText()));
}

@@ -108,0 +106,0 @@

@@ -32,2 +32,9 @@ 'use strict';

/**
* Temporary utility for generating the warnings
*/
function logWarning(oldMethodCall, newMethodCall) {
console.warn('WARNING: ' + oldMethodCall + ' will be deprecated soon!\nPlease use "' + newMethodCall + '" instead.');
}
/**
* A "document entity" is an object containing metadata associated with a

@@ -47,2 +54,18 @@ * piece of text in a ContentBlock.

/**
* WARNING: This method will be deprecated soon!
* Please use 'contentState.getLastCreatedEntityKey' instead.
* ---
* Get the random key string from whatever entity was last created.
* We need this to support the new API, as part of transitioning to put Entity
* storage in contentState.
*/
getLastCreatedEntityKey: function getLastCreatedEntityKey() {
logWarning('DraftEntity.getLastCreatedEntityKey', 'contentState.getLastCreatedEntityKey');
return DraftEntity.__getLastCreatedEntityKey();
},
/**
* WARNING: This method will be deprecated soon!
* Please use 'contentState.createEntity' instead.
* ---
* Create a DraftEntityInstance and store it for later retrieval.

@@ -55,6 +78,10 @@ *

create: function create(type, mutability, data) {
return DraftEntity.add(new DraftEntityInstance({ type: type, mutability: mutability, data: data || {} }));
logWarning('DraftEntity.create', 'contentState.createEntity');
return DraftEntity.__create(type, mutability, data);
},
/**
* WARNING: This method will be deprecated soon!
* Please use 'contentState.addEntity' instead.
* ---
* Add an existing DraftEntityInstance to the DraftEntity map. This is

@@ -64,2 +91,70 @@ * useful when restoring instances from the server.

add: function add(instance) {
logWarning('DraftEntity.add', 'contentState.addEntity');
return DraftEntity.__add(instance);
},
/**
* WARNING: This method will be deprecated soon!
* Please use 'contentState.getEntity' instead.
* ---
* Retrieve the entity corresponding to the supplied key string.
*/
get: function get(key) {
logWarning('DraftEntity.get', 'contentState.getEntity');
return DraftEntity.__get(key);
},
/**
* WARNING: This method will be deprecated soon!
* Please use 'contentState.mergeEntityData' instead.
* ---
* Entity instances are immutable. If you need to update the data for an
* instance, this method will merge your data updates and return a new
* instance.
*/
mergeData: function mergeData(key, toMerge) {
logWarning('DraftEntity.mergeData', 'contentState.mergeEntityData');
return DraftEntity.__mergeData(key, toMerge);
},
/**
* WARNING: This method will be deprecated soon!
* Please use 'contentState.replaceEntityData' instead.
* ---
* Completely replace the data for a given instance.
*/
replaceData: function replaceData(key, newData) {
logWarning('DraftEntity.replaceData', 'contentState.replaceEntityData');
return DraftEntity.__replaceData(key, newData);
},
// ***********************************WARNING******************************
// --- the above public API will be deprecated in the next version of Draft!
// The methods below this line are private - don't call them directly.
/**
* Get the random key string from whatever entity was last created.
* We need this to support the new API, as part of transitioning to put Entity
* storage in contentState.
*/
__getLastCreatedEntityKey: function __getLastCreatedEntityKey() {
return '' + instanceKey;
},
/**
* Create a DraftEntityInstance and store it for later retrieval.
*
* A random key string will be generated and returned. This key may
* be used to track the entity's usage in a ContentBlock, and for
* retrieving data about the entity at render time.
*/
__create: function __create(type, mutability, data) {
return DraftEntity.__add(new DraftEntityInstance({ type: type, mutability: mutability, data: data || {} }));
},
/**
* Add an existing DraftEntityInstance to the DraftEntity map. This is
* useful when restoring instances from the server.
*/
__add: function __add(instance) {
var key = '' + ++instanceKey;

@@ -73,3 +168,3 @@ instances = instances.set(key, instance);

*/
get: function get(key) {
__get: function __get(key) {
var instance = instances.get(key);

@@ -85,4 +180,4 @@ !!!instance ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Unknown DraftEntity key.') : invariant(false) : void 0;

*/
mergeData: function mergeData(key, toMerge) {
var instance = DraftEntity.get(key);
__mergeData: function __mergeData(key, toMerge) {
var instance = DraftEntity.__get(key);
var newData = _extends({}, instance.getData(), toMerge);

@@ -97,4 +192,4 @@ var newInstance = instance.set('data', newData);

*/
replaceData: function replaceData(key, newData) {
var instance = DraftEntity.get(key);
__replaceData: function __replaceData(key, newData) {
var instance = DraftEntity.__get(key);
var newInstance = instance.set('data', newData);

@@ -101,0 +196,0 @@ instances = instances.set(key, newInstance);

@@ -89,3 +89,3 @@ /**

if (startEntity && startEntity === endEntity) {
var adjustedRemovalRange = getCharacterRemovalRange(block, rangeToRemove, removalDirection);
var adjustedRemovalRange = getCharacterRemovalRange(contentState.getEntityMap(), block, rangeToRemove, removalDirection);
return removeRangeFromContentState(contentState, adjustedRemovalRange);

@@ -92,0 +92,0 @@ }

@@ -24,3 +24,3 @@ /**

// punctuation.
var CHAMELEON_CHARS = '[\'‘’]';
var CHAMELEON_CHARS = '[\'\u2018\u2019]';

@@ -27,0 +27,0 @@ // Remove the underscore, which should count as part of the removable word. The

@@ -23,2 +23,3 @@ /**

var nullthrows = require('fbjs/lib/nullthrows');
var setImmediate = require('fbjs/lib/setImmediate');

@@ -60,3 +61,8 @@ var isEventHandled = require('./isEventHandled');

*/
function editOnBeforeInput(e) {
function editOnBeforeInput(editor, e) {
if (editor._pendingStateFromBeforeInput !== undefined) {
editor.update(editor._pendingStateFromBeforeInput);
editor._pendingStateFromBeforeInput = undefined;
}
var chars = e.data;

@@ -75,3 +81,3 @@

// start of the block.
if (this.props.handleBeforeInput && isEventHandled(this.props.handleBeforeInput(chars))) {
if (editor.props.handleBeforeInput && isEventHandled(editor.props.handleBeforeInput(chars))) {
e.preventDefault();

@@ -84,3 +90,3 @@ return;

// is not collapsed, we will re-render.
var editorState = this.props.editorState;
var editorState = editor._latestEditorState;
var selection = editorState.getSelection();

@@ -90,3 +96,3 @@

e.preventDefault();
this.update(replaceText(editorState, chars, editorState.getCurrentInlineStyle(), getEntityKeyForSelection(editorState.getCurrentContent(), editorState.getSelection())));
editor.update(replaceText(editorState, chars, editorState.getCurrentInlineStyle(), getEntityKeyForSelection(editorState.getCurrentContent(), editorState.getSelection())));
return;

@@ -100,3 +106,3 @@ }

e.preventDefault();
this.update(newEditorState);
editor.update(newEditorState);
return;

@@ -116,12 +122,21 @@ }

e.preventDefault();
editor.update(newEditorState);
} else {
// The native event is allowed to occur.
newEditorState = EditorState.set(newEditorState, {
nativelyRenderedContent: newEditorState.getCurrentContent()
});
// The native event is allowed to occur. To allow user onChange handlers to
// change the inserted text, we wait until the text is actually inserted
// before we actually update our state. That way when we rerender, the text
// we see in the DOM will already have been inserted properly.
editor._pendingStateFromBeforeInput = newEditorState;
setImmediate(function () {
if (editor._pendingStateFromBeforeInput !== undefined) {
editor.update(editor._pendingStateFromBeforeInput);
editor._pendingStateFromBeforeInput = undefined;
}
});
}
this.update(newEditorState);
}
module.exports = editOnBeforeInput;

@@ -22,3 +22,3 @@ /**

function editOnBlur(e) {
function editOnBlur(editor, e) {
// Webkit has a bug in which blurring a contenteditable by clicking on

@@ -34,3 +34,3 @@ // other active elements will trigger the `blur` event but will not remove

var editorState = this.props.editorState;
var editorState = editor._latestEditorState;
var currentSelection = editorState.getSelection();

@@ -42,6 +42,6 @@ if (!currentSelection.getHasFocus()) {

var selection = currentSelection.set('hasFocus', false);
this.props.onBlur && this.props.onBlur(e);
this.update(EditorState.acceptSelection(editorState, selection));
editor.props.onBlur && editor.props.onBlur(e);
editor.update(EditorState.acceptSelection(editorState, selection));
}
module.exports = editOnBlur;

@@ -21,8 +21,9 @@ /**

*/
function editOnCompositionStart() {
this.setRenderGuard();
this.setMode('composite');
this.update(EditorState.set(this.props.editorState, { inCompositionMode: true }));
function editOnCompositionStart(editor, e) {
editor.setMode('composite');
editor.update(EditorState.set(editor._latestEditorState, { inCompositionMode: true }));
// Allow composition handler to interpret the compositionstart event
editor._onCompositionStart(e);
}
module.exports = editOnCompositionStart;

@@ -22,4 +22,4 @@ /**

*/
function editOnCopy(e) {
var editorState = this.props.editorState;
function editOnCopy(editor, e) {
var editorState = editor._latestEditorState;
var selection = editorState.getSelection();

@@ -33,5 +33,5 @@

this.setClipboard(getFragmentFromSelection(this.props.editorState));
editor.setClipboard(getFragmentFromSelection(editor._latestEditorState));
}
module.exports = editOnCopy;

@@ -31,6 +31,4 @@ /**

*/
function editOnCut(e) {
var _this = this;
var editorState = this.props.editorState;
function editOnCut(editor, e) {
var editorState = editor._latestEditorState;
var selection = editorState.getSelection();

@@ -55,14 +53,12 @@

var fragment = getFragmentFromSelection(editorState);
this.setClipboard(fragment);
editor.setClipboard(fragment);
// Set `cut` mode to disable all event handling temporarily.
this.setRenderGuard();
this.setMode('cut');
editor.setMode('cut');
// Let native `cut` behavior occur, then recover control.
setTimeout(function () {
_this.restoreEditorDOM({ x: x, y: y });
_this.removeRenderGuard();
_this.exitCurrentMode();
_this.update(removeFragment(editorState));
editor.restoreEditorDOM({ x: x, y: y });
editor.exitCurrentMode();
editor.update(removeFragment(editorState));
}, 0);

@@ -69,0 +65,0 @@ }

@@ -18,6 +18,5 @@ /**

*/
function editOnDragOver(e) {
this._internalDrag = false;
this.setMode('drag');
function editOnDragOver(editor, e) {
editor._internalDrag = false;
editor.setMode('drag');
e.preventDefault();

@@ -24,0 +23,0 @@ }

@@ -18,8 +18,7 @@ /**

*/
function editOnDragStart() {
this._internalDrag = true;
this.setMode('drag');
function editOnDragStart(editor) {
editor._internalDrag = true;
editor.setMode('drag');
}
module.exports = editOnDragStart;

@@ -17,4 +17,4 @@ /**

function editOnFocus(e) {
var editorState = this.props.editorState;
function editOnFocus(editor, e) {
var editorState = editor._latestEditorState;
var currentSelection = editorState.getSelection();

@@ -26,3 +26,3 @@ if (currentSelection.getHasFocus()) {

var selection = currentSelection.set('hasFocus', true);
this.props.onFocus && this.props.onFocus(e);
editor.props.onFocus && editor.props.onFocus(e);

@@ -35,5 +35,5 @@ // When the tab containing this text editor is hidden and the user does a

// old cursor position. See https://crbug.com/540004.
this.update(EditorState.forceSelection(editorState, selection));
editor.update(EditorState.forceSelection(editorState, selection));
}
module.exports = editOnFocus;

@@ -18,3 +18,2 @@ /**

var EditorState = require('./EditorState');
var Entity = require('./DraftEntity');
var UserAgent = require('fbjs/lib/UserAgent');

@@ -41,3 +40,8 @@

*/
function editOnInput() {
function editOnInput(editor) {
if (editor._pendingStateFromBeforeInput !== undefined) {
editor.update(editor._pendingStateFromBeforeInput);
editor._pendingStateFromBeforeInput = undefined;
}
var domSelection = global.getSelection();

@@ -53,4 +57,3 @@

var domText = anchorNode.textContent;
var editorState = this.props.editorState;
var editorState = editor._latestEditorState;
var offsetKey = nullthrows(findAncestorOffsetKey(anchorNode));

@@ -97,3 +100,3 @@

var entityKey = block.getEntityAt(start);
var entity = entityKey && Entity.get(entityKey);
var entity = entityKey && content.getEntity(entityKey);
var entityType = entity && entity.getMutability();

@@ -143,5 +146,5 @@ var preserveEntity = entityType === 'MUTABLE';

this.update(EditorState.push(editorState, contentWithAdjustedDOMSelection, changeType));
editor.update(EditorState.push(editorState, contentWithAdjustedDOMSelection, changeType));
}
module.exports = editOnInput;

@@ -82,5 +82,5 @@ /**

*/
function editOnKeyDown(e) {
function editOnKeyDown(editor, e) {
var keyCode = e.which;
var editorState = this.props.editorState;
var editorState = editor._latestEditorState;

@@ -92,3 +92,3 @@ switch (keyCode) {

// no special handling is performed, fall through to command handling.
if (this.props.handleReturn && isEventHandled(this.props.handleReturn(e))) {
if (editor.props.handleReturn && isEventHandled(editor.props.handleReturn(e))) {
return;

@@ -99,12 +99,12 @@ }

e.preventDefault();
this.props.onEscape && this.props.onEscape(e);
editor.props.onEscape && editor.props.onEscape(e);
return;
case Keys.TAB:
this.props.onTab && this.props.onTab(e);
editor.props.onTab && editor.props.onTab(e);
return;
case Keys.UP:
this.props.onUpArrow && this.props.onUpArrow(e);
editor.props.onUpArrow && editor.props.onUpArrow(e);
return;
case Keys.DOWN:
this.props.onDownArrow && this.props.onDownArrow(e);
editor.props.onDownArrow && editor.props.onDownArrow(e);
return;

@@ -116,4 +116,4 @@ case Keys.SPACE:

// Insert a nbsp into the editor.
var contentState = DraftModifier.replaceText(editorState.getCurrentContent(), editorState.getSelection(), ' ');
this.update(EditorState.push(editorState, contentState, 'insert-characters'));
var contentState = DraftModifier.replaceText(editorState.getCurrentContent(), editorState.getSelection(), '\xA0');
editor.update(EditorState.push(editorState, contentState, 'insert-characters'));
return;

@@ -123,3 +123,3 @@ }

var command = this.props.keyBindingFn(e);
var command = editor.props.keyBindingFn(e);

@@ -134,3 +134,3 @@ // If no command is specified, allow keydown event to continue.

// in sync, handle it separately.
keyCommandUndo(e, editorState, this.update);
keyCommandUndo(e, editorState, editor.update);
return;

@@ -144,3 +144,3 @@ }

// Allow components higher up the tree to handle the command first.
if (this.props.handleKeyCommand && isEventHandled(this.props.handleKeyCommand(command))) {
if (editor.props.handleKeyCommand && isEventHandled(editor.props.handleKeyCommand(command))) {
return;

@@ -151,3 +151,3 @@ }

if (newState !== editorState) {
this.update(newState);
editor.update(newState);
}

@@ -154,0 +154,0 @@ }

@@ -24,12 +24,9 @@ /**

var getTextContentFromFiles = require('./getTextContentFromFiles');
var isEventHandled = require('./isEventHandled');
var splitTextIntoTextBlocks = require('./splitTextIntoTextBlocks');
var isEventHandled = require('./isEventHandled');
/**
* Paste content.
*/
function editOnPaste(e) {
var _this = this;
function editOnPaste(editor, e) {
e.preventDefault();

@@ -45,3 +42,3 @@ var data = new DataTransfer(e.clipboardData);

// through to insert text contents into the editor.
if (this.props.handlePastedFiles && isEventHandled(this.props.handlePastedFiles(files))) {
if (editor.props.handlePastedFiles && isEventHandled(editor.props.handlePastedFiles(files))) {
return;

@@ -56,4 +53,3 @@ }

var editorState = _this.props.editorState;
var editorState = editor._latestEditorState;
var blocks = splitTextIntoTextBlocks(fileText);

@@ -70,3 +66,3 @@ var character = CharacterMetadata.create({

_this.update(EditorState.push(editorState, withInsertedText, 'insert-fragment'));
editor.update(EditorState.push(editorState, withInsertedText, 'insert-fragment'));
});

@@ -82,3 +78,3 @@

if (this.props.handlePastedText && isEventHandled(this.props.handlePastedText(text, html))) {
if (editor.props.handlePastedText && isEventHandled(editor.props.handlePastedText(text, html))) {
return;

@@ -91,3 +87,3 @@ }

if (!this.props.stripPastedStyles) {
if (!editor.props.stripPastedStyles) {
// If the text from the paste event is rich content that matches what we

@@ -100,3 +96,3 @@ // already have on the internal clipboard, assume that we should just use

// paste will preserve the newlines correctly.
var internalClipboard = this.getClipboard();
var internalClipboard = editor.getClipboard();
if (data.isRichText() && internalClipboard) {

@@ -106,3 +102,3 @@ if (

// assume this is an internal paste.
html.indexOf(this.getEditorKey()) !== -1 ||
html.indexOf(editor.getEditorKey()) !== -1 ||
// The copy may have been made within a single block, in which case the

@@ -112,3 +108,3 @@ // editor key won't be part of the paste. In this case, just check

textBlocks.length === 1 && internalClipboard.size === 1 && internalClipboard.first().getText() === text) {
this.update(insertFragment(this.props.editorState, internalClipboard));
editor.update(insertFragment(editor._latestEditorState, internalClipboard));
return;

@@ -120,3 +116,3 @@ }

// the clipboard. See https://bugs.webkit.org/show_bug.cgi?id=19893.
this.update(insertFragment(this.props.editorState, internalClipboard));
editor.update(insertFragment(editor._latestEditorState, internalClipboard));
return;

@@ -127,7 +123,12 @@ }

if (html) {
var htmlFragment = DraftPasteProcessor.processHTML(html, this.props.blockRenderMap);
var htmlFragment = DraftPasteProcessor.processHTML(html, editor.props.blockRenderMap);
if (htmlFragment) {
var htmlMap = BlockMapBuilder.createFromArray(htmlFragment);
this.update(insertFragment(this.props.editorState, htmlMap));
return;
var contentBlocks = htmlFragment.contentBlocks;
var entityMap = htmlFragment.entityMap;
if (contentBlocks) {
var htmlMap = BlockMapBuilder.createFromArray(contentBlocks);
editor.update(insertFragment(editor._latestEditorState, htmlMap, entityMap));
return;
}
}

@@ -138,8 +139,7 @@ }

// empty the internal clipboard, since it's no longer valid.
this.setClipboard(null);
editor.setClipboard(null);
}
if (textBlocks) {
var editorState = this.props.editorState;
if (textBlocks.length) {
var editorState = editor._latestEditorState;
var character = CharacterMetadata.create({

@@ -153,9 +153,13 @@ style: editorState.getCurrentInlineStyle(),

var textMap = BlockMapBuilder.createFromArray(textFragment);
this.update(insertFragment(this.props.editorState, textMap));
editor.update(insertFragment(editor._latestEditorState, textMap));
}
}
function insertFragment(editorState, fragment) {
function insertFragment(editorState, fragment, entityMap) {
var newContent = DraftModifier.replaceWithFragment(editorState.getCurrentContent(), editorState.getSelection(), fragment);
return EditorState.push(editorState, newContent, 'insert-fragment');
// TODO: merge the entity map once we stop using DraftEntity
// like this:
// const mergedEntityMap = newContent.getEntityMap().merge(entityMap);
return EditorState.push(editorState, newContent.set('entityMap', entityMap), 'insert-fragment');
}

@@ -162,0 +166,0 @@

@@ -20,9 +20,9 @@ /**

function editOnSelect() {
if (this._blockSelectEvents) {
function editOnSelect(editor) {
if (editor._blockSelectEvents || editor._latestEditorState !== editor.props.editorState) {
return;
}
var editorState = this.props.editorState;
var documentSelection = getDraftEditorSelection(editorState, ReactDOM.findDOMNode(this.refs.editorContainer).firstChild);
var editorState = editor.props.editorState;
var documentSelection = getDraftEditorSelection(editorState, ReactDOM.findDOMNode(editor.refs.editorContainer).firstChild);
var updatedSelectionState = documentSelection.selectionState;

@@ -36,3 +36,3 @@

}
this.update(editorState);
editor.update(editorState);
}

@@ -39,0 +39,0 @@ }

@@ -93,3 +93,3 @@ /**

if (decorator && existingDecorator) {
newTreeMap = regenerateTreeForNewDecorator(newContent.getBlockMap(), treeMap, decorator, existingDecorator);
newTreeMap = regenerateTreeForNewDecorator(newContent, newContent.getBlockMap(), treeMap, decorator, existingDecorator);
} else {

@@ -109,3 +109,3 @@ newTreeMap = generateNewTreeMap(newContent, decorator);

if (newContent !== existingContent) {
state.set('treeMap', regenerateTreeForNewBlocks(editorState, newContent.getBlockMap(), decorator));
state.set('treeMap', regenerateTreeForNewBlocks(editorState, newContent.getBlockMap(), newContent.getEntityMap(), decorator));
}

@@ -462,3 +462,3 @@

return contentState.getBlockMap().map(function (block) {
return BlockTree.generate(block, decorator);
return BlockTree.generate(contentState, block, decorator);
}).toOrderedMap();

@@ -472,4 +472,5 @@ }

*/
function regenerateTreeForNewBlocks(editorState, newBlockMap, decorator) {
var prevBlockMap = editorState.getCurrentContent().getBlockMap();
function regenerateTreeForNewBlocks(editorState, newBlockMap, newEntityMap, decorator) {
var contentState = editorState.getCurrentContent().set('entityMap', newEntityMap);
var prevBlockMap = contentState.getBlockMap();
var prevTreeMap = editorState.getImmutable().get('treeMap');

@@ -479,3 +480,3 @@ return prevTreeMap.merge(newBlockMap.toSeq().filter(function (block, key) {

}).map(function (block) {
return BlockTree.generate(block, decorator);
return BlockTree.generate(contentState, block, decorator);
}));

@@ -492,7 +493,7 @@ }

*/
function regenerateTreeForNewDecorator(blockMap, previousTreeMap, decorator, existingDecorator) {
function regenerateTreeForNewDecorator(content, blockMap, previousTreeMap, decorator, existingDecorator) {
return previousTreeMap.merge(blockMap.toSeq().filter(function (block) {
return decorator.getDecorations(block) !== existingDecorator.getDecorations(block);
return decorator.getDecorations(block, content) !== existingDecorator.getDecorations(block, content);
}).map(function (block) {
return BlockTree.generate(block, decorator);
return BlockTree.generate(content, block, decorator);
}));

@@ -499,0 +500,0 @@ }

@@ -16,3 +16,2 @@ /**

var DraftEntity = require('./DraftEntity');
var DraftEntitySegments = require('./DraftEntitySegments');

@@ -32,3 +31,3 @@

*/
function getCharacterRemovalRange(block, selectionState, direction) {
function getCharacterRemovalRange(entityMap, block, selectionState, direction) {
var start = selectionState.getStartOffset();

@@ -41,3 +40,3 @@ var end = selectionState.getEndOffset();

var entity = DraftEntity.get(entityKey);
var entity = entityMap.__get(entityKey);
var mutability = entity.getMutability();

@@ -44,0 +43,0 @@

@@ -16,4 +16,2 @@ /**

var DraftEntity = require('./DraftEntity');
/**

@@ -32,3 +30,3 @@ * Return the entity key that should be used when inserting text for the

entityKey = contentState.getBlockForKey(key).getEntityAt(offset - 1);
return filterKey(entityKey);
return filterKey(contentState.getEntityMap(), entityKey);
}

@@ -44,3 +42,3 @@ return null;

return filterKey(entityKey);
return filterKey(contentState.getEntityMap(), entityKey);
}

@@ -52,5 +50,5 @@

*/
function filterKey(entityKey) {
function filterKey(entityMap, entityKey) {
if (entityKey) {
var entity = DraftEntity.get(entityKey);
var entity = entityMap.__get(entityKey);
return entity.getMutability() === 'MUTABLE' ? entityKey : null;

@@ -57,0 +55,0 @@ }

@@ -59,2 +59,3 @@ /**

blockMap: blockMap,
entityMap: Immutable.OrderedMap(),
selectionBefore: selectionState,

@@ -61,0 +62,0 @@ selectionAfter: selectionState

@@ -16,3 +16,2 @@ /**

var CharacterMetadata = require('./CharacterMetadata');
var DraftEntity = require('./DraftEntity');

@@ -24,2 +23,3 @@ var findRangesImmutable = require('./findRangesImmutable');

var blockMap = contentState.getBlockMap();
var entityMap = contentState.getEntityMap();

@@ -31,3 +31,3 @@ var updatedBlocks = {};

var startBlock = blockMap.get(startKey);
var updatedStart = removeForBlock(startBlock, startOffset);
var updatedStart = removeForBlock(entityMap, startBlock, startOffset);

@@ -45,3 +45,3 @@ if (updatedStart !== startBlock) {

var updatedEnd = removeForBlock(endBlock, endOffset);
var updatedEnd = removeForBlock(entityMap, endBlock, endOffset);

@@ -77,3 +77,3 @@ if (updatedEnd !== endBlock) {

function removeForBlock(block, offset) {
function removeForBlock(entityMap, block, offset) {
var chars = block.getCharacterList();

@@ -86,3 +86,3 @@ var charBefore = offset > 0 ? chars.get(offset - 1) : undefined;

if (entityAfterCursor && entityAfterCursor === entityBeforeCursor) {
var entity = DraftEntity.get(entityAfterCursor);
var entity = entityMap.__get(entityAfterCursor);
if (entity.getMutability() !== 'MUTABLE') {

@@ -89,0 +89,0 @@ var _getRemovalRange = getRemovalRange(chars, entityAfterCursor, offset);

@@ -16,3 +16,2 @@ /**

var DraftEntity = require('./DraftEntity');
var DraftModifier = require('./DraftModifier');

@@ -28,5 +27,7 @@ var EditorState = require('./EditorState');

var selection = editorState.getSelection();
return editorState.getCurrentContent().getBlockForKey(selection.getAnchorKey()).getCharacterList().slice(selection.getStartOffset(), selection.getEndOffset()).some(function (v) {
var contentState = editorState.getCurrentContent();
var entityMap = contentState.getEntityMap();
return contentState.getBlockForKey(selection.getAnchorKey()).getCharacterList().slice(selection.getStartOffset(), selection.getEndOffset()).some(function (v) {
var entity = v.getEntity();
return !!entity && DraftEntity.get(entity).getType() === 'LINK';
return !!entity && entityMap.__get(entity).getType() === 'LINK';
});

@@ -63,2 +64,3 @@ },

default:
// they may have custom editor commands; ignore those
return null;

@@ -92,8 +94,4 @@ }

if (blockBefore && blockBefore.getType() === 'atomic') {
var atomicBlockTarget = selection.merge({
anchorKey: blockBefore.getKey(),
anchorOffset: 0
});
var asCurrentStyle = DraftModifier.setBlockType(content, atomicBlockTarget, content.getBlockForKey(startKey).getType());
var withoutAtomicBlock = DraftModifier.removeRange(asCurrentStyle, atomicBlockTarget, 'backward');
var blockMap = content.getBlockMap()['delete'](blockBefore.getKey());
var withoutAtomicBlock = content.merge({ blockMap: blockMap, selectionAfter: selection });
if (withoutAtomicBlock !== content) {

@@ -100,0 +98,0 @@ return EditorState.push(editorState, withoutAtomicBlock, 'remove-range');

{
"name": "draft-js",
"description": "A React framework for building text editors.",
"version": "0.9.1",
"version": "0.10.0",
"keywords": [

@@ -33,3 +33,3 @@ "draftjs",

"dependencies": {
"fbjs": "^0.8.3",
"fbjs": "^0.8.7",
"immutable": "~3.7.4",

@@ -45,3 +45,3 @@ "object-assign": "^4.1.0"

"babel-eslint": "^6.1.2",
"babel-preset-fbjs": "^2.0.0",
"babel-preset-fbjs": "^2.1.0",
"del": "^2.2.0",

@@ -51,5 +51,5 @@ "envify": "^3.4.0",

"eslint": "^3.0.1",
"eslint-config-fbjs": "^1.0.0",
"eslint-config-fbjs": "^1.1.0",
"eslint-plugin-babel": "^3.3.0",
"eslint-plugin-flow-vars": "^0.4.0",
"eslint-plugin-flowtype": "^2.17.1",
"eslint-plugin-react": "^5.2.2",

@@ -85,3 +85,5 @@ "fbjs-scripts": "^0.7.0",

"scriptPreprocessor": "scripts/jest/preprocessor.js",
"setupFiles": ["node_modules/fbjs-scripts/jest/environment.js"],
"setupFiles": [
"node_modules/fbjs-scripts/jest/environment.js"
],
"modulePathIgnorePatterns": [

@@ -88,0 +90,0 @@ "<rootDir>/lib/",

@@ -20,4 +20,49 @@ # [Draft.js](https://facebook.github.io/draft-js/) [![Build Status](https://img.shields.io/travis/facebook/draft-js/master.svg?style=flat)](https://travis-ci.org/facebook/draft-js) [![npm version](https://img.shields.io/npm/v/draft-js.svg?style=flat)](https://www.npmjs.com/package/draft-js)

## Examples
## API Notice
Before getting started, please be aware that we are changing the API of Entity storage in Draft. Currently, the master branch supports both the old and new API. We hope to release this soon, as `v0.10.0`. Following that up will be `v0.11.0` which will remove the old API. This update will also include documentation on how to upgrade. If you are interested in helping out, or tracking the progress, please follow [issue 839](https://github.com/facebook/draft-js/issues/839).
## Getting Started
Currently Draft.js is distributed via npm. It depends on React and React DOM which must also be installed.
```
npm install --save draft-js react react-dom
```
### Using Draft.js
```
import React from 'react';
import ReactDOM from 'react-dom';
import {Editor, EditorState} from 'draft-js';
class MyEditor extends React.Component {
constructor(props) {
super(props);
this.state = {editorState: EditorState.createEmpty()};
this.onChange = (editorState) => this.setState({editorState});
}
render() {
return (
<Editor editorState={this.state.editorState} onChange={this.onChange} />
);
}
}
ReactDOM.render(
<MyEditor />,
document.getElementById('container')
);
```
Because Draft.js supports unicode, you must have the following meta tag in the `<head>` `</head>` block of your HTML file:
```
<meta charset="utf-8" />
```
Further examples of how Draft.js can be used are provided below.
### Examples
Visit https://facebook.github.io/draft-js/ to try out a simple rich editor example.

@@ -43,2 +88,6 @@

## Resources and Ecosystem
Check out this curated list of articles and open-sourced projects/utilities: [Awesome Draft-JS](https://github.com/nikgraf/awesome-draft-js).
## Discussion and Support

@@ -45,0 +94,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc