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

148 строки
3.7 KiB

  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. * This file is a fork of ContentBlock adding support for nesting references by
  12. * providing links to children, parent, prevSibling, and nextSibling.
  13. *
  14. * This is unstable and not part of the public API and should not be used by
  15. * production systems. This file may be update/removed without notice.
  16. */
  17. 'use strict';
  18. import type { BlockNode, BlockNodeConfig, BlockNodeKey } from "./BlockNode";
  19. import type { DraftBlockType } from "./DraftBlockType";
  20. import type { DraftInlineStyle } from "./DraftInlineStyle";
  21. const CharacterMetadata = require("./CharacterMetadata");
  22. const findRangesImmutable = require("./findRangesImmutable");
  23. const Immutable = require("immutable");
  24. const {
  25. List,
  26. Map,
  27. OrderedSet,
  28. Record,
  29. Repeat
  30. } = Immutable;
  31. type ContentBlockNodeConfig = BlockNodeConfig & {
  32. children?: List<BlockNodeKey>,
  33. parent?: ?BlockNodeKey,
  34. prevSibling?: ?BlockNodeKey,
  35. nextSibling?: ?BlockNodeKey,
  36. ...
  37. };
  38. const EMPTY_SET = OrderedSet();
  39. const defaultRecord: ContentBlockNodeConfig = {
  40. parent: null,
  41. characterList: List(),
  42. data: Map(),
  43. depth: 0,
  44. key: '',
  45. text: '',
  46. type: 'unstyled',
  47. children: List(),
  48. prevSibling: null,
  49. nextSibling: null
  50. };
  51. const haveEqualStyle = (charA: CharacterMetadata, charB: CharacterMetadata): boolean => charA.getStyle() === charB.getStyle();
  52. const haveEqualEntity = (charA: CharacterMetadata, charB: CharacterMetadata): boolean => charA.getEntity() === charB.getEntity();
  53. const decorateCharacterList = (config: ContentBlockNodeConfig): ContentBlockNodeConfig => {
  54. if (!config) {
  55. return config;
  56. }
  57. const {
  58. characterList,
  59. text
  60. } = config;
  61. if (text && !characterList) {
  62. config.characterList = List(Repeat(CharacterMetadata.EMPTY, text.length));
  63. }
  64. return config;
  65. };
  66. class ContentBlockNode extends (Record(defaultRecord): any) implements BlockNode {
  67. constructor(props: ContentBlockNodeConfig = defaultRecord) {
  68. /* eslint-disable-next-line constructor-super */
  69. super(decorateCharacterList(props));
  70. }
  71. getKey(): BlockNodeKey {
  72. return this.get('key');
  73. }
  74. getType(): DraftBlockType {
  75. return this.get('type');
  76. }
  77. getText(): string {
  78. return this.get('text');
  79. }
  80. getCharacterList(): List<CharacterMetadata> {
  81. return this.get('characterList');
  82. }
  83. getLength(): number {
  84. return this.getText().length;
  85. }
  86. getDepth(): number {
  87. return this.get('depth');
  88. }
  89. getData(): Map<any, any> {
  90. return this.get('data');
  91. }
  92. getInlineStyleAt(offset: number): DraftInlineStyle {
  93. const character = this.getCharacterList().get(offset);
  94. return character ? character.getStyle() : EMPTY_SET;
  95. }
  96. getEntityAt(offset: number): ?string {
  97. const character = this.getCharacterList().get(offset);
  98. return character ? character.getEntity() : null;
  99. }
  100. getChildKeys(): List<BlockNodeKey> {
  101. return this.get('children');
  102. }
  103. getParentKey(): ?BlockNodeKey {
  104. return this.get('parent');
  105. }
  106. getPrevSiblingKey(): ?BlockNodeKey {
  107. return this.get('prevSibling');
  108. }
  109. getNextSiblingKey(): ?BlockNodeKey {
  110. return this.get('nextSibling');
  111. }
  112. findStyleRanges(filterFn: (value: CharacterMetadata) => boolean, callback: (start: number, end: number) => void): void {
  113. findRangesImmutable(this.getCharacterList(), haveEqualStyle, filterFn, callback);
  114. }
  115. findEntityRanges(filterFn: (value: CharacterMetadata) => boolean, callback: (start: number, end: number) => void): void {
  116. findRangesImmutable(this.getCharacterList(), haveEqualEntity, filterFn, callback);
  117. }
  118. }
  119. module.exports = ContentBlockNode;