Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

3 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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. *
  9. * @emails oncall+draft_js
  10. */
  11. 'use strict';
  12. function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
  13. function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
  14. var ContentBlock = require("./ContentBlock");
  15. var ContentBlockNode = require("./ContentBlockNode");
  16. var ContentState = require("./ContentState");
  17. var DraftEntity = require("./DraftEntity");
  18. var DraftTreeAdapter = require("./DraftTreeAdapter");
  19. var DraftTreeInvariants = require("./DraftTreeInvariants");
  20. var SelectionState = require("./SelectionState");
  21. var createCharacterList = require("./createCharacterList");
  22. var decodeEntityRanges = require("./decodeEntityRanges");
  23. var decodeInlineStyleRanges = require("./decodeInlineStyleRanges");
  24. var generateRandomKey = require("./generateRandomKey");
  25. var gkx = require("./gkx");
  26. var Immutable = require("immutable");
  27. var invariant = require("fbjs/lib/invariant");
  28. var experimentalTreeDataSupport = gkx('draft_tree_data_support');
  29. var List = Immutable.List,
  30. Map = Immutable.Map,
  31. OrderedMap = Immutable.OrderedMap;
  32. var decodeBlockNodeConfig = function decodeBlockNodeConfig(block, entityMap) {
  33. var key = block.key,
  34. type = block.type,
  35. data = block.data,
  36. text = block.text,
  37. depth = block.depth;
  38. var blockNodeConfig = {
  39. text: text,
  40. depth: depth || 0,
  41. type: type || 'unstyled',
  42. key: key || generateRandomKey(),
  43. data: Map(data),
  44. characterList: decodeCharacterList(block, entityMap)
  45. };
  46. return blockNodeConfig;
  47. };
  48. var decodeCharacterList = function decodeCharacterList(block, entityMap) {
  49. var text = block.text,
  50. rawEntityRanges = block.entityRanges,
  51. rawInlineStyleRanges = block.inlineStyleRanges;
  52. var entityRanges = rawEntityRanges || [];
  53. var inlineStyleRanges = rawInlineStyleRanges || []; // Translate entity range keys to the DraftEntity map.
  54. return createCharacterList(decodeInlineStyleRanges(text, inlineStyleRanges), decodeEntityRanges(text, entityRanges.filter(function (range) {
  55. return entityMap.hasOwnProperty(range.key);
  56. }).map(function (range) {
  57. return _objectSpread({}, range, {
  58. key: entityMap[range.key]
  59. });
  60. })));
  61. };
  62. var addKeyIfMissing = function addKeyIfMissing(block) {
  63. return _objectSpread({}, block, {
  64. key: block.key || generateRandomKey()
  65. });
  66. };
  67. /**
  68. * Node stack is responsible to ensure we traverse the tree only once
  69. * in depth order, while also providing parent refs to inner nodes to
  70. * construct their links.
  71. */
  72. var updateNodeStack = function updateNodeStack(stack, nodes, parentRef) {
  73. var nodesWithParentRef = nodes.map(function (block) {
  74. return _objectSpread({}, block, {
  75. parentRef: parentRef
  76. });
  77. }); // since we pop nodes from the stack we need to insert them in reverse
  78. return stack.concat(nodesWithParentRef.reverse());
  79. };
  80. /**
  81. * This will build a tree draft content state by creating the node
  82. * reference links into a single tree walk. Each node has a link
  83. * reference to "parent", "children", "nextSibling" and "prevSibling"
  84. * blockMap will be created using depth ordering.
  85. */
  86. var decodeContentBlockNodes = function decodeContentBlockNodes(blocks, entityMap) {
  87. return blocks // ensure children have valid keys to enable sibling links
  88. .map(addKeyIfMissing).reduce(function (blockMap, block, index) {
  89. !Array.isArray(block.children) ? process.env.NODE_ENV !== "production" ? invariant(false, 'invalid RawDraftContentBlock can not be converted to ContentBlockNode') : invariant(false) : void 0; // ensure children have valid keys to enable sibling links
  90. var children = block.children.map(addKeyIfMissing); // root level nodes
  91. var contentBlockNode = new ContentBlockNode(_objectSpread({}, decodeBlockNodeConfig(block, entityMap), {
  92. prevSibling: index === 0 ? null : blocks[index - 1].key,
  93. nextSibling: index === blocks.length - 1 ? null : blocks[index + 1].key,
  94. children: List(children.map(function (child) {
  95. return child.key;
  96. }))
  97. })); // push root node to blockMap
  98. blockMap = blockMap.set(contentBlockNode.getKey(), contentBlockNode); // this stack is used to ensure we visit all nodes respecting depth ordering
  99. var stack = updateNodeStack([], children, contentBlockNode); // start computing children nodes
  100. while (stack.length > 0) {
  101. // we pop from the stack and start processing this node
  102. var node = stack.pop(); // parentRef already points to a converted ContentBlockNode
  103. var parentRef = node.parentRef;
  104. var siblings = parentRef.getChildKeys();
  105. var _index = siblings.indexOf(node.key);
  106. var isValidBlock = Array.isArray(node.children);
  107. if (!isValidBlock) {
  108. !isValidBlock ? process.env.NODE_ENV !== "production" ? invariant(false, 'invalid RawDraftContentBlock can not be converted to ContentBlockNode') : invariant(false) : void 0;
  109. break;
  110. } // ensure children have valid keys to enable sibling links
  111. var _children = node.children.map(addKeyIfMissing);
  112. var _contentBlockNode = new ContentBlockNode(_objectSpread({}, decodeBlockNodeConfig(node, entityMap), {
  113. parent: parentRef.getKey(),
  114. children: List(_children.map(function (child) {
  115. return child.key;
  116. })),
  117. prevSibling: _index === 0 ? null : siblings.get(_index - 1),
  118. nextSibling: _index === siblings.size - 1 ? null : siblings.get(_index + 1)
  119. })); // push node to blockMap
  120. blockMap = blockMap.set(_contentBlockNode.getKey(), _contentBlockNode); // this stack is used to ensure we visit all nodes respecting depth ordering
  121. stack = updateNodeStack(stack, _children, _contentBlockNode);
  122. }
  123. return blockMap;
  124. }, OrderedMap());
  125. };
  126. var decodeContentBlocks = function decodeContentBlocks(blocks, entityMap) {
  127. return OrderedMap(blocks.map(function (block) {
  128. var contentBlock = new ContentBlock(decodeBlockNodeConfig(block, entityMap));
  129. return [contentBlock.getKey(), contentBlock];
  130. }));
  131. };
  132. var decodeRawBlocks = function decodeRawBlocks(rawState, entityMap) {
  133. var isTreeRawBlock = rawState.blocks.find(function (block) {
  134. return Array.isArray(block.children) && block.children.length > 0;
  135. });
  136. var rawBlocks = experimentalTreeDataSupport && !isTreeRawBlock ? DraftTreeAdapter.fromRawStateToRawTreeState(rawState).blocks : rawState.blocks;
  137. if (!experimentalTreeDataSupport) {
  138. return decodeContentBlocks(isTreeRawBlock ? DraftTreeAdapter.fromRawTreeStateToRawState(rawState).blocks : rawBlocks, entityMap);
  139. }
  140. var blockMap = decodeContentBlockNodes(rawBlocks, entityMap); // in dev mode, check that the tree invariants are met
  141. if (process.env.NODE_ENV !== "production") {
  142. !DraftTreeInvariants.isValidTree(blockMap) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Should be a valid tree') : invariant(false) : void 0;
  143. }
  144. return blockMap;
  145. };
  146. var decodeRawEntityMap = function decodeRawEntityMap(rawState) {
  147. var rawEntityMap = rawState.entityMap;
  148. var entityMap = {}; // TODO: Update this once we completely remove DraftEntity
  149. Object.keys(rawEntityMap).forEach(function (rawEntityKey) {
  150. var _rawEntityMap$rawEnti = rawEntityMap[rawEntityKey],
  151. type = _rawEntityMap$rawEnti.type,
  152. mutability = _rawEntityMap$rawEnti.mutability,
  153. data = _rawEntityMap$rawEnti.data; // get the key reference to created entity
  154. entityMap[rawEntityKey] = DraftEntity.__create(type, mutability, data || {});
  155. });
  156. return entityMap;
  157. };
  158. var convertFromRawToDraftState = function convertFromRawToDraftState(rawState) {
  159. !Array.isArray(rawState.blocks) ? process.env.NODE_ENV !== "production" ? invariant(false, 'invalid RawDraftContentState') : invariant(false) : void 0; // decode entities
  160. var entityMap = decodeRawEntityMap(rawState); // decode blockMap
  161. var blockMap = decodeRawBlocks(rawState, entityMap); // create initial selection
  162. var selectionState = blockMap.isEmpty() ? new SelectionState() : SelectionState.createEmpty(blockMap.first().getKey());
  163. return new ContentState({
  164. blockMap: blockMap,
  165. entityMap: entityMap,
  166. selectionBefore: selectionState,
  167. selectionAfter: selectionState
  168. });
  169. };
  170. module.exports = convertFromRawToDraftState;