選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

DraftEntitySegments.js.flow 2.6 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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 { DraftRange } from "./DraftRange";
  13. import type { DraftRemovalDirection } from "./DraftRemovalDirection";
  14. /**
  15. * Identify the range to delete from a segmented entity.
  16. *
  17. * Rules:
  18. *
  19. * Example: 'John F. Kennedy'
  20. *
  21. * - Deletion from within any non-whitespace (i.e. ['John', 'F.', 'Kennedy'])
  22. * will return the range of that text.
  23. *
  24. * 'John F. Kennedy' -> 'John F.'
  25. * ^
  26. *
  27. * - Forward deletion of whitespace will remove the following section:
  28. *
  29. * 'John F. Kennedy' -> 'John Kennedy'
  30. * ^
  31. *
  32. * - Backward deletion of whitespace will remove the previous section:
  33. *
  34. * 'John F. Kennedy' -> 'F. Kennedy'
  35. * ^
  36. */
  37. const DraftEntitySegments = {
  38. getRemovalRange: function (selectionStart: number, selectionEnd: number, text: string, entityStart: number, direction: DraftRemovalDirection): DraftRange {
  39. let segments = text.split(' ');
  40. segments = segments.map((
  41. /*string*/
  42. segment,
  43. /*number*/
  44. ii) => {
  45. if (direction === 'forward') {
  46. if (ii > 0) {
  47. return ' ' + segment;
  48. }
  49. } else if (ii < segments.length - 1) {
  50. return segment + ' ';
  51. }
  52. return segment;
  53. });
  54. let segmentStart = entityStart;
  55. let segmentEnd;
  56. let segment;
  57. let removalStart: any = null;
  58. let removalEnd: any = null;
  59. for (let jj = 0; jj < segments.length; jj++) {
  60. segment = segments[jj];
  61. segmentEnd = segmentStart + segment.length; // Our selection overlaps this segment.
  62. if (selectionStart < segmentEnd && segmentStart < selectionEnd) {
  63. if (removalStart !== null) {
  64. removalEnd = segmentEnd;
  65. } else {
  66. removalStart = segmentStart;
  67. removalEnd = segmentEnd;
  68. }
  69. } else if (removalStart !== null) {
  70. break;
  71. }
  72. segmentStart = segmentEnd;
  73. }
  74. const entityEnd = entityStart + text.length;
  75. const atStart = removalStart === entityStart;
  76. const atEnd = removalEnd === entityEnd;
  77. if (!atStart && atEnd || atStart && !atEnd) {
  78. if (direction === 'forward') {
  79. if (removalEnd !== entityEnd) {
  80. removalEnd++;
  81. }
  82. } else if (removalStart !== entityStart) {
  83. removalStart--;
  84. }
  85. }
  86. return {
  87. start: removalStart,
  88. end: removalEnd
  89. };
  90. }
  91. };
  92. module.exports = DraftEntitySegments;