|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- /**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @format
- * @flow
- * @emails oncall+draft_js
- */
- 'use strict';
-
- import type { BlockNodeRecord } from "./BlockNodeRecord";
- import type ContentState from "./ContentState";
- import type { RawDraftContentBlock } from "./RawDraftContentBlock";
- import type { RawDraftContentState } from "./RawDraftContentState";
-
- const ContentBlock = require("./ContentBlock");
-
- const ContentBlockNode = require("./ContentBlockNode");
-
- const DraftStringKey = require("./DraftStringKey");
-
- const encodeEntityRanges = require("./encodeEntityRanges");
-
- const encodeInlineStyleRanges = require("./encodeInlineStyleRanges");
-
- const invariant = require("fbjs/lib/invariant");
-
- const createRawBlock = (block: BlockNodeRecord, entityStorageMap: *) => {
- return {
- key: block.getKey(),
- text: block.getText(),
- type: block.getType(),
- depth: block.getDepth(),
- inlineStyleRanges: encodeInlineStyleRanges(block),
- entityRanges: encodeEntityRanges(block, entityStorageMap),
- data: block.getData().toObject()
- };
- };
-
- const insertRawBlock = (block: BlockNodeRecord, entityMap: *, rawBlocks: Array<RawDraftContentBlock>, blockCacheRef: *) => {
- if (block instanceof ContentBlock) {
- rawBlocks.push(createRawBlock(block, entityMap));
- return;
- }
-
- invariant(block instanceof ContentBlockNode, 'block is not a BlockNode');
- const parentKey = block.getParentKey();
- const rawBlock = blockCacheRef[block.getKey()] = { ...createRawBlock(block, entityMap),
- children: []
- };
-
- if (parentKey) {
- blockCacheRef[parentKey].children.push(rawBlock);
- return;
- }
-
- rawBlocks.push(rawBlock);
- };
-
- const encodeRawBlocks = (contentState: ContentState, rawState: RawDraftContentState): RawDraftContentState => {
- const {
- entityMap
- } = rawState;
- const rawBlocks = [];
- const blockCacheRef = {};
- const entityCacheRef = {};
- let entityStorageKey = 0;
- contentState.getBlockMap().forEach(block => {
- block.findEntityRanges(character => character.getEntity() !== null, start => {
- const entityKey = block.getEntityAt(start); // Stringify to maintain order of otherwise numeric keys.
-
- const stringifiedEntityKey = DraftStringKey.stringify(entityKey); // This makes this function resilient to two entities
- // erroneously having the same key
-
- if (entityCacheRef[stringifiedEntityKey]) {
- return;
- }
-
- entityCacheRef[stringifiedEntityKey] = entityKey; // we need the `any` casting here since this is a temporary state
- // where we will later on flip the entity map and populate it with
- // real entity, at this stage we just need to map back the entity
- // key used by the BlockNode
-
- entityMap[stringifiedEntityKey] = (`${entityStorageKey}`: any);
- entityStorageKey++;
- });
- insertRawBlock(block, entityMap, rawBlocks, blockCacheRef);
- });
- return {
- blocks: rawBlocks,
- entityMap
- };
- }; // Flip storage map so that our storage keys map to global
- // DraftEntity keys.
-
-
- const encodeRawEntityMap = (contentState: ContentState, rawState: RawDraftContentState): RawDraftContentState => {
- const {
- blocks,
- entityMap
- } = rawState;
- const rawEntityMap = {};
- Object.keys(entityMap).forEach((key, index) => {
- const entity = contentState.getEntity(DraftStringKey.unstringify(key));
- rawEntityMap[index] = {
- type: entity.getType(),
- mutability: entity.getMutability(),
- data: entity.getData()
- };
- });
- return {
- blocks,
- entityMap: rawEntityMap
- };
- };
-
- const convertFromDraftStateToRaw = (contentState: ContentState): RawDraftContentState => {
- let rawDraftContentState = {
- entityMap: {},
- blocks: []
- }; // add blocks
-
- rawDraftContentState = encodeRawBlocks(contentState, rawDraftContentState); // add entities
-
- rawDraftContentState = encodeRawEntityMap(contentState, rawDraftContentState);
- return rawDraftContentState;
- };
-
- module.exports = convertFromDraftStateToRaw;
|