You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

67 lines
2.3 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 strict-local
  9. * @emails oncall+draft_js
  10. */
  11. 'use strict';
  12. import type ContentState from "./ContentState";
  13. import type SelectionState from "./SelectionState";
  14. const CharacterMetadata = require("./CharacterMetadata");
  15. const {
  16. Map
  17. } = require("immutable");
  18. const ContentStateInlineStyle = {
  19. add: function (contentState: ContentState, selectionState: SelectionState, inlineStyle: string): ContentState {
  20. return modifyInlineStyle(contentState, selectionState, inlineStyle, true);
  21. },
  22. remove: function (contentState: ContentState, selectionState: SelectionState, inlineStyle: string): ContentState {
  23. return modifyInlineStyle(contentState, selectionState, inlineStyle, false);
  24. }
  25. };
  26. function modifyInlineStyle(contentState: ContentState, selectionState: SelectionState, inlineStyle: string, addOrRemove: boolean): ContentState {
  27. const blockMap = contentState.getBlockMap();
  28. const startKey = selectionState.getStartKey();
  29. const startOffset = selectionState.getStartOffset();
  30. const endKey = selectionState.getEndKey();
  31. const endOffset = selectionState.getEndOffset();
  32. const newBlocks = blockMap.skipUntil((_, k) => k === startKey).takeUntil((_, k) => k === endKey).concat(Map([[endKey, blockMap.get(endKey)]])).map((block, blockKey) => {
  33. let sliceStart;
  34. let sliceEnd;
  35. if (startKey === endKey) {
  36. sliceStart = startOffset;
  37. sliceEnd = endOffset;
  38. } else {
  39. sliceStart = blockKey === startKey ? startOffset : 0;
  40. sliceEnd = blockKey === endKey ? endOffset : block.getLength();
  41. }
  42. let chars = block.getCharacterList();
  43. let current;
  44. while (sliceStart < sliceEnd) {
  45. current = chars.get(sliceStart);
  46. chars = chars.set(sliceStart, addOrRemove ? CharacterMetadata.applyStyle(current, inlineStyle) : CharacterMetadata.removeStyle(current, inlineStyle));
  47. sliceStart++;
  48. }
  49. return block.set('characterList', chars);
  50. });
  51. return contentState.merge({
  52. blockMap: blockMap.merge(newBlocks),
  53. selectionBefore: selectionState,
  54. selectionAfter: selectionState
  55. });
  56. }
  57. module.exports = ContentStateInlineStyle;