UNPKG

3.74 kBJavaScriptView Raw
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 *
9 * @emails oncall+draft_js
10 */
11'use strict';
12
13function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
14
15var Immutable = require("immutable");
16
17var List = Immutable.List;
18var DELIMITER = '.';
19/**
20 * A CompositeDraftDecorator traverses through a list of DraftDecorator
21 * instances to identify sections of a ContentBlock that should be rendered
22 * in a "decorated" manner. For example, hashtags, mentions, and links may
23 * be intended to stand out visually, be rendered as anchors, etc.
24 *
25 * The list of decorators supplied to the constructor will be used in the
26 * order they are provided. This allows the caller to specify a priority for
27 * string matching, in case of match collisions among decorators.
28 *
29 * For instance, I may have a link with a `#` in its text. Though this section
30 * of text may match our hashtag decorator, it should not be treated as a
31 * hashtag. I should therefore list my link DraftDecorator
32 * before my hashtag DraftDecorator when constructing this composite
33 * decorator instance.
34 *
35 * Thus, when a collision like this is encountered, the earlier match is
36 * preserved and the new match is discarded.
37 */
38
39var CompositeDraftDecorator = /*#__PURE__*/function () {
40 function CompositeDraftDecorator(decorators) {
41 _defineProperty(this, "_decorators", void 0);
42
43 // Copy the decorator array, since we use this array order to determine
44 // precedence of decoration matching. If the array is mutated externally,
45 // we don't want to be affected here.
46 this._decorators = decorators.slice();
47 }
48
49 var _proto = CompositeDraftDecorator.prototype;
50
51 _proto.getDecorations = function getDecorations(block, contentState) {
52 var decorations = Array(block.getText().length).fill(null);
53
54 this._decorators.forEach(function (
55 /*object*/
56 decorator,
57 /*number*/
58 ii) {
59 var counter = 0;
60 var strategy = decorator.strategy;
61
62 var callback = function callback(
63 /*number*/
64 start,
65 /*number*/
66 end) {
67 // Find out if any of our matching range is already occupied
68 // by another decorator. If so, discard the match. Otherwise, store
69 // the component key for rendering.
70 if (canOccupySlice(decorations, start, end)) {
71 occupySlice(decorations, start, end, ii + DELIMITER + counter);
72 counter++;
73 }
74 };
75
76 strategy(block, callback, contentState);
77 });
78
79 return List(decorations);
80 };
81
82 _proto.getComponentForKey = function getComponentForKey(key) {
83 var componentKey = parseInt(key.split(DELIMITER)[0], 10);
84 return this._decorators[componentKey].component;
85 };
86
87 _proto.getPropsForKey = function getPropsForKey(key) {
88 var componentKey = parseInt(key.split(DELIMITER)[0], 10);
89 return this._decorators[componentKey].props;
90 };
91
92 return CompositeDraftDecorator;
93}();
94/**
95 * Determine whether we can occupy the specified slice of the decorations
96 * array.
97 */
98
99
100function canOccupySlice(decorations, start, end) {
101 for (var ii = start; ii < end; ii++) {
102 if (decorations[ii] != null) {
103 return false;
104 }
105 }
106
107 return true;
108}
109/**
110 * Splice the specified component into our decoration array at the desired
111 * range.
112 */
113
114
115function occupySlice(targetArr, start, end, componentKey) {
116 for (var ii = start; ii < end; ii++) {
117 targetArr[ii] = componentKey;
118 }
119}
120
121module.exports = CompositeDraftDecorator;
\No newline at end of file