Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

convertFromDraftStateToRaw.js.flow 4.0 KiB

il y a 3 ans
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /**
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. *
  7. * @format
  8. * @flow
  9. * @emails oncall+draft_js
  10. */
  11. 'use strict';
  12. import type { BlockNodeRecord } from "./BlockNodeRecord";
  13. import type ContentState from "./ContentState";
  14. import type { RawDraftContentBlock } from "./RawDraftContentBlock";
  15. import type { RawDraftContentState } from "./RawDraftContentState";
  16. const ContentBlock = require("./ContentBlock");
  17. const ContentBlockNode = require("./ContentBlockNode");
  18. const DraftStringKey = require("./DraftStringKey");
  19. const encodeEntityRanges = require("./encodeEntityRanges");
  20. const encodeInlineStyleRanges = require("./encodeInlineStyleRanges");
  21. const invariant = require("fbjs/lib/invariant");
  22. const createRawBlock = (block: BlockNodeRecord, entityStorageMap: *) => {
  23. return {
  24. key: block.getKey(),
  25. text: block.getText(),
  26. type: block.getType(),
  27. depth: block.getDepth(),
  28. inlineStyleRanges: encodeInlineStyleRanges(block),
  29. entityRanges: encodeEntityRanges(block, entityStorageMap),
  30. data: block.getData().toObject()
  31. };
  32. };
  33. const insertRawBlock = (block: BlockNodeRecord, entityMap: *, rawBlocks: Array<RawDraftContentBlock>, blockCacheRef: *) => {
  34. if (block instanceof ContentBlock) {
  35. rawBlocks.push(createRawBlock(block, entityMap));
  36. return;
  37. }
  38. invariant(block instanceof ContentBlockNode, 'block is not a BlockNode');
  39. const parentKey = block.getParentKey();
  40. const rawBlock = blockCacheRef[block.getKey()] = { ...createRawBlock(block, entityMap),
  41. children: []
  42. };
  43. if (parentKey) {
  44. blockCacheRef[parentKey].children.push(rawBlock);
  45. return;
  46. }
  47. rawBlocks.push(rawBlock);
  48. };
  49. const encodeRawBlocks = (contentState: ContentState, rawState: RawDraftContentState): RawDraftContentState => {
  50. const {
  51. entityMap
  52. } = rawState;
  53. const rawBlocks = [];
  54. const blockCacheRef = {};
  55. const entityCacheRef = {};
  56. let entityStorageKey = 0;
  57. contentState.getBlockMap().forEach(block => {
  58. block.findEntityRanges(character => character.getEntity() !== null, start => {
  59. const entityKey = block.getEntityAt(start); // Stringify to maintain order of otherwise numeric keys.
  60. const stringifiedEntityKey = DraftStringKey.stringify(entityKey); // This makes this function resilient to two entities
  61. // erroneously having the same key
  62. if (entityCacheRef[stringifiedEntityKey]) {
  63. return;
  64. }
  65. entityCacheRef[stringifiedEntityKey] = entityKey; // we need the `any` casting here since this is a temporary state
  66. // where we will later on flip the entity map and populate it with
  67. // real entity, at this stage we just need to map back the entity
  68. // key used by the BlockNode
  69. entityMap[stringifiedEntityKey] = (`${entityStorageKey}`: any);
  70. entityStorageKey++;
  71. });
  72. insertRawBlock(block, entityMap, rawBlocks, blockCacheRef);
  73. });
  74. return {
  75. blocks: rawBlocks,
  76. entityMap
  77. };
  78. }; // Flip storage map so that our storage keys map to global
  79. // DraftEntity keys.
  80. const encodeRawEntityMap = (contentState: ContentState, rawState: RawDraftContentState): RawDraftContentState => {
  81. const {
  82. blocks,
  83. entityMap
  84. } = rawState;
  85. const rawEntityMap = {};
  86. Object.keys(entityMap).forEach((key, index) => {
  87. const entity = contentState.getEntity(DraftStringKey.unstringify(key));
  88. rawEntityMap[index] = {
  89. type: entity.getType(),
  90. mutability: entity.getMutability(),
  91. data: entity.getData()
  92. };
  93. });
  94. return {
  95. blocks,
  96. entityMap: rawEntityMap
  97. };
  98. };
  99. const convertFromDraftStateToRaw = (contentState: ContentState): RawDraftContentState => {
  100. let rawDraftContentState = {
  101. entityMap: {},
  102. blocks: []
  103. }; // add blocks
  104. rawDraftContentState = encodeRawBlocks(contentState, rawDraftContentState); // add entities
  105. rawDraftContentState = encodeRawEntityMap(contentState, rawDraftContentState);
  106. return rawDraftContentState;
  107. };
  108. module.exports = convertFromDraftStateToRaw;