/** * 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 * * @emails oncall+draft_js */ 'use strict'; var ContentBlockNode = require("./ContentBlockNode"); var generateRandomKey = require("./generateRandomKey"); var Immutable = require("immutable"); var OrderedMap = Immutable.OrderedMap; var randomizeContentBlockNodeKeys = function randomizeContentBlockNodeKeys(blockMap) { var newKeysRef = {}; // we keep track of root blocks in order to update subsequent sibling links var lastRootBlock; return OrderedMap(blockMap.withMutations(function (blockMapState) { blockMapState.forEach(function (block, index) { var oldKey = block.getKey(); var nextKey = block.getNextSiblingKey(); var prevKey = block.getPrevSiblingKey(); var childrenKeys = block.getChildKeys(); var parentKey = block.getParentKey(); // new key that we will use to build linking var key = generateRandomKey(); // we will add it here to re-use it later newKeysRef[oldKey] = key; if (nextKey) { var nextBlock = blockMapState.get(nextKey); if (nextBlock) { blockMapState.setIn([nextKey, 'prevSibling'], key); } else { // this can happen when generating random keys for fragments blockMapState.setIn([oldKey, 'nextSibling'], null); } } if (prevKey) { var prevBlock = blockMapState.get(prevKey); if (prevBlock) { blockMapState.setIn([prevKey, 'nextSibling'], key); } else { // this can happen when generating random keys for fragments blockMapState.setIn([oldKey, 'prevSibling'], null); } } if (parentKey && blockMapState.get(parentKey)) { var parentBlock = blockMapState.get(parentKey); var parentChildrenList = parentBlock.getChildKeys(); blockMapState.setIn([parentKey, 'children'], parentChildrenList.set(parentChildrenList.indexOf(block.getKey()), key)); } else { // blocks will then be treated as root block nodes blockMapState.setIn([oldKey, 'parent'], null); if (lastRootBlock) { blockMapState.setIn([lastRootBlock.getKey(), 'nextSibling'], key); blockMapState.setIn([oldKey, 'prevSibling'], newKeysRef[lastRootBlock.getKey()]); } lastRootBlock = blockMapState.get(oldKey); } childrenKeys.forEach(function (childKey) { var childBlock = blockMapState.get(childKey); if (childBlock) { blockMapState.setIn([childKey, 'parent'], key); } else { blockMapState.setIn([oldKey, 'children'], block.getChildKeys().filter(function (child) { return child !== childKey; })); } }); }); }).toArray().map(function (block) { return [newKeysRef[block.getKey()], block.set('key', newKeysRef[block.getKey()])]; })); }; var randomizeContentBlockKeys = function randomizeContentBlockKeys(blockMap) { return OrderedMap(blockMap.toArray().map(function (block) { var key = generateRandomKey(); return [key, block.set('key', key)]; })); }; var randomizeBlockMapKeys = function randomizeBlockMapKeys(blockMap) { var isTreeBasedBlockMap = blockMap.first() instanceof ContentBlockNode; if (!isTreeBasedBlockMap) { return randomizeContentBlockKeys(blockMap); } return randomizeContentBlockNodeKeys(blockMap); }; module.exports = randomizeBlockMapKeys;