Last active
December 3, 2019 21:54
-
-
Save stedman/b49c280f4a200a1d75b72ffb4c066dd6 to your computer and use it in GitHub Desktop.
Insert optional HTML content break points to improve word wrap appearance.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* HTML content doesn't always break where we want it to--especially when long, | |
* unbroken strings are present. If we want HTML to optionally break at certain | |
* pre-determined points, we add <wbr> (word break oppportunity) tags. | |
* | |
* This utility adds <wbr> tags after a specified content length and character. | |
* | |
* For example, given the following string: | |
* https://github.com/stedman/long-hash/raw/file-name.js | |
* ...if we want to gracefully break after 30 characters and a forward slash (/), | |
* the HTML would need to look like: | |
* https://github.com/stedman/long-hash/<wbr>raw/<wbr>file-name.js | |
* | |
* Reference: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr | |
* | |
* @param {String} content Raw content to insert <wbr> into. | |
* @param {Object} options | |
* @param {Number} [options.cutLength=30] Length of content allowed before inserting <wbr>. | |
* @param {String} [options.cutChar='/'] Character(s) to insert <wbr> after. | |
* | |
* @return {String} Content with <wbr> tags added. | |
*/ | |
function breakSoftly(_content, _options) { | |
let content = _content || ''; | |
const options = _options || {}; | |
const cutLength = options.cutLength || 30; | |
const cutChar = options.cutChar || '/'; | |
// Exit if content isn't long enough. | |
if (content.length <= cutLength) { | |
return content.trim(); | |
} | |
// Use the cutLength as the loop starting point. | |
let index = cutLength; | |
// Loop over the character matches until none remain. | |
while ((index = content.indexOf(cutChar, index + 1)) !== -1) { | |
const lookbehind = content[index - 1]; | |
const lookahead = content[index + 1]; | |
// If there's a left bracket (the start of an HTML element), skip this replacement. | |
// If there's a leading or trailing space, skip replacement -- browsers already break on spaces. | |
if (lookbehind !== '<' && lookbehind !== ' ' && lookahead !== ' ') { | |
// Splice content together: | |
// 1) from the start to the point where the cutChar was found | |
// 2) the cutChar and inserted <wbr> tag | |
// 3) the rest of the original content following the cutChar | |
content = content.substring(0, index) + cutChar + '<wbr>' + content.substring(index + 1); | |
} | |
} | |
return content.trim(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
FWIW, the original regex replace took about twice as long to run as the while loop.