113 lines
3.6 KiB
JavaScript
113 lines
3.6 KiB
JavaScript
/**
|
|
* Copyright (c) 2013-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule randomizeBlockMapKeys
|
|
* @format
|
|
*
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ContentBlockNode = require('./ContentBlockNode');
|
|
var Immutable = require('immutable');
|
|
|
|
var generateRandomKey = require('./generateRandomKey');
|
|
|
|
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 = void 0;
|
|
|
|
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; |