@hsds/utils-strings
Advanced tools
Comparing version 8.1.0 to 8.1.1
@@ -5,2 +5,9 @@ # Changelog | ||
## [8.1.1](https://github.com/helpscout/hsds/compare/utils-strings-8.1.0...utils-strings-8.1.1) (2023-10-23) | ||
### Bug Fixes | ||
* **workspace:** updates babelize target ([d5c720e](https://github.com/helpscout/hsds/commit/d5c720ea4da26f3c5d55ac0c6acc508722716c7c)) | ||
## [8.1.0](https://github.com/helpscout/hsds/compare/utils-strings-8.0.0...utils-strings-8.1.0) (2023-10-23) | ||
@@ -7,0 +14,0 @@ |
222
index.cjs.js
@@ -1,215 +0,9 @@ | ||
'use strict'; | ||
"use strict"; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
const normalizeUrl = string => { | ||
if (string == null) { | ||
return ''; | ||
} | ||
let url = string; | ||
if (url.search(/^http[s]?:\/\//) === -1) { | ||
url = `http://${url}`; | ||
} | ||
return url; | ||
}; | ||
const newlineToHTML = string => { | ||
if (!string) { | ||
return ''; | ||
} | ||
return string.trim().replace(/\r?\n/g, '<br>'); | ||
}; | ||
// Taken from the React escapeTextForBrowser internal utility | ||
const escapeHtmlRegExp = /["'&<>]/; | ||
/** | ||
* Escape HTML special characters in the string for output in the browser. | ||
* | ||
* @param {string} string | ||
* @returns {string} | ||
*/ | ||
const escapeHTML = string => { | ||
if (!string) { | ||
return ''; | ||
} | ||
const match = escapeHtmlRegExp.exec(string); | ||
if (!match) { | ||
return string; | ||
} | ||
let escape; | ||
let html = ''; | ||
let index; | ||
let lastIndex = 0; | ||
for (index = match.index; index < string.length; index++) { | ||
switch (string.charCodeAt(index)) { | ||
case 34: | ||
// " | ||
escape = '"'; | ||
break; | ||
case 38: | ||
// & | ||
escape = '&'; | ||
break; | ||
case 39: | ||
// ' | ||
escape = '''; | ||
break; | ||
case 60: | ||
// < | ||
escape = '<'; | ||
break; | ||
case 62: | ||
// > | ||
escape = '>'; | ||
break; | ||
default: | ||
continue; | ||
} | ||
if (lastIndex !== index) { | ||
html += string.substring(lastIndex, index); | ||
} | ||
lastIndex = index + 1; | ||
html += escape; | ||
} | ||
return lastIndex !== index ? html + string.substring(lastIndex, index) : html; | ||
}; | ||
/** | ||
* The string form of a regular expression that would match all of the | ||
* letters, combining marks, and decimal number chars in the unicode character | ||
* set within a URL. | ||
*/ | ||
const alphaNumericAndMarksChars = 'a-z0-9\\-+&@#/%=~_'; | ||
/** | ||
* Partial regex pattern to match the TLD of a domain. | ||
* | ||
* Maximum length for a TLD is currently 24 characters. | ||
* See: as shown in http://data.iana.org/TLD/tlds-alpha-by-domain.txt | ||
*/ | ||
const tldPattern = '[a-z]{2,24}'; | ||
/** | ||
* Partial regex pattern to match the domain part of a URL without the subdomain. | ||
*/ | ||
const domainPattern = '[a-z0-9-]+\\.' + tldPattern; | ||
/** | ||
* Partial regex pattern to match the path of a URL. | ||
*/ | ||
const pathPattern = '(?:[/?#](?:[' + alphaNumericAndMarksChars + "\\(\\)|'$*\\[\\]?!:,.;]*[" + alphaNumericAndMarksChars + "|'$*\\[\\]])?)?)"; | ||
/** | ||
* Regex pattern to match a complete URL. | ||
*/ | ||
const urlPattern = '(?:(?:(?:https?:\\/\\/(?:[a-z0-9-]+\\.)*)|(?:[a-z0-9-]+\\.)+)?' + domainPattern + pathPattern; | ||
/** | ||
* Regex pattern to match an email address. | ||
*/ | ||
const emailPattern = "(?:\\b[a-z0-9._'%+-]+@[a-z0-9.-]+\\." + tldPattern + ')'; | ||
/** | ||
* @param {string} string | ||
* | ||
* @returns {string} | ||
*/ | ||
const convertLinksToHTML = string => { | ||
if (!string) { | ||
return ''; | ||
} | ||
return string.split(new RegExp(`(${urlPattern}|${emailPattern})`, 'gi')).reduce((accumulator, value, index) => { | ||
if (index % 2) { | ||
if (value.match(new RegExp(`^${emailPattern}$`, 'i'))) { | ||
// Matched an email | ||
return accumulator + `<a href="mailto:${escapeHTML(value)}">${escapeHTML(value)}</a>`; | ||
} | ||
// Matched a URL | ||
let url = value; | ||
if (url.match(new RegExp(`^${domainPattern}$`, 'i'))) { | ||
// Only matched a domain name (without subdomain) | ||
// Skip this as it could be the end/start of a sentence without whitespace. | ||
// For example with "Hello Tom.how are you?" we should not match "Tom.how" | ||
return accumulator + url; | ||
} | ||
// Add http as the default scheme if needed | ||
url = normalizeUrl(url); | ||
// Adding target blank and rel noopener for external links | ||
// See: https://developers.google.com/web/tools/lighthouse/audits/noopener | ||
return accumulator + `<a href="${escapeHTML(url)}" target="_blank" rel="noopener">${escapeHTML(value)}</a>`; | ||
} | ||
return accumulator + escapeHTML(value); | ||
}, ''); | ||
}; | ||
/** | ||
* Camelcases a specified string. | ||
* | ||
* @param {string} string The string. | ||
* @returns {string} The camelCased string. | ||
*/ | ||
function camelCase(string) { | ||
return string.replace(/-/g, ' ').replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, (match, index) => { | ||
if (+match === 0) return ''; // or if (/\s+/.test(match)) for white spaces | ||
return index === 0 ? match.toLowerCase() : match.toUpperCase(); | ||
}); | ||
} | ||
/** | ||
* @license | ||
* Copyright Google Inc. All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
const STRING_DASHERIZE_REGEXP = /[ _.]/g; | ||
const STRING_DECAMELIZE_REGEXP = /([a-z\d])([A-Z])/g; | ||
/** | ||
* Converts a camelized string into all lower case separated by underscores. | ||
* | ||
```javascript | ||
decamelize('innerHTML'); // 'inner_html' | ||
decamelize('action_name'); // 'action_name' | ||
decamelize('css-class-name'); // 'css-class-name' | ||
decamelize('my favorite items'); // 'my favorite items' | ||
``` | ||
@method decamelize | ||
@param {String} str The string to decamelize. | ||
@return {String} the decamelized string. | ||
*/ | ||
function decamelize(str) { | ||
return str.replace(STRING_DECAMELIZE_REGEXP, '$1_$2').toLowerCase(); | ||
} | ||
/** | ||
Replaces underscores, spaces, periods, or camelCase with dashes. | ||
```javascript | ||
dasherize('innerHTML'); // 'inner-html' | ||
dasherize('action_name'); // 'action-name' | ||
dasherize('css-class-name'); // 'css-class-name' | ||
dasherize('my favorite items'); // 'my-favorite-items' | ||
dasherize('nrwl.io'); // 'nrwl-io' | ||
``` | ||
@method dasherize | ||
@param {String} str The string to dasherize. | ||
@return {String} the dasherized string. | ||
*/ | ||
function dasherize(str) { | ||
return decamelize(str || '').replace(STRING_DASHERIZE_REGEXP, '-'); | ||
} | ||
exports.camelCase = camelCase; | ||
exports.convertLinksToHTML = convertLinksToHTML; | ||
exports.dasherize = dasherize; | ||
exports.decamelize = decamelize; | ||
exports.escapeHTML = escapeHTML; | ||
exports.newlineToHTML = newlineToHTML; | ||
exports.normalizeUrl = normalizeUrl; | ||
exports.__esModule = true; | ||
var _strings = require("./strings"); | ||
Object.keys(_strings).forEach(function (key) { | ||
if (key === "default" || key === "__esModule") return; | ||
if (key in exports && exports[key] === _strings[key]) return; | ||
exports[key] = _strings[key]; | ||
}); |
{ | ||
"name": "@hsds/utils-strings", | ||
"version": "8.1.0", | ||
"version": "8.1.1", | ||
"main": "./index.cjs.js", | ||
"type": "commonjs" | ||
} |
18301
6
398