Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

randomizeBlockMapKeys.js.flow 3.5 KiB

před 3 roky
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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 { BlockMap } from "./BlockMap";
  13. const ContentBlockNode = require("./ContentBlockNode");
  14. const generateRandomKey = require("./generateRandomKey");
  15. const Immutable = require("immutable");
  16. const {
  17. OrderedMap
  18. } = Immutable;
  19. const randomizeContentBlockNodeKeys = (blockMap: BlockMap): BlockMap => {
  20. const newKeysRef = {}; // we keep track of root blocks in order to update subsequent sibling links
  21. let lastRootBlock: ContentBlockNode;
  22. return OrderedMap(blockMap.withMutations(blockMapState => {
  23. blockMapState.forEach((block, index) => {
  24. const oldKey = block.getKey();
  25. const nextKey = block.getNextSiblingKey();
  26. const prevKey = block.getPrevSiblingKey();
  27. const childrenKeys = block.getChildKeys();
  28. const parentKey = block.getParentKey(); // new key that we will use to build linking
  29. const key = generateRandomKey(); // we will add it here to re-use it later
  30. newKeysRef[oldKey] = key;
  31. if (nextKey) {
  32. const nextBlock = blockMapState.get(nextKey);
  33. if (nextBlock) {
  34. blockMapState.setIn([nextKey, 'prevSibling'], key);
  35. } else {
  36. // this can happen when generating random keys for fragments
  37. blockMapState.setIn([oldKey, 'nextSibling'], null);
  38. }
  39. }
  40. if (prevKey) {
  41. const prevBlock = blockMapState.get(prevKey);
  42. if (prevBlock) {
  43. blockMapState.setIn([prevKey, 'nextSibling'], key);
  44. } else {
  45. // this can happen when generating random keys for fragments
  46. blockMapState.setIn([oldKey, 'prevSibling'], null);
  47. }
  48. }
  49. if (parentKey && blockMapState.get(parentKey)) {
  50. const parentBlock = blockMapState.get(parentKey);
  51. const parentChildrenList = parentBlock.getChildKeys();
  52. blockMapState.setIn([parentKey, 'children'], parentChildrenList.set(parentChildrenList.indexOf(block.getKey()), key));
  53. } else {
  54. // blocks will then be treated as root block nodes
  55. blockMapState.setIn([oldKey, 'parent'], null);
  56. if (lastRootBlock) {
  57. blockMapState.setIn([lastRootBlock.getKey(), 'nextSibling'], key);
  58. blockMapState.setIn([oldKey, 'prevSibling'], newKeysRef[lastRootBlock.getKey()]);
  59. }
  60. lastRootBlock = blockMapState.get(oldKey);
  61. }
  62. childrenKeys.forEach(childKey => {
  63. const childBlock = blockMapState.get(childKey);
  64. if (childBlock) {
  65. blockMapState.setIn([childKey, 'parent'], key);
  66. } else {
  67. blockMapState.setIn([oldKey, 'children'], block.getChildKeys().filter(child => child !== childKey));
  68. }
  69. });
  70. });
  71. }).toArray().map(block => [newKeysRef[block.getKey()], block.set('key', newKeysRef[block.getKey()])]));
  72. };
  73. const randomizeContentBlockKeys = (blockMap: BlockMap): BlockMap => {
  74. return OrderedMap(blockMap.toArray().map(block => {
  75. const key = generateRandomKey();
  76. return [key, block.set('key', key)];
  77. }));
  78. };
  79. const randomizeBlockMapKeys = (blockMap: BlockMap): BlockMap => {
  80. const isTreeBasedBlockMap = blockMap.first() instanceof ContentBlockNode;
  81. if (!isTreeBasedBlockMap) {
  82. return randomizeContentBlockKeys(blockMap);
  83. }
  84. return randomizeContentBlockNodeKeys(blockMap);
  85. };
  86. module.exports = randomizeBlockMapKeys;