@getflip/swirl-components 0.107.0 → 0.108.1

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