/** * 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 BlockTree * @format * */ 'use strict'; var Immutable = require('immutable'); var emptyFunction = require('fbjs/lib/emptyFunction'); var findRangesImmutable = require('./findRangesImmutable'); var List = Immutable.List, Repeat = Immutable.Repeat, Record = Immutable.Record; var returnTrue = emptyFunction.thatReturnsTrue; var FINGERPRINT_DELIMITER = '-'; var defaultLeafRange = { start: null, end: null }; var LeafRange = Record(defaultLeafRange); var defaultDecoratorRange = { start: null, end: null, decoratorKey: null, leaves: null }; var DecoratorRange = Record(defaultDecoratorRange); var BlockTree = { /** * Generate a block tree for a given ContentBlock/decorator pair. */ generate: function generate(contentState, block, decorator) { var textLength = block.getLength(); if (!textLength) { return List.of(new DecoratorRange({ start: 0, end: 0, decoratorKey: null, leaves: List.of(new LeafRange({ start: 0, end: 0 })) })); } var leafSets = []; var decorations = decorator ? decorator.getDecorations(block, contentState) : List(Repeat(null, textLength)); var chars = block.getCharacterList(); findRangesImmutable(decorations, areEqual, returnTrue, function (start, end) { leafSets.push(new DecoratorRange({ start: start, end: end, decoratorKey: decorations.get(start), leaves: generateLeaves(chars.slice(start, end).toList(), start) })); }); return List(leafSets); }, /** * Create a string representation of the given tree map. This allows us * to rapidly determine whether a tree has undergone a significant * structural change. */ getFingerprint: function getFingerprint(tree) { return tree.map(function (leafSet) { var decoratorKey = leafSet.get('decoratorKey'); var fingerprintString = decoratorKey !== null ? decoratorKey + '.' + (leafSet.get('end') - leafSet.get('start')) : ''; return '' + fingerprintString + '.' + leafSet.get('leaves').size; }).join(FINGERPRINT_DELIMITER); } }; /** * Generate LeafRange records for a given character list. */ function generateLeaves(characters, offset) { var leaves = []; var inlineStyles = characters.map(function (c) { return c.getStyle(); }).toList(); findRangesImmutable(inlineStyles, areEqual, returnTrue, function (start, end) { leaves.push(new LeafRange({ start: start + offset, end: end + offset })); }); return List(leaves); } function areEqual(a, b) { return a === b; } module.exports = BlockTree;