@getflip/swirl-components 0.107.0 → 0.108.0

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.
Files changed (40) hide show
  1. package/components.json +19 -9
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/swirl-components.cjs.js +1 -1
  4. package/dist/cjs/swirl-heading.cjs.entry.js +3 -15
  5. package/dist/cjs/swirl-popover_2.cjs.entry.js +4 -2
  6. package/dist/cjs/swirl-text.cjs.entry.js +765 -8
  7. package/dist/collection/components/swirl-heading/swirl-heading.css +4 -0
  8. package/dist/collection/components/swirl-heading/swirl-heading.js +2 -23
  9. package/dist/collection/components/swirl-heading/swirl-heading.spec.js +2 -2
  10. package/dist/collection/components/swirl-popover/swirl-popover.js +22 -2
  11. package/dist/collection/components/swirl-popover/swirl-popover.stories.js +3 -0
  12. package/dist/collection/components/swirl-resource-list-item/swirl-resource-list-item.stories.js +1 -0
  13. package/dist/collection/components/swirl-search/swirl-search.stories.js +0 -3
  14. package/dist/collection/components/swirl-theme-provider/swirl-theme-provider.stories.js +0 -3
  15. package/dist/collection/components/swirl-time-input/swirl-time-input.stories.js +0 -3
  16. package/dist/components/swirl-heading2.js +4 -16
  17. package/dist/components/swirl-popover2.js +5 -2
  18. package/dist/components/swirl-text2.js +759 -2
  19. package/dist/esm/loader.js +1 -1
  20. package/dist/esm/swirl-components.js +1 -1
  21. package/dist/esm/swirl-heading.entry.js +3 -15
  22. package/dist/esm/swirl-popover_2.entry.js +4 -2
  23. package/dist/esm/swirl-text.entry.js +759 -2
  24. package/dist/swirl-components/p-39cf2a0f.entry.js +8 -0
  25. package/dist/swirl-components/p-bff41b61.entry.js +1 -0
  26. package/dist/swirl-components/p-e2870d0c.entry.js +1 -0
  27. package/dist/swirl-components/swirl-components.esm.js +1 -1
  28. package/dist/types/components/swirl-heading/swirl-heading.d.ts +0 -4
  29. package/dist/types/components/swirl-popover/swirl-popover.d.ts +1 -0
  30. package/dist/types/components/swirl-popover/swirl-popover.stories.d.ts +3 -0
  31. package/dist/types/components.d.ts +2 -0
  32. package/package.json +2 -3
  33. package/vscode-data.json +4 -0
  34. package/dist/cjs/balancetext-562c7a48.js +0 -763
  35. package/dist/components/balancetext.js +0 -761
  36. package/dist/esm/balancetext-fa49c64f.js +0 -761
  37. package/dist/swirl-components/p-52282426.entry.js +0 -8
  38. package/dist/swirl-components/p-8d3d2f60.entry.js +0 -1
  39. package/dist/swirl-components/p-d7af31e3.entry.js +0 -1
  40. package/dist/swirl-components/p-f83a5757.js +0 -1
@@ -2,9 +2,766 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- const index = require('./index-506fe4ea.js');
6
- const index$1 = require('./index-2ddd0598.js');
7
- const balancetext = require('./balancetext-562c7a48.js');
5
+ const index$1 = require('./index-506fe4ea.js');
6
+ const index = require('./index-2ddd0598.js');
7
+
8
+ var balancetext = index.createCommonjsModule(function (module) {
9
+ /*
10
+ * Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
11
+ *
12
+ * Licensed under the Apache License, Version 2.0 (the "License");
13
+ * you may not use this file except in compliance with the License.
14
+ * You may obtain a copy of the License at
15
+ *
16
+ * http://www.apache.org/licenses/LICENSE-2.0
17
+ *
18
+ * Unless required by applicable law or agreed to in writing, software
19
+ * distributed under the License is distributed on an "AS IS" BASIS,
20
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
+ * See the License for the specific language governing permissions and
22
+ * limitations under the License. *
23
+ */
24
+ /**
25
+ * balancetext.js
26
+ *
27
+ * Author: Randy Edmunds
28
+ */
29
+
30
+ /* global define, module */
31
+
32
+ /*
33
+ * Copyright (c) 2007-2009 unscriptable.com and John M. Hann
34
+ *
35
+ * Permission is hereby granted, free of charge, to any person
36
+ * obtaining a copy of this software and associated documentation
37
+ * files (the “Software”), to deal in the Software without
38
+ * restriction, including without limitation the rights to use,
39
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
40
+ * copies of the Software, and to permit persons to whom the
41
+ * Software is furnished to do so, subject to the following
42
+ * conditions:
43
+ *
44
+ * The above copyright notice and this permission notice shall be
45
+ * included in all copies or substantial portions of the Software.
46
+ *
47
+ * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
48
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
49
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
50
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
51
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
52
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
53
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
54
+ * OTHER DEALINGS IN THE SOFTWARE.
55
+ *
56
+ * Except as contained in this notice, the name(s) of the above
57
+ * copyright holders (unscriptable.com and John M. Hann) shall not be
58
+ * used in advertising or otherwise to promote the sale, use or other
59
+ * dealings in this Software without prior written authorization.
60
+ *
61
+ * http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
62
+ *
63
+ * Tested to work on (lowest browser):
64
+ * - Sarari 4
65
+ * - Chrome 16
66
+ * - Firefox 10
67
+ * - IE 9
68
+ * - Edge 13
69
+ */
70
+
71
+ (function (root, factory) {
72
+ if (module.exports) {
73
+ module.exports = factory();
74
+ } else {
75
+ root.balanceText = factory();
76
+ }
77
+ }(index.commonjsGlobal, () => {
78
+ /**
79
+ * Line breaking global vars
80
+ */
81
+ let breakMatches, wsnwMatches, wsnwOffset;
82
+
83
+ /**
84
+ * Selectors and elements to watch;
85
+ * calling $.balanceText(elements) adds "elements" to this list.
86
+ */
87
+ const watching = {
88
+ sel: [], // default class to watch
89
+ el: [],
90
+ };
91
+
92
+ /**
93
+ * Have handlers been initialized?
94
+ */
95
+ let handlersInitialized = false;
96
+
97
+ /**
98
+ * Is this a polyfill?
99
+ */
100
+ let polyfilled = false;
101
+
102
+
103
+ /**
104
+ * Do nothing
105
+ */
106
+ function noop() { }
107
+
108
+ /**
109
+ * Loop that works with array-likes
110
+ * @param {Array-like} elements - List of elements to run a function on
111
+ * @param {Function} callback - The function to call on each supplied element
112
+ */
113
+ function forEach(elements, callback) {
114
+ Array.prototype.forEach.call(elements, callback);
115
+ }
116
+
117
+ /**
118
+ * Polyfill for $(document).ready()
119
+ *
120
+ * @param {Function} fn - The function to execute when the document is ready
121
+ */
122
+ function ready(fn) {
123
+ if (document.readyState !== "loading") {
124
+ fn();
125
+ } else if (document.addEventListener) {
126
+ document.addEventListener("DOMContentLoaded", fn);
127
+ } else {
128
+ document.attachEvent("onreadystatechange", () => {
129
+ if (document.readyState !== "loading") {
130
+ fn();
131
+ }
132
+ });
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Debounces a function over a threshold
138
+ *
139
+ * @param {Function} func - The function to debounce
140
+ * @param {number} threshold - time in ms
141
+ * @param {boolean} execAsap - when true, execute immediately
142
+ * @param args
143
+ * @return {Function} Debounced function
144
+ */
145
+ function debounce(func, threshold, execAsap, ...args) {
146
+ let timeout;
147
+
148
+ return function () {
149
+ const obj = this;
150
+
151
+ function delayed() {
152
+ if (!execAsap) {
153
+ func.apply(obj, args);
154
+ }
155
+ timeout = null;
156
+ }
157
+
158
+ if (timeout) {
159
+ clearTimeout(timeout);
160
+ } else if (execAsap) {
161
+ func.apply(obj, args);
162
+ }
163
+ timeout = setTimeout(delayed, threshold || 100);
164
+ };
165
+ }
166
+
167
+ /**
168
+ * Determine whether the document supports TextWrap
169
+ * @return {boolean}
170
+ */
171
+ function hasTextWrap() {
172
+ if (typeof window === "undefined") {
173
+ return false;
174
+ }
175
+ const { style } = document.documentElement;
176
+ return style.textWrap || style.WebkitTextWrap || style.MozTextWrap || style.MsTextWrap;
177
+ }
178
+
179
+ /**
180
+ * Object for tracking next whitespace params
181
+ */
182
+ // eslint-disable-next-line camelcase
183
+ function NextWS_params() {
184
+ this.reset();
185
+ }
186
+
187
+ NextWS_params.prototype.reset = function () {
188
+ this.index = 0;
189
+ this.width = 0;
190
+ };
191
+
192
+ /**
193
+ * Check if index is contained in previously calculated list of white-space:nowrap ranges
194
+ *
195
+ * @param {number} index - the index of the character to check
196
+ * @return {boolean}
197
+ */
198
+ function isWhiteSpaceNoWrap(index) {
199
+ // Is index inside 1 of the ranges?
200
+ // start and end are breakable, but not inside range
201
+ return wsnwMatches.some(range => (range.start < index && index < range.end));
202
+ }
203
+
204
+ /**
205
+ * Recursively calculate white-space:nowrap offsets for line.
206
+ *
207
+ * @param {Node} el - the element to act on
208
+ * @param {boolean} includeTag - include length of tag itself
209
+ */
210
+ function recursiveCalcNoWrapOffsetsForLine(el, includeTag) {
211
+ if (el.nodeType === el.ELEMENT_NODE) {
212
+ // Found an embedded tag
213
+ const style = window.getComputedStyle(el);
214
+ if (style.whiteSpace === "nowrap") {
215
+ // Tag with white-space:nowrap - add match, skip children
216
+ const len = el.outerHTML.length;
217
+ wsnwMatches.push({ start: wsnwOffset, end: wsnwOffset + len });
218
+ wsnwOffset += len;
219
+ } else {
220
+ // Tag without white-space:nowrap - recursively check children of tag
221
+ forEach(el.childNodes, (child) => {
222
+ recursiveCalcNoWrapOffsetsForLine(child, true);
223
+ });
224
+ if (includeTag) {
225
+ // Length of opening tag, attributes, and closing tag
226
+ wsnwOffset += (el.outerHTML.length - el.innerHTML.length);
227
+ }
228
+ }
229
+ } else if (el.nodeType === el.COMMENT_NODE) {
230
+ wsnwOffset += el.length + 7; // delimiter: <!-- -->
231
+ } else if (el.nodeType === el.PROCESSING_INSTRUCTION_NODE) {
232
+ wsnwOffset += el.length + 2; // delimiter: < >
233
+ } else {
234
+ // Text node: add length
235
+ wsnwOffset += el.length;
236
+ }
237
+ }
238
+
239
+ /**
240
+ * Calculate white-space:nowrap offsets for line.
241
+ *
242
+ * @param {Node} el - the element to act on
243
+ * @param {string} oldWS - "old" whitespace setting for temporarily resetting
244
+ * @param {number} lineCharOffset - char offset of current line from start of text
245
+ */
246
+ function calcNoWrapOffsetsForLine(el, oldWS, lineCharOffset) {
247
+ // For first line (lineCharOffset === 0), calculate start and end offsets for each
248
+ // white-space:nowrap element in the line.
249
+ if (lineCharOffset === 0) {
250
+ // Reset whiteSpace setting when breakMatches is being calculated
251
+ // so white-space:nowrap can be detected in text
252
+ el.style.whiteSpace = oldWS;
253
+
254
+ wsnwOffset = 0;
255
+ wsnwMatches = [];
256
+ recursiveCalcNoWrapOffsetsForLine(el, false);
257
+
258
+ // Restore temporary whitespace setting to recalc width
259
+ el.style.whiteSpace = "nowrap";
260
+ } else {
261
+ // For all other lines, update the offsets for current line
262
+ // 1. Ignore matches less than offset
263
+ // 2. Subtract offset from remaining matches
264
+ const newMatches = [];
265
+ wsnwMatches.forEach((match) => {
266
+ if (match.start > lineCharOffset) {
267
+ newMatches.push({ start: match.start - lineCharOffset, end: match.end - lineCharOffset });
268
+ }
269
+ });
270
+ wsnwMatches = newMatches;
271
+ }
272
+ }
273
+
274
+ /**
275
+ * Strip balance-text tags from an element inserted in previous run
276
+ *
277
+ * @param {Node} el - the element to act on
278
+ */
279
+ function removeTags(el) {
280
+ // Remove soft-hyphen breaks
281
+ let brs = el.querySelectorAll('br[data-owner="balance-text-hyphen"]');
282
+ forEach(brs, (br) => {
283
+ br.outerHTML = "";
284
+ });
285
+
286
+ // Replace other breaks with whitespace
287
+ brs = el.querySelectorAll('br[data-owner="balance-text"]');
288
+ forEach(brs, (br) => {
289
+ br.outerHTML = " ";
290
+ });
291
+
292
+ // Restore hyphens inserted for soft-hyphens
293
+ let spans = el.querySelectorAll('span[data-owner="balance-text-softhyphen"]');
294
+ if (spans.length > 0) {
295
+ forEach(spans, (span) => {
296
+ const textNode = document.createTextNode("\u00ad");
297
+ span.parentNode.insertBefore(textNode, span);
298
+ span.parentNode.removeChild(span);
299
+ });
300
+ }
301
+
302
+ // Remove spans inserted for justified text
303
+ spans = el.querySelectorAll('span[data-owner="balance-text-justify"]');
304
+ if (spans.length > 0) {
305
+ let txt = "";
306
+ forEach(spans, (span) => {
307
+ txt += span.textContent;
308
+ span.parentNode.removeChild(span);
309
+ });
310
+ el.innerHTML = txt;
311
+ }
312
+ }
313
+
314
+ /**
315
+ * Checks to see if we should justify the balanced text with the
316
+ * element based on the textAlign property in the computed CSS
317
+ *
318
+ * @param {Node} el - element to check
319
+ * @return {boolean}
320
+ */
321
+ const isJustified = function (el) {
322
+ const style = el.currentStyle || window.getComputedStyle(el, null);
323
+ return (style.textAlign === "justify");
324
+ };
325
+
326
+ /**
327
+ * Add whitespace after words in text to justify the string to
328
+ * the specified size.
329
+ * @param {Node} el - the element to justify
330
+ * @param {string} txt - text string
331
+ * @param {number} conWidth - container width
332
+ * @return {string} Justified text
333
+ */
334
+ function justify(el, txt, conWidth) {
335
+ txt = txt.trim();
336
+ const words = txt.split(" ").length;
337
+ txt = `${txt} `;
338
+
339
+ // if we don't have at least 2 words, no need to justify.
340
+ if (words < 2) {
341
+ return txt;
342
+ }
343
+
344
+ // Find width of text in the DOM
345
+ const tmp = document.createElement("span");
346
+ tmp.innerHTML = txt;
347
+ el.appendChild(tmp);
348
+ const size = tmp.offsetWidth;
349
+ tmp.parentNode.removeChild(tmp);
350
+
351
+ // Figure out our word spacing and return the element
352
+ const wordSpacing = Math.floor((conWidth - size) / (words - 1));
353
+ tmp.style.wordSpacing = `${wordSpacing}px`;
354
+ tmp.setAttribute("data-owner", "balance-text-justify");
355
+
356
+ const div = document.createElement("div");
357
+ div.appendChild(tmp);
358
+ return div.innerHTML;
359
+ }
360
+
361
+ /**
362
+ * Returns true iff char at index is a break char outside of HTML < > tags.
363
+ * Break char can be: whitespace (except non-breaking-space: u00a0),
364
+ * hypen, emdash (u2014), endash (u2013), or soft-hyphen (u00ad).
365
+ *
366
+ * @param {string} txt - the text to check
367
+ * @param {number} index - the index of the character to check
368
+ * @return {boolean}
369
+ */
370
+ function isBreakChar(txt, index) {
371
+ const re = /([^\S\u00a0]|-|\u2014|\u2013|\u00ad)(?![^<]*>)/g;
372
+ let match;
373
+
374
+ if (!breakMatches) {
375
+ // Only calc break matches once per line
376
+ breakMatches = [];
377
+ match = re.exec(txt);
378
+ while (match !== null) {
379
+ if (!isWhiteSpaceNoWrap(match.index)) {
380
+ breakMatches.push(match.index);
381
+ }
382
+ match = re.exec(txt);
383
+ }
384
+ }
385
+
386
+ return breakMatches.indexOf(index) !== -1;
387
+ }
388
+
389
+ /**
390
+ * In the current implementation, an index is a break
391
+ * opportunity in txt iff it is:
392
+ * - 0 or txt.length
393
+ * - index of a non-whitespace char immediately preceded by a
394
+ * whitespace, hyphen, soft-hyphen, em-dash, or en-dash char.
395
+ *
396
+ * Thus, it doesn't honour "white-space" or any other Unicode
397
+ * line-breaking classes.)
398
+ *
399
+ * @precondition 0 <= index && index <= txt.length
400
+ *
401
+ * @param {string} txt - the text to check
402
+ * @param {number} index - the index to check
403
+ * @return {boolean}
404
+ */
405
+ function isBreakOpportunity(txt, index) {
406
+ return ((index === 0) || (index === txt.length) ||
407
+ (isBreakChar(txt, index - 1) && !isBreakChar(txt, index)));
408
+ }
409
+
410
+ /**
411
+ * Finds the first break opportunity (@see isBreakOpportunity)
412
+ * in txt that's both after-or-equal-to index c in the direction dir
413
+ * and resulting in line width equal to or past clamp(desWidth,
414
+ * 0, conWidth) in direction dir. Sets ret.index and ret.width
415
+ * to the corresponding index and line width (from the start of
416
+ * txt to ret.index).
417
+ *
418
+ * @param {Node} el - element
419
+ * @param {string} txt - text string
420
+ * @param {number} conWidth - container width
421
+ * @param {number} desWidth - desired width
422
+ * @param {number} dir - direction (-1 or +1)
423
+ * @param {number} c - char index (0 <= c && c <= txt.length)
424
+ * @param {Object} ret - return {index: {number}, width: {number}} of previous/next break
425
+ */
426
+ function findBreakOpportunity(el, txt, conWidth, desWidth, dir, c, ret) {
427
+ let w;
428
+
429
+ if (txt && typeof txt === "string") {
430
+ for (;;) {
431
+ while (!isBreakOpportunity(txt, c)) {
432
+ c += dir;
433
+ }
434
+
435
+ el.innerHTML = txt.substr(0, c);
436
+ w = el.offsetWidth;
437
+
438
+ if (dir < 0) {
439
+ if ((w <= desWidth) || (w <= 0) || (c === 0)) {
440
+ break;
441
+ }
442
+ } else if ((desWidth <= w) || (conWidth <= w) || (c === txt.length)) {
443
+ break;
444
+ }
445
+
446
+ c += dir;
447
+ }
448
+ }
449
+ ret.index = c;
450
+ ret.width = w;
451
+ }
452
+
453
+ /**
454
+ * Detects the width of a non-breaking space character, given the height of
455
+ * the element with no-wrap applied.
456
+ *
457
+ * @param {Node} el - element
458
+ * @param {number} h - height
459
+ * @return {number}
460
+ */
461
+ function getSpaceWidth(el, h) {
462
+ const container = document.createElement("div");
463
+
464
+ container.style.display = "block";
465
+ container.style.position = "absolute";
466
+ container.style.bottom = 0;
467
+ container.style.right = 0;
468
+ container.style.width = 0;
469
+ container.style.height = 0;
470
+ container.style.margin = 0;
471
+ container.style.padding = 0;
472
+ container.style.visibility = "hidden";
473
+ container.style.overflow = "hidden";
474
+
475
+ const space = document.createElement("span");
476
+
477
+ space.style.fontSize = "2000px";
478
+ space.innerHTML = "&nbsp;";
479
+
480
+ container.appendChild(space);
481
+
482
+ el.appendChild(container);
483
+
484
+ const dims = space.getBoundingClientRect();
485
+ container.parentNode.removeChild(container);
486
+
487
+ const spaceRatio = dims.height / dims.width;
488
+
489
+ return (h / spaceRatio);
490
+ }
491
+
492
+ /**
493
+ * Get a list of elements regardless of input
494
+ *
495
+ * @param {string|Node|Array-like} elements - The selector to query, one or more elements
496
+ * @return {Array<{Node}>}
497
+ */
498
+ function getElementsList(elements) {
499
+ if (!elements) {
500
+ return [];
501
+ }
502
+
503
+ // is selector
504
+ if (typeof elements === "string") {
505
+ return document.querySelectorAll(elements);
506
+ }
507
+
508
+ // is single element
509
+ if (elements.tagName && elements.querySelectorAll) {
510
+ return [elements];
511
+ }
512
+
513
+ return elements;
514
+ }
515
+
516
+ /**
517
+ * When a browser has native support for the text-wrap property,
518
+ * the text balanceText plugin will let the browser handle it natively,
519
+ * otherwise it will apply its own text balancing code.
520
+ *
521
+ * @param {string|Node|Array-like} elements - the list of elements to balance
522
+ */
523
+ function balanceText(elements) {
524
+ forEach(getElementsList(elements), (el) => {
525
+ // In a lower level language, this algorithm takes time
526
+ // comparable to normal text layout other than the fact
527
+ // that we do two passes instead of one, so we should
528
+ // be able to do without this limit.
529
+ const maxTextWidth = 5000;
530
+
531
+ // strip balance-text generated tags
532
+ removeTags(el);
533
+
534
+ // save settings
535
+ const oldWS = el.style.whiteSpace;
536
+ const oldFloat = el.style.float;
537
+ const oldDisplay = el.style.display;
538
+ const oldPosition = el.style.position;
539
+ const oldLH = el.style.lineHeight;
540
+
541
+ // remove line height before measuring container size
542
+ el.style.lineHeight = "normal";
543
+
544
+ const containerWidth = el.offsetWidth;
545
+ const containerHeight = el.offsetHeight;
546
+
547
+ // temporary settings
548
+ el.style.whiteSpace = "nowrap";
549
+ el.style.float = "none";
550
+ el.style.display = "inline";
551
+ el.style.position = "static";
552
+
553
+ let nowrapWidth = el.offsetWidth;
554
+ const nowrapHeight = el.offsetHeight;
555
+
556
+ // An estimate of the average line width reduction due
557
+ // to trimming trailing space that we expect over all
558
+ // lines other than the last.
559
+ const spaceWidth = ((oldWS === "pre-wrap") ? 0 : getSpaceWidth(el, nowrapHeight));
560
+
561
+ if (containerWidth > 0 && // prevent divide by zero
562
+ nowrapWidth > containerWidth && // text is more than 1 line
563
+ nowrapWidth < maxTextWidth) { // text is less than arbitrary limit (make this a param?)
564
+ let remainingText = el.innerHTML;
565
+ let newText = "";
566
+ let lineText = "";
567
+ const shouldJustify = isJustified(el);
568
+ const totLines = Math.round(containerHeight / nowrapHeight);
569
+ let remLines = totLines;
570
+ let lineCharOffset = 0;
571
+
572
+ // loop vars
573
+ let desiredWidth, guessIndex, le, ge, splitIndex, isHyphen, isSoftHyphen;
574
+
575
+ // Determine where to break:
576
+ while (remLines > 1) {
577
+ // clear whitespace match cache for each line
578
+ breakMatches = null;
579
+
580
+ // Must calc white-space:nowrap offsets before first call to findBreakOpportunity()
581
+ calcNoWrapOffsetsForLine(el, oldWS, lineCharOffset);
582
+
583
+ desiredWidth = Math.round((nowrapWidth + spaceWidth) / remLines - spaceWidth);
584
+
585
+ // Guessed char index
586
+ guessIndex = Math.round((remainingText.length + 1) / remLines) - 1;
587
+
588
+ le = new NextWS_params();
589
+
590
+ // Find a breaking space somewhere before (or equal to) desired width,
591
+ // not necessarily the closest to the desired width.
592
+ findBreakOpportunity(el, remainingText, containerWidth, desiredWidth, -1, guessIndex, le);
593
+
594
+ // Find first breaking char after (or equal to) desired width.
595
+ ge = new NextWS_params();
596
+ guessIndex = le.index;
597
+ findBreakOpportunity(el, remainingText, containerWidth, desiredWidth, +1, guessIndex, ge);
598
+
599
+ // Find first breaking char before (or equal to) desired width.
600
+ le.reset();
601
+ guessIndex = ge.index;
602
+ findBreakOpportunity(el, remainingText, containerWidth, desiredWidth, -1, guessIndex, le);
603
+
604
+ // Find closest string to desired length
605
+ if (le.index === 0) {
606
+ splitIndex = ge.index;
607
+ } else if ((containerWidth < ge.width) || (le.index === ge.index)) {
608
+ splitIndex = le.index;
609
+ } else {
610
+ splitIndex = ((Math.abs(desiredWidth - le.width) < Math.abs(ge.width - desiredWidth))
611
+ ? le.index
612
+ : ge.index);
613
+ }
614
+
615
+ // Break string
616
+ lineText = remainingText.substr(0, splitIndex).replace(/\s$/, "");
617
+
618
+ isSoftHyphen = Boolean(lineText.match(/\u00ad$/));
619
+ if (isSoftHyphen) {
620
+ // Replace soft-hyphen causing break with explicit hyphen
621
+ lineText = lineText.replace(/\u00ad$/, '<span data-owner="balance-text-softhyphen">-</span>');
622
+ }
623
+
624
+ if (shouldJustify) {
625
+ newText += justify(el, lineText, containerWidth);
626
+ } else {
627
+ newText += lineText;
628
+ isHyphen = isSoftHyphen || Boolean(lineText.match(/(-|\u2014|\u2013)$/));
629
+ newText += isHyphen ? '<br data-owner="balance-text-hyphen" />'
630
+ : '<br data-owner="balance-text" aria-hidden="true" />';
631
+ }
632
+ remainingText = remainingText.substr(splitIndex);
633
+ lineCharOffset = splitIndex;
634
+
635
+ // update counters
636
+ remLines--;
637
+ el.innerHTML = remainingText;
638
+ nowrapWidth = el.offsetWidth;
639
+ }
640
+
641
+ if (shouldJustify) {
642
+ el.innerHTML = newText + justify(el, remainingText, containerWidth);
643
+ } else {
644
+ el.innerHTML = newText + remainingText;
645
+ }
646
+ }
647
+
648
+ // restore settings
649
+ el.style.whiteSpace = oldWS;
650
+ el.style.float = oldFloat;
651
+ el.style.display = oldDisplay;
652
+ el.style.position = oldPosition;
653
+ el.style.lineHeight = oldLH;
654
+ });
655
+ }
656
+
657
+ /**
658
+ * Call the balanceText plugin on elements that it's watching.
659
+ */
660
+ function updateWatched() {
661
+ const selectors = watching.sel.join(",");
662
+ const selectedElements = getElementsList(selectors);
663
+ const elements = Array.prototype.concat.apply(watching.el, selectedElements);
664
+ balanceText(elements);
665
+ }
666
+
667
+ /**
668
+ * Initialize the events for which to re-apply BalanceText. They are:
669
+ * - Document ready
670
+ * - Document full load
671
+ * - Window resize
672
+ */
673
+ function initHandlers() {
674
+ if (handlersInitialized) {
675
+ return;
676
+ }
677
+
678
+ // Apply on DOM ready
679
+ ready(updateWatched);
680
+
681
+ // Reapply on full load
682
+ window.addEventListener("load", updateWatched);
683
+
684
+ // Reapply on resize
685
+ window.addEventListener("resize", debounce(updateWatched));
686
+
687
+ handlersInitialized = true;
688
+ }
689
+
690
+ /**
691
+ * Apply the BalanceText routine on the document and watch the list
692
+ * of elements. On window resize, re-apply BalanceText to the given elements
693
+ *
694
+ * @param {string|Node|Array-like} elements - the elements to watch after applying BalanceText
695
+ */
696
+ function balanceTextAndWatch(elements) {
697
+ if (typeof elements === "string") {
698
+ watching.sel.push(elements);
699
+ } else {
700
+ forEach(getElementsList(elements), (el) => {
701
+ watching.el.push(el);
702
+ });
703
+ }
704
+
705
+ initHandlers();
706
+ updateWatched();
707
+ }
708
+
709
+ /**
710
+ * Stop watching elements
711
+ *
712
+ * @param {string|Node|Array-like} elements
713
+ */
714
+ function unwatch(elements) {
715
+ if (typeof elements === "string") {
716
+ watching.sel = watching.sel.filter(el => el !== elements);
717
+ } else {
718
+ elements = getElementsList(elements);
719
+ watching.el = watching.el.filter(el => elements.indexOf(el) === -1);
720
+ }
721
+ }
722
+
723
+ /**
724
+ * Treat this app as a polyfill. Watch for changes to the .balance-text selector
725
+ */
726
+ function polyfill() {
727
+ if (polyfilled) {
728
+ return;
729
+ }
730
+
731
+ watching.sel.push(".balance-text");
732
+ initHandlers();
733
+ polyfilled = true;
734
+ }
735
+
736
+ /**
737
+ * Public interface
738
+ *
739
+ * @param {string|Node|Array-like} elements - elements to balance
740
+ * @param {Object} options - processing options
741
+ * - {boolean} watch - watch elements for resize
742
+ */
743
+ function publicInterface(elements, options) {
744
+ if (!elements) {
745
+ // empty call means polyfill (watch for changes)
746
+ polyfill();
747
+ } else if (options && options.watch === true) {
748
+ balanceTextAndWatch(elements);
749
+ } else if (options && options.watch === false) {
750
+ unwatch(elements);
751
+ } else {
752
+ balanceText(elements);
753
+ }
754
+ }
755
+
756
+ publicInterface.updateWatched = updateWatched;
757
+
758
+ if (hasTextWrap()) {
759
+ noop.updateWatched = noop;
760
+ return noop;
761
+ }
762
+ return publicInterface;
763
+ }));
764
+ });
8
765
 
9
766
  /**
10
767
  shave - Shave is a javascript plugin that truncates multi-line text within a html element based on set max height
@@ -173,7 +930,7 @@ const swirlTextCss = ".sc-swirl-text-h{display:block;max-width:100%}.sc-swirl-te
173
930
 
174
931
  const SwirlText = class {
175
932
  constructor(hostRef) {
176
- index.registerInstance(this, hostRef);
933
+ index$1.registerInstance(this, hostRef);
177
934
  this.align = "start";
178
935
  this.as = "p";
179
936
  this.balance = undefined;
@@ -210,16 +967,16 @@ const SwirlText = class {
210
967
  if (!this.balance || !Boolean(this.textEl)) {
211
968
  return;
212
969
  }
213
- balancetext.balancetext(this.textEl);
970
+ balancetext(this.textEl);
214
971
  }
215
972
  render() {
216
973
  const Tag = this.as;
217
- const className = index$1.classnames("text", `text--align-${this.align}`, `text--color-${this.color}`, `text--font-family-${this.fontFamily}`, `text--font-style-${this.fontStyle}`, `text--size-${this.size}`, `text--truncate-direction-${this.truncateDirection}`, `text--weight-${this.weight}`, {
974
+ const className = index.classnames("text", `text--align-${this.align}`, `text--color-${this.color}`, `text--font-family-${this.fontFamily}`, `text--font-style-${this.fontStyle}`, `text--size-${this.size}`, `text--truncate-direction-${this.truncateDirection}`, `text--weight-${this.weight}`, {
218
975
  "text--truncate": this.truncate && (!Boolean(this.lines) || this.lines === 1),
219
976
  });
220
- return (index.h(index.Host, null, index.h(Tag, { class: className, ref: (el) => (this.textEl = el) }, index.h("slot", null))));
977
+ return (index$1.h(index$1.Host, null, index$1.h(Tag, { class: className, ref: (el) => (this.textEl = el) }, index$1.h("slot", null))));
221
978
  }
222
- get el() { return index.getElement(this); }
979
+ get el() { return index$1.getElement(this); }
223
980
  };
224
981
  SwirlText.style = swirlTextCss;
225
982