@instructure/ui-truncate-text 8.33.1 → 8.33.2-snapshot-5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/es/TruncateText/index.js +19 -51
- package/es/TruncateText/props.js +1 -0
- package/es/TruncateText/styles.js +0 -1
- package/es/TruncateText/theme.js +2 -2
- package/es/TruncateText/utils/cleanData.js +3 -31
- package/es/TruncateText/utils/cleanString.js +0 -5
- package/es/TruncateText/utils/measureText.js +8 -16
- package/es/TruncateText/utils/truncate.js +30 -82
- package/lib/TruncateText/index.js +19 -70
- package/lib/TruncateText/props.js +1 -3
- package/lib/TruncateText/styles.js +0 -2
- package/lib/TruncateText/theme.js +2 -3
- package/lib/TruncateText/utils/cleanData.js +2 -32
- package/lib/TruncateText/utils/cleanString.js +0 -6
- package/lib/TruncateText/utils/measureText.js +6 -17
- package/lib/TruncateText/utils/truncate.js +29 -92
- package/lib/index.js +0 -1
- package/package.json +14 -14
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -4,9 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _cloneArray = require("@instructure/ui-utils/lib/cloneArray.js");
|
|
9
|
-
|
|
10
8
|
/*
|
|
11
9
|
* The MIT License (MIT)
|
|
12
10
|
*
|
|
@@ -49,91 +47,73 @@ var _cloneArray = require("@instructure/ui-utils/lib/cloneArray.js");
|
|
|
49
47
|
function cleanData(stringData, options) {
|
|
50
48
|
let repeat = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : false;
|
|
51
49
|
const truncate = options.truncate,
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
ignore = options.ignore,
|
|
51
|
+
ellipsis = options.ellipsis;
|
|
54
52
|
let newData = (0, _cloneArray.cloneArray)(stringData);
|
|
55
53
|
let ellipsisNode = -1;
|
|
56
54
|
let ellipsisIndex = -1;
|
|
57
|
-
|
|
58
55
|
const findEllipsis = () => {
|
|
59
56
|
for (let i = 0; i < newData.length; i++) {
|
|
60
57
|
const nodeData = newData[i];
|
|
61
|
-
|
|
62
58
|
if (nodeData.indexOf(ellipsis) !== -1) {
|
|
63
59
|
ellipsisNode = i;
|
|
64
60
|
ellipsisIndex = nodeData.indexOf(ellipsis);
|
|
65
61
|
}
|
|
66
62
|
}
|
|
67
63
|
};
|
|
68
|
-
|
|
69
64
|
if (truncate === 'character') {
|
|
70
65
|
findEllipsis();
|
|
71
66
|
let node = newData[ellipsisNode];
|
|
72
|
-
|
|
73
67
|
if (node) {
|
|
74
68
|
const before = node[ellipsisIndex - 1];
|
|
75
|
-
|
|
76
69
|
if (before && ignore.indexOf(before) !== -1) {
|
|
77
70
|
// remove character immediately BEFORE the ellipsis in the same node
|
|
78
71
|
newData[ellipsisNode].splice(ellipsisIndex - 1, 1);
|
|
79
72
|
}
|
|
80
|
-
|
|
81
73
|
if (!before) {
|
|
82
74
|
// character before the ellipsis is part of a different node
|
|
83
75
|
// find the next node with data and remove last datum
|
|
84
76
|
let prevNode = null;
|
|
85
77
|
let prevNodeIndex = ellipsisNode - 1;
|
|
86
|
-
|
|
87
78
|
while (prevNodeIndex >= 0) {
|
|
88
79
|
prevNode = newData[prevNodeIndex];
|
|
89
|
-
|
|
90
80
|
if (prevNode.length > 0) {
|
|
91
81
|
break;
|
|
92
82
|
} else {
|
|
93
83
|
prevNodeIndex--;
|
|
94
84
|
}
|
|
95
85
|
}
|
|
96
|
-
|
|
97
86
|
if (prevNode) {
|
|
98
87
|
const lastChar = String(prevNode.slice(-1));
|
|
99
|
-
|
|
100
88
|
if (ignore.indexOf(lastChar) !== -1) {
|
|
101
89
|
newData[prevNodeIndex].length -= 1;
|
|
102
90
|
}
|
|
103
91
|
}
|
|
104
92
|
}
|
|
105
93
|
}
|
|
106
|
-
|
|
107
94
|
findEllipsis();
|
|
108
95
|
node = newData[ellipsisNode];
|
|
109
|
-
|
|
110
96
|
if (node) {
|
|
111
97
|
const after = node[ellipsisIndex + 1];
|
|
112
|
-
|
|
113
98
|
if (after && ignore.indexOf(after) !== -1) {
|
|
114
99
|
// remove character immediately AFTER the ellipsis in the same node
|
|
115
100
|
newData[ellipsisNode].splice(ellipsisIndex + 1, 1);
|
|
116
101
|
}
|
|
117
|
-
|
|
118
102
|
if (!after) {
|
|
119
103
|
// character after the ellipsis is part of a different node
|
|
120
104
|
// find the next node with data and remove first datum
|
|
121
105
|
let nextNode = null;
|
|
122
106
|
let nextNodeIndex = ellipsisNode + 1;
|
|
123
|
-
|
|
124
107
|
while (nextNodeIndex < newData.length) {
|
|
125
108
|
nextNode = newData[nextNodeIndex];
|
|
126
|
-
|
|
127
109
|
if (nextNode.length > 0) {
|
|
128
110
|
break;
|
|
129
111
|
} else {
|
|
130
112
|
nextNodeIndex++;
|
|
131
113
|
}
|
|
132
114
|
}
|
|
133
|
-
|
|
134
115
|
if (nextNode) {
|
|
135
116
|
const firstChar = String(nextNode[0]);
|
|
136
|
-
|
|
137
117
|
if (ignore.indexOf(firstChar) !== -1) {
|
|
138
118
|
newData[nextNodeIndex].shift();
|
|
139
119
|
}
|
|
@@ -143,10 +123,8 @@ function cleanData(stringData, options) {
|
|
|
143
123
|
} else {
|
|
144
124
|
findEllipsis();
|
|
145
125
|
const node = newData[ellipsisNode];
|
|
146
|
-
|
|
147
126
|
if (node) {
|
|
148
127
|
const before = node[ellipsisIndex - 1];
|
|
149
|
-
|
|
150
128
|
if (before && ignore.indexOf(before.slice(-1)) !== -1) {
|
|
151
129
|
if (before.length === 1) {
|
|
152
130
|
// remove entire word datum
|
|
@@ -156,26 +134,21 @@ function cleanData(stringData, options) {
|
|
|
156
134
|
newData[ellipsisNode][ellipsisIndex - 1] = before.slice(0, -1);
|
|
157
135
|
}
|
|
158
136
|
}
|
|
159
|
-
|
|
160
137
|
if (!before) {
|
|
161
138
|
// word before the ellipsis is part of a different node
|
|
162
139
|
// find the next node with data and remove last datum
|
|
163
140
|
let prevNode = null;
|
|
164
141
|
let prevNodeIndex = ellipsisNode - 1;
|
|
165
|
-
|
|
166
142
|
while (prevNodeIndex >= 0) {
|
|
167
143
|
prevNode = newData[prevNodeIndex];
|
|
168
|
-
|
|
169
144
|
if (prevNode.length > 0) {
|
|
170
145
|
break;
|
|
171
146
|
} else {
|
|
172
147
|
prevNodeIndex--;
|
|
173
148
|
}
|
|
174
149
|
}
|
|
175
|
-
|
|
176
150
|
if (prevNode) {
|
|
177
151
|
const lastChar = String(prevNode.slice(-1)).slice(-1);
|
|
178
|
-
|
|
179
152
|
if (ignore.indexOf(lastChar) !== -1) {
|
|
180
153
|
const lastItem = prevNode.length - 1;
|
|
181
154
|
newData[prevNodeIndex][lastItem] = prevNode[lastItem].slice(0, -1);
|
|
@@ -184,13 +157,10 @@ function cleanData(stringData, options) {
|
|
|
184
157
|
}
|
|
185
158
|
}
|
|
186
159
|
}
|
|
187
|
-
|
|
188
160
|
if (repeat) {
|
|
189
161
|
newData = cleanData(newData, options, false);
|
|
190
162
|
}
|
|
191
|
-
|
|
192
163
|
return newData;
|
|
193
164
|
}
|
|
194
|
-
|
|
195
165
|
var _default = cleanData;
|
|
196
166
|
exports.default = _default;
|
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
/*
|
|
9
8
|
* The MIT License (MIT)
|
|
10
9
|
*
|
|
@@ -49,21 +48,16 @@ function cleanString(string, ignore) {
|
|
|
49
48
|
let text = string;
|
|
50
49
|
const firstChar = text.charAt(0);
|
|
51
50
|
const lastChar = text.slice(-1);
|
|
52
|
-
|
|
53
51
|
if (start && ignore.indexOf(firstChar) !== -1) {
|
|
54
52
|
text = text.slice(1);
|
|
55
53
|
}
|
|
56
|
-
|
|
57
54
|
if (end && ignore.indexOf(lastChar) !== -1) {
|
|
58
55
|
text = text.slice(0, -1);
|
|
59
56
|
}
|
|
60
|
-
|
|
61
57
|
if (repeat) {
|
|
62
58
|
text = cleanString(text, ignore, start, end, false);
|
|
63
59
|
}
|
|
64
|
-
|
|
65
60
|
return text;
|
|
66
61
|
}
|
|
67
|
-
|
|
68
62
|
var _default = cleanString;
|
|
69
63
|
exports.default = _default;
|
|
@@ -4,9 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _getComputedStyle = require("@instructure/ui-dom-utils/lib/getComputedStyle.js");
|
|
9
|
-
|
|
10
8
|
/*
|
|
11
9
|
* The MIT License (MIT)
|
|
12
10
|
*
|
|
@@ -43,33 +41,27 @@ var _getComputedStyle = require("@instructure/ui-dom-utils/lib/getComputedStyle.
|
|
|
43
41
|
*/
|
|
44
42
|
function measureText(nodes, parentNode) {
|
|
45
43
|
let width = 0;
|
|
46
|
-
|
|
47
44
|
for (let i = 0; i < nodes.length; i++) {
|
|
48
45
|
const node = nodes[i];
|
|
49
46
|
width += measure(node.textContent, node.nodeType === 1 ? node : parentNode);
|
|
50
47
|
}
|
|
51
|
-
|
|
52
48
|
return width;
|
|
53
49
|
}
|
|
54
|
-
|
|
55
50
|
function measure(string, domNode) {
|
|
56
|
-
const style = (0, _getComputedStyle.getComputedStyle)(domNode);
|
|
57
|
-
|
|
51
|
+
const style = (0, _getComputedStyle.getComputedStyle)(domNode);
|
|
52
|
+
// we use a canvas in a doc fragment to prevent having to render the string full width in the DOM
|
|
58
53
|
const canvas = document.createElement('canvas');
|
|
59
54
|
document.createDocumentFragment().appendChild(canvas);
|
|
60
55
|
const context = canvas.getContext('2d');
|
|
61
|
-
|
|
62
56
|
if (!context || !string) {
|
|
63
57
|
return 0;
|
|
64
58
|
}
|
|
65
|
-
|
|
66
59
|
let text = string;
|
|
67
60
|
let letterOffset = 0;
|
|
68
|
-
let width = 0;
|
|
61
|
+
let width = 0;
|
|
62
|
+
// grab individual font styles
|
|
69
63
|
// some browsers don't report a value for style['font']
|
|
70
|
-
|
|
71
64
|
context.font = [style.fontWeight, style.fontStyle, style.fontSize, style.fontFamily].join(' ');
|
|
72
|
-
|
|
73
65
|
if (style.textTransform === 'uppercase') {
|
|
74
66
|
text = string.toUpperCase();
|
|
75
67
|
} else if (style.textTransform === 'lowercase') {
|
|
@@ -77,15 +69,12 @@ function measure(string, domNode) {
|
|
|
77
69
|
} else if (style.textTransform === 'capitalize') {
|
|
78
70
|
text = string.replace(/\b\w/g, str => str.toUpperCase());
|
|
79
71
|
}
|
|
80
|
-
|
|
81
72
|
if (style.letterSpacing !== 'normal') {
|
|
82
73
|
letterOffset = text.length * parseInt(style.letterSpacing);
|
|
83
74
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
75
|
+
width = context.measureText(text).width + letterOffset;
|
|
76
|
+
// returns the max potential width of the text, assuming the text was on a single line
|
|
87
77
|
return width;
|
|
88
78
|
}
|
|
89
|
-
|
|
90
79
|
var _default = measureText;
|
|
91
80
|
exports.default = _default;
|
|
@@ -1,30 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
-
|
|
5
4
|
Object.defineProperty(exports, "__esModule", {
|
|
6
5
|
value: true
|
|
7
6
|
});
|
|
8
7
|
exports.default = void 0;
|
|
9
|
-
|
|
10
8
|
var _escapeHtml = _interopRequireDefault(require("escape-html"));
|
|
11
|
-
|
|
12
9
|
var _cloneArray = require("@instructure/ui-utils/lib/cloneArray.js");
|
|
13
|
-
|
|
14
10
|
var _console = require("@instructure/console");
|
|
15
|
-
|
|
16
11
|
var _getComputedStyle = require("@instructure/ui-dom-utils/lib/getComputedStyle.js");
|
|
17
|
-
|
|
18
12
|
var _getBoundingClientRect = require("@instructure/ui-dom-utils/lib/getBoundingClientRect.js");
|
|
19
|
-
|
|
20
13
|
var _isVisible = require("@instructure/ui-dom-utils/lib/isVisible.js");
|
|
21
|
-
|
|
22
14
|
var _measureText = _interopRequireDefault(require("./measureText"));
|
|
23
|
-
|
|
24
15
|
var _cleanString = _interopRequireDefault(require("./cleanString"));
|
|
25
|
-
|
|
26
16
|
var _cleanData = _interopRequireDefault(require("./cleanData"));
|
|
27
|
-
|
|
28
17
|
/*
|
|
29
18
|
* The MIT License (MIT)
|
|
30
19
|
*
|
|
@@ -69,14 +58,11 @@ var _cleanData = _interopRequireDefault(require("./cleanData"));
|
|
|
69
58
|
*/
|
|
70
59
|
function truncate(element, options) {
|
|
71
60
|
const truncator = new Truncator(element, options);
|
|
72
|
-
|
|
73
61
|
if (truncator) {
|
|
74
62
|
return truncator.truncate();
|
|
75
63
|
}
|
|
76
|
-
|
|
77
64
|
return;
|
|
78
65
|
}
|
|
79
|
-
|
|
80
66
|
class Truncator {
|
|
81
67
|
constructor(element) {
|
|
82
68
|
let options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
@@ -100,161 +86,133 @@ class Truncator {
|
|
|
100
86
|
lineHeight: options.lineHeight || 1.2,
|
|
101
87
|
shouldTruncateWhenInvisible: !!options.shouldTruncateWhenInvisible
|
|
102
88
|
};
|
|
103
|
-
|
|
104
89
|
if (!element) {
|
|
105
90
|
(0, _console.logError)(false, '[Truncator] No element to truncate.');
|
|
106
91
|
return;
|
|
107
92
|
}
|
|
108
|
-
|
|
109
93
|
this._stage = element;
|
|
110
|
-
|
|
111
94
|
if (options.parent) {
|
|
112
95
|
this._parent = this._options.parent;
|
|
113
96
|
} else {
|
|
114
97
|
const parentEl = this._stage.parentElement ? this._stage.parentElement : void 0;
|
|
115
98
|
this._parent = this._options.maxLines === 'auto' ? parentEl : this._stage;
|
|
116
99
|
}
|
|
117
|
-
|
|
118
100
|
this.setup();
|
|
119
101
|
}
|
|
120
|
-
|
|
121
102
|
setup() {
|
|
122
103
|
if (!this._stage) {
|
|
123
104
|
return;
|
|
124
105
|
}
|
|
125
|
-
|
|
126
106
|
const _this$_options = this._options,
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const style = (0, _getComputedStyle.getComputedStyle)(this._parent);
|
|
131
|
-
|
|
107
|
+
maxLines = _this$_options.maxLines,
|
|
108
|
+
truncate = _this$_options.truncate,
|
|
109
|
+
lineHeight = _this$_options.lineHeight;
|
|
110
|
+
const style = (0, _getComputedStyle.getComputedStyle)(this._parent);
|
|
111
|
+
// if no explicit lineHeight is inherited, use lineHeight multiplier for calculations
|
|
132
112
|
const actualLineHeight = style.lineHeight === 'normal' ? lineHeight * parseFloat(style.fontSize) : parseFloat(style.lineHeight);
|
|
133
113
|
const node = this._stage.firstChild.children ? this._stage.firstChild : this._stage;
|
|
134
114
|
const nodeDataIndexes = [];
|
|
135
115
|
const stringData = [];
|
|
136
116
|
this._nodeMap = this.getNodeMap(node);
|
|
137
|
-
|
|
138
117
|
for (let i = 0; i < this._nodeMap.length; i++) {
|
|
139
118
|
const item = this._nodeMap[i];
|
|
140
|
-
|
|
141
119
|
if (truncate === 'word' && item.data[item.data.length - 1] === ' ') {
|
|
142
120
|
// remove random whitespace data between nodes
|
|
143
121
|
item.data.length -= 1;
|
|
144
122
|
}
|
|
145
|
-
|
|
146
123
|
stringData[i] = item.data;
|
|
147
|
-
|
|
148
124
|
for (let j = 0; j < item.data.length; j++) {
|
|
149
125
|
// map each word or character datum index to its corresponding node
|
|
150
126
|
nodeDataIndexes.push(i);
|
|
151
127
|
}
|
|
152
128
|
}
|
|
153
|
-
|
|
154
129
|
this._defaultStringData = (0, _cloneArray.cloneArray)(stringData);
|
|
155
130
|
this._nodeDataIndexes = (0, _cloneArray.cloneArray)(nodeDataIndexes);
|
|
156
131
|
this._maxHeight = maxLines === 'auto' ? (0, _getBoundingClientRect.getBoundingClientRect)(this._parent).height : maxLines * actualLineHeight;
|
|
157
132
|
this._maxWidth = (0, _measureText.default)(this._nodeMap.map(item => item.node), this._parent);
|
|
158
133
|
this._maxLines = maxLines === 'auto' ? Math.round(this._maxHeight / actualLineHeight) : maxLines;
|
|
159
134
|
}
|
|
160
|
-
|
|
161
135
|
getNodeMap(rootNode) {
|
|
162
136
|
const _this$_options2 = this._options,
|
|
163
|
-
|
|
164
|
-
|
|
137
|
+
shouldTruncateWhenInvisible = _this$_options2.shouldTruncateWhenInvisible,
|
|
138
|
+
truncate = _this$_options2.truncate;
|
|
165
139
|
const nodes = Array.from(rootNode.childNodes);
|
|
166
|
-
const map = [];
|
|
167
|
-
|
|
140
|
+
const map = [];
|
|
141
|
+
// parse child nodes and build a data map to associate each node with its data
|
|
168
142
|
nodes.forEach(node => {
|
|
169
143
|
if (node.nodeType === 1 || node.nodeType === 3) {
|
|
170
144
|
const shouldTruncate = shouldTruncateWhenInvisible ? true : (0, _isVisible.isVisible)(node, false);
|
|
171
145
|
const textContent = node.textContent + ' ';
|
|
172
146
|
map.push({
|
|
173
147
|
node,
|
|
174
|
-
data: truncate === 'word' ? shouldTruncate ?
|
|
148
|
+
data: truncate === 'word' ? shouldTruncate ?
|
|
149
|
+
// eslint-disable-next-line no-useless-escape
|
|
175
150
|
textContent.match(/.*?[\.\s\/]+?/g) : [''] : shouldTruncate ? node.textContent.split('') : []
|
|
176
151
|
});
|
|
177
152
|
}
|
|
178
153
|
});
|
|
179
154
|
return map;
|
|
180
155
|
}
|
|
181
|
-
|
|
182
156
|
getNodeIndexes(data) {
|
|
183
157
|
const nodeDataIndexes = [];
|
|
184
|
-
|
|
185
158
|
for (let i = 0; i < data.length; i++) {
|
|
186
159
|
for (let j = 0; j < data[i].length; j++) {
|
|
187
160
|
nodeDataIndexes.push([i, j]);
|
|
188
161
|
}
|
|
189
162
|
}
|
|
190
|
-
|
|
191
163
|
return nodeDataIndexes;
|
|
192
164
|
}
|
|
193
|
-
|
|
194
165
|
domString(data) {
|
|
195
166
|
let html = '';
|
|
196
|
-
|
|
197
167
|
for (let i = 0; i < data.length; i++) {
|
|
198
168
|
const mapItem = this._nodeMap[i];
|
|
199
169
|
const text = data[i].join('');
|
|
200
170
|
const safeText = (0, _escapeHtml.default)(text);
|
|
201
|
-
|
|
202
171
|
if (mapItem.node.nodeType === Node.ELEMENT_NODE) {
|
|
203
172
|
const name = mapItem.node.nodeName;
|
|
204
173
|
const attr = mapItem.node.attributes;
|
|
205
174
|
let attributes = '';
|
|
206
|
-
|
|
207
175
|
for (let j = 0; j < attr.length; j++) {
|
|
208
176
|
const att = attr[j];
|
|
209
177
|
attributes += ` ${att.nodeName}="${att.nodeValue}"`;
|
|
210
178
|
}
|
|
211
|
-
|
|
212
179
|
html += `<${name}${attributes}>${safeText}</${name}>`;
|
|
213
180
|
} else if (mapItem.node.nodeType === 3) {
|
|
214
181
|
html += safeText;
|
|
215
182
|
}
|
|
216
183
|
}
|
|
217
|
-
|
|
218
184
|
return html;
|
|
219
185
|
}
|
|
220
|
-
|
|
221
186
|
checkFit(data) {
|
|
222
187
|
const html = this.domString(data);
|
|
223
188
|
const node = this._options.maxLines === 'auto' ? this._stage : this._parent;
|
|
224
189
|
let fits = true;
|
|
225
|
-
this._stage.innerHTML = html;
|
|
226
|
-
|
|
190
|
+
this._stage.innerHTML = html;
|
|
191
|
+
// allow a 0.5 px margin of error for browser calculation discrepancies
|
|
227
192
|
if ((0, _getBoundingClientRect.getBoundingClientRect)(node).height - this._maxHeight > 0.5) {
|
|
228
193
|
fits = false;
|
|
229
194
|
}
|
|
230
|
-
|
|
231
195
|
return fits;
|
|
232
196
|
}
|
|
233
|
-
|
|
234
197
|
truncate() {
|
|
235
198
|
const _this$_options3 = this._options,
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
199
|
+
ellipsis = _this$_options3.ellipsis,
|
|
200
|
+
ignore = _this$_options3.ignore,
|
|
201
|
+
position = _this$_options3.position;
|
|
239
202
|
const middle = position === 'middle';
|
|
240
203
|
let truncated = false;
|
|
241
204
|
let truncatedText = '';
|
|
242
205
|
let stringData = null;
|
|
243
|
-
|
|
244
206
|
if (!this._stage) {
|
|
245
207
|
return;
|
|
246
208
|
}
|
|
247
|
-
|
|
248
209
|
const binarySearch = function (_low, _high, ev, middle) {
|
|
249
210
|
let _default = arguments.length > 4 && arguments[4] !== void 0 ? arguments[4] : null;
|
|
250
|
-
|
|
251
211
|
let low = _low;
|
|
252
212
|
let high = _high;
|
|
253
213
|
let bestResult = _default;
|
|
254
|
-
|
|
255
214
|
while (low <= high) {
|
|
256
215
|
const tryNumber = Math.floor((low + high) / 2);
|
|
257
|
-
|
|
258
216
|
if (ev(tryNumber, middle)) {
|
|
259
217
|
high = tryNumber - 1;
|
|
260
218
|
bestResult = tryNumber;
|
|
@@ -262,72 +220,65 @@ class Truncator {
|
|
|
262
220
|
low = tryNumber + 1;
|
|
263
221
|
}
|
|
264
222
|
}
|
|
265
|
-
|
|
266
223
|
return bestResult;
|
|
267
224
|
};
|
|
268
|
-
|
|
269
225
|
const truncateArray = (truncatedLength, originalArray, indexArray, middle) => {
|
|
270
226
|
let truncated = false;
|
|
271
227
|
const truncatedArray = (0, _cloneArray.cloneArray)(originalArray);
|
|
272
|
-
|
|
273
228
|
switch (truncatedLength) {
|
|
274
229
|
// truncate nothing
|
|
275
230
|
case 0:
|
|
276
231
|
break;
|
|
277
|
-
// truncate all
|
|
278
232
|
|
|
233
|
+
// truncate all
|
|
279
234
|
case indexArray.length:
|
|
280
235
|
truncated = true;
|
|
281
|
-
|
|
282
236
|
for (let i = 0; i < truncatedArray.length; i++) {
|
|
283
237
|
truncatedArray[i] = [];
|
|
284
238
|
}
|
|
285
|
-
|
|
286
239
|
truncatedArray[0].push(ellipsis);
|
|
287
240
|
break;
|
|
288
|
-
// truncate a positive amount of elements
|
|
289
241
|
|
|
242
|
+
// truncate a positive amount of elements
|
|
290
243
|
default:
|
|
291
244
|
truncated = true;
|
|
292
|
-
|
|
293
245
|
if (middle) {
|
|
294
|
-
const dataHalves = Array(2);
|
|
295
|
-
|
|
246
|
+
const dataHalves = Array(2);
|
|
247
|
+
// calculate the indexes for two parts
|
|
296
248
|
dataHalves[0] = Math.floor((indexArray.length - truncatedLength - 1) / 2);
|
|
297
249
|
dataHalves[1] = dataHalves[0] + truncatedLength + 1;
|
|
298
250
|
const nodeHalves = dataHalves.map(index => indexArray[index]);
|
|
299
251
|
const sliceAmounts = Array(2);
|
|
300
252
|
sliceAmounts[0] = dataHalves[0] + 1;
|
|
301
|
-
sliceAmounts[1] = indexArray.length - truncatedLength - sliceAmounts[0];
|
|
253
|
+
sliceAmounts[1] = indexArray.length - truncatedLength - sliceAmounts[0];
|
|
302
254
|
|
|
255
|
+
// keep the first part
|
|
303
256
|
for (let i = 0; i <= nodeHalves[0]; i++) {
|
|
304
257
|
switch (true) {
|
|
305
258
|
case i < nodeHalves[0]:
|
|
306
259
|
sliceAmounts[0] -= truncatedArray[i].length;
|
|
307
260
|
break;
|
|
308
|
-
|
|
309
261
|
case i === nodeHalves[0]:
|
|
310
262
|
truncatedArray[i] = originalArray[i].slice(0, sliceAmounts[0]);
|
|
311
263
|
truncatedArray[i].push(ellipsis);
|
|
312
264
|
break;
|
|
313
265
|
}
|
|
314
|
-
}
|
|
315
|
-
|
|
266
|
+
}
|
|
316
267
|
|
|
268
|
+
// and the second part
|
|
317
269
|
for (let i = originalArray.length - 1; i >= nodeHalves[1]; i--) {
|
|
318
270
|
switch (true) {
|
|
319
271
|
case i > nodeHalves[1]:
|
|
320
272
|
sliceAmounts[1] -= originalArray[i].length;
|
|
321
273
|
break;
|
|
322
|
-
|
|
323
274
|
case i === nodeHalves[1]:
|
|
324
275
|
if (nodeHalves[1] > nodeHalves[0]) truncatedArray[i] = originalArray[i].slice(-sliceAmounts[1]);
|
|
325
276
|
if (nodeHalves[1] === nodeHalves[0]) truncatedArray[i] = truncatedArray[i].concat(originalArray[i].slice(-sliceAmounts[1]));
|
|
326
277
|
break;
|
|
327
278
|
}
|
|
328
|
-
}
|
|
329
|
-
|
|
279
|
+
}
|
|
330
280
|
|
|
281
|
+
// delete the middle
|
|
331
282
|
for (let i = nodeHalves[0] + 1; i < nodeHalves[1]; i++) {
|
|
332
283
|
truncatedArray[i] = [];
|
|
333
284
|
}
|
|
@@ -336,55 +287,44 @@ class Truncator {
|
|
|
336
287
|
const indexToTry = indexArray.length - truncatedLength - 1;
|
|
337
288
|
const nodeIndex = indexArray[indexToTry];
|
|
338
289
|
let sliceAmount = indexToTry + 1;
|
|
339
|
-
|
|
340
290
|
for (let i = 0; i < originalArray.length; i++) {
|
|
341
291
|
switch (true) {
|
|
342
292
|
case i < nodeIndex:
|
|
343
293
|
sliceAmount -= truncatedArray[i].length;
|
|
344
294
|
break;
|
|
345
|
-
|
|
346
295
|
case i === nodeIndex:
|
|
347
296
|
truncatedArray[i] = truncatedArray[i].slice(0, sliceAmount);
|
|
348
297
|
truncatedArray[i].push(ellipsis);
|
|
349
298
|
break;
|
|
350
|
-
|
|
351
299
|
case i > nodeIndex:
|
|
352
300
|
truncatedArray[i] = [];
|
|
353
301
|
break;
|
|
354
302
|
}
|
|
355
303
|
}
|
|
356
304
|
}
|
|
357
|
-
|
|
358
305
|
break;
|
|
359
306
|
}
|
|
360
|
-
|
|
361
307
|
return {
|
|
362
308
|
truncated,
|
|
363
309
|
truncatedArray
|
|
364
310
|
};
|
|
365
311
|
};
|
|
366
|
-
|
|
367
312
|
const truncateEvaluate = (truncatedLength, middle) => {
|
|
368
313
|
const _truncateArray = truncateArray(truncatedLength, this._defaultStringData, this._nodeDataIndexes, middle),
|
|
369
|
-
|
|
370
|
-
|
|
314
|
+
truncatedArray = _truncateArray.truncatedArray;
|
|
371
315
|
return this.checkFit(truncatedArray);
|
|
372
|
-
};
|
|
373
|
-
|
|
316
|
+
};
|
|
374
317
|
|
|
318
|
+
// find the best number of element to truncate
|
|
375
319
|
const finestMatch = binarySearch(0, this._nodeDataIndexes.length, truncateEvaluate, middle, this._nodeDataIndexes.length);
|
|
376
|
-
|
|
377
320
|
var _truncateArray2 = truncateArray(finestMatch, this._defaultStringData, this._nodeDataIndexes, middle);
|
|
378
|
-
|
|
379
321
|
truncated = _truncateArray2.truncated;
|
|
380
322
|
stringData = _truncateArray2.truncatedArray;
|
|
381
323
|
stringData = (0, _cleanData.default)(stringData, this._options, true);
|
|
382
|
-
|
|
383
324
|
for (let i = 0; i < stringData.length; i++) {
|
|
384
325
|
const data = stringData[i];
|
|
385
326
|
truncatedText += data.join('');
|
|
386
327
|
}
|
|
387
|
-
|
|
388
328
|
if (truncated && !middle) {
|
|
389
329
|
truncatedText = (0, _cleanString.default)(truncatedText.split(ellipsis)[0], ignore, false, true, true);
|
|
390
330
|
truncatedText += ellipsis;
|
|
@@ -392,7 +332,6 @@ class Truncator {
|
|
|
392
332
|
const halves = truncatedText.split(ellipsis);
|
|
393
333
|
truncatedText = (0, _cleanString.default)(halves[0], ignore, false, true, true) + ellipsis + (0, _cleanString.default)(halves[1], ignore, true, false, true);
|
|
394
334
|
}
|
|
395
|
-
|
|
396
335
|
return {
|
|
397
336
|
isTruncated: truncated,
|
|
398
337
|
text: truncatedText,
|
|
@@ -404,8 +343,6 @@ class Truncator {
|
|
|
404
343
|
}
|
|
405
344
|
};
|
|
406
345
|
}
|
|
407
|
-
|
|
408
346
|
}
|
|
409
|
-
|
|
410
347
|
var _default2 = truncate;
|
|
411
348
|
exports.default = _default2;
|
package/lib/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instructure/ui-truncate-text",
|
|
3
|
-
"version": "8.33.
|
|
3
|
+
"version": "8.33.2-snapshot-5",
|
|
4
4
|
"description": "A TruncateText component made by Instructure Inc.",
|
|
5
5
|
"author": "Instructure, Inc. Engineering and Product Design",
|
|
6
6
|
"module": "./es/index.js",
|
|
@@ -24,23 +24,23 @@
|
|
|
24
24
|
"license": "MIT",
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@babel/runtime": "^7.13.10",
|
|
27
|
-
"@instructure/console": "8.33.
|
|
28
|
-
"@instructure/debounce": "8.33.
|
|
29
|
-
"@instructure/emotion": "8.33.
|
|
30
|
-
"@instructure/shared-types": "8.33.
|
|
31
|
-
"@instructure/ui-dom-utils": "8.33.
|
|
32
|
-
"@instructure/ui-react-utils": "8.33.
|
|
33
|
-
"@instructure/ui-testable": "8.33.
|
|
34
|
-
"@instructure/ui-utils": "8.33.
|
|
27
|
+
"@instructure/console": "8.33.2-snapshot-5",
|
|
28
|
+
"@instructure/debounce": "8.33.2-snapshot-5",
|
|
29
|
+
"@instructure/emotion": "8.33.2-snapshot-5",
|
|
30
|
+
"@instructure/shared-types": "8.33.2-snapshot-5",
|
|
31
|
+
"@instructure/ui-dom-utils": "8.33.2-snapshot-5",
|
|
32
|
+
"@instructure/ui-react-utils": "8.33.2-snapshot-5",
|
|
33
|
+
"@instructure/ui-testable": "8.33.2-snapshot-5",
|
|
34
|
+
"@instructure/ui-utils": "8.33.2-snapshot-5",
|
|
35
35
|
"escape-html": "^1",
|
|
36
36
|
"prop-types": "^15"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@instructure/ui-babel-preset": "8.33.
|
|
40
|
-
"@instructure/ui-color-utils": "8.33.
|
|
41
|
-
"@instructure/ui-test-utils": "8.33.
|
|
42
|
-
"@instructure/ui-text": "8.33.
|
|
43
|
-
"@instructure/ui-themes": "8.33.
|
|
39
|
+
"@instructure/ui-babel-preset": "8.33.2-snapshot-5",
|
|
40
|
+
"@instructure/ui-color-utils": "8.33.2-snapshot-5",
|
|
41
|
+
"@instructure/ui-test-utils": "8.33.2-snapshot-5",
|
|
42
|
+
"@instructure/ui-text": "8.33.2-snapshot-5",
|
|
43
|
+
"@instructure/ui-themes": "8.33.2-snapshot-5",
|
|
44
44
|
"@types/escape-html": "^1"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|