Comparing version 0.5.0 to 0.5.1
{ | ||
"name": "htmlfy", | ||
"version": "0.5.0", | ||
"version": "0.5.1", | ||
"description": "HTML formatter yo!. Prettify, minify, and more!", | ||
@@ -5,0 +5,0 @@ "exports": { |
@@ -9,3 +9,4 @@ # htmlfy | ||
- Added configuration options. | ||
- Refactored the code, including naming changes. | ||
- Lots of refactoring. | ||
- Improved some of the processing logic. | ||
@@ -128,5 +129,7 @@ ## Install | ||
{ | ||
ignore: {}, | ||
ignore: [], | ||
ignore_with: '_!i-£___£%_', | ||
strict: false, | ||
tab_size: 2 | ||
tab_size: 2, | ||
trim: [] | ||
} | ||
@@ -163,2 +166,9 @@ ``` | ||
### Ignore With | ||
You can pass in your own string, for ignoring elements, if the default is actually being used in your ignored elements. | ||
```js | ||
prettify(html, { ignore: [ 'p' ], ignore_with: 'some-string-that-wont-be-in-your-ignored-elements' }) | ||
``` | ||
### Strict | ||
@@ -181,3 +191,3 @@ If set to `true`, removes comments and ensures void elements are not self-closing. | ||
### Tab Size | ||
Determines the number of spaces, per tab, for indentation. | ||
Determines the number of spaces, per tab, for indentation. For sanity reasons, the valid range is between 1 and 16. | ||
@@ -199,3 +209,3 @@ ```js | ||
### Trim | ||
Trim leading and trailing whitespace from `textarea` elements, since all whitespace is preserved by default. | ||
Trim leading and trailing whitespace within `textarea` elements, since all whitespace is preserved by default. | ||
@@ -210,2 +220,2 @@ ```js | ||
> For compatibility and possible future expansion, we require declaring an array with the value 'textarea', as opposed to using something like `{ trim: true }`. Passing in additional HTML element values has no effect, since we already trim whitespace for all other elements. | ||
> For compatibility and possible future expansion, we require declaring an array with the value 'textarea', as opposed to using something like `{ trim: true }`. Passing in additional HTML element values has no real effect, since we already trim whitespace for all other elements. |
@@ -13,14 +13,12 @@ import { isHtml } from "./utils.js" | ||
* @param {string} html The HTML string to evaluate. | ||
* @param {boolean} html_check Check to see if the content contains any HTML, before processing. | ||
* @param {boolean} check_html Check to see if the content contains any HTML, before processing. | ||
* @returns {string} | ||
* @example <br> => <br /> | ||
*/ | ||
export const closify = (html, html_check = true) => { | ||
if (html_check) | ||
if (!isHtml(html)) return html | ||
export const closify = (html, check_html = true) => { | ||
if (check_html && !isHtml(html)) return html | ||
return html.replace(/<([a-zA-Z\-0-9]+)[^>]*>/g, (match, name) => { | ||
if (void_elements.indexOf(name) > -1) { | ||
if (void_elements.indexOf(name) > -1) | ||
return (`${match.substring(0, match.length - 1)} />`).replace(/\/\s\//g, '/') | ||
} | ||
@@ -27,0 +25,0 @@ return match.replace(/[\s]?\/>/g, `></${name}>`) |
@@ -6,2 +6,3 @@ /** | ||
ignore: [], | ||
ignore_with: '_!i-£___£%_', | ||
strict: false, | ||
@@ -8,0 +9,0 @@ tab_size: 2, |
@@ -9,8 +9,7 @@ import { entify } from "./entify.js" | ||
* @param {string} html The HTML string to minify. | ||
* @param {boolean} html_check Check to see if the content contains any HTML, before processing. | ||
* @param {boolean} check_html Check to see if the content contains any HTML, before processing. | ||
* @returns {string} A minified HTML string. | ||
*/ | ||
export const minify = (html, html_check = true) => { | ||
if (html_check) | ||
if (!isHtml(html)) return html | ||
export const minify = (html, check_html = true) => { | ||
if (check_html && !isHtml(html)) return html | ||
@@ -17,0 +16,0 @@ /** |
import { closify } from './closify.js' | ||
import { minify } from './minify.js' | ||
import { ignoreElement, isHtml, trimify, validateConfig } from './utils.js' | ||
import { isHtml, setIgnoreElement, trimify, unsetIgnoreElement, validateConfig } from './utils.js' | ||
import { CONFIG } from './constants.js' | ||
@@ -56,4 +56,3 @@ | ||
if (trim.length > 0) | ||
html = trimify(html, trim) | ||
if (trim.length > 0) html = trimify(html, trim) | ||
@@ -126,3 +125,4 @@ html = minify(html, false) | ||
/* Remove line returns, tabs, and consecutive spaces within html elements or their content. */ | ||
html = html.replace(/>[^<]*?[^><\/\s][^<]*?<\/|>\s+[^><\s]|<script[^>]*>\s+<\/script>|<(\w+)>\s+<\/(\w+)|<([\w\-]+)[^>]*[^\/]>\s+<\/([\w\-]+)>/g, | ||
html = html.replace( | ||
/>[^<]*?[^><\/\s][^<]*?<\/|>\s+[^><\s]|<script[^>]*>\s+<\/script>|<(\w+)>\s+<\/(\w+)|<([\w\-]+)[^>]*[^\/]>\s+<\/([\w\-]+)>/g, | ||
match => match.replace(/\n|\t|\s{2,}/g, '') | ||
@@ -164,6 +164,4 @@ ) | ||
/* Protect ignored elements. */ | ||
if (ignore) { | ||
html = ignoreElement(html, validated_config.ignore) | ||
} | ||
/* Preserve ignored elements. */ | ||
if (ignore) html = setIgnoreElement(html, validated_config) | ||
@@ -173,8 +171,6 @@ html = preprocess(html) | ||
/* Unprotect ignored elements. */ | ||
if (ignore) { | ||
html = ignoreElement(html, validated_config.ignore, 'unprotect') | ||
} | ||
/* Revert ignored elements. */ | ||
if (ignore) html = unsetIgnoreElement(html, validated_config) | ||
return html | ||
} |
export interface DefaultConfig { | ||
ignore: string[]; | ||
ignore_with: string; | ||
strict: boolean; | ||
@@ -4,0 +5,0 @@ tab_size: number; |
@@ -9,6 +9,3 @@ import { CONFIG } from './constants.js' | ||
*/ | ||
export const isHtml = (content) => { | ||
const regex = /<(?<Element>[A-Za-z]+\b)[^>]*(?:.|\n)*?<\/{1}\k<Element>>/ | ||
return regex.test(content) | ||
} | ||
export const isHtml = (content) => /<(?<Element>[A-Za-z]+\b)[^>]*(?:.|\n)*?<\/{1}\k<Element>>/.test(content) | ||
@@ -24,3 +21,3 @@ /** | ||
if (!current || !updates) | ||
throw new Error("Both 'current' and 'updates' must be passed-in to merge()") | ||
throw new Error("Both 'current' and 'updates' must be passed-in to mergeObjects()") | ||
@@ -65,15 +62,27 @@ /** | ||
/** | ||
* Ignores elements by protecting or unprotecting their entities. | ||
* Replace entities with ignore string. | ||
* | ||
* @param {string} html | ||
* @param {string[]} ignore | ||
* @param {string} [mode] | ||
* @param {import('htmlfy').Config} config | ||
* @returns {string} | ||
*/ | ||
export const ignoreElement = (html, ignore, mode = 'protect') => { | ||
export const setIgnoreElement = (html, config) => { | ||
const ignore = config.ignore | ||
const ignore_string = config.ignore_with | ||
for (let e = 0; e < ignore.length; e++) { | ||
const regex = new RegExp(`<${ignore[e]}[^>]*>((.|\n)*?)<\/${ignore[e]}>`, "g") | ||
html = html.replace(regex, mode === 'protect' ? protectElement : unprotectElement) | ||
html = html.replace(regex, (/** @type {string} */match, /** @type {any} */capture) => { | ||
return match.replace(capture, (match) => { | ||
return match | ||
.replace(/</g, '-' + ignore_string + 'lt-') | ||
.replace(/>/g, '-' + ignore_string + 'gt-') | ||
.replace(/\n/g, '-' + ignore_string + 'nl-') | ||
.replace(/\r/g, '-' + ignore_string + 'cr-') | ||
.replace(/\s/g, '-' + ignore_string + 'ws-') | ||
}) | ||
}) | ||
} | ||
return html | ||
@@ -83,20 +92,2 @@ } | ||
/** | ||
* Protect an element by inserting entities. | ||
* | ||
* @param {string} match | ||
* @param {any} capture | ||
* @returns | ||
*/ | ||
const protectElement = (match, capture) => { | ||
return match.replace(capture, (match) => { | ||
return match | ||
.replace(/</g, '<') | ||
.replace(/>/g, '>') | ||
.replace(/\n/g, ' ') | ||
.replace(/\r/g, ' ') | ||
.replace(/\s/g, ' ') | ||
}) | ||
} | ||
/** | ||
* Trim leading and trailing whitespace characters. | ||
@@ -123,17 +114,28 @@ * | ||
/** | ||
* Unprotect an element by removing entities. | ||
* Replace ignore string with entities. | ||
* | ||
* @param {string} match | ||
* @param {any} capture | ||
* @returns | ||
* @param {string} html | ||
* @param {import('htmlfy').Config} config | ||
* @returns {string} | ||
*/ | ||
const unprotectElement = (match, capture) => { | ||
return match.replace(capture, (match) => { | ||
return match | ||
.replace(/</g, '<') | ||
.replace(/>/g, '>') | ||
.replace(/ /g, '\n') | ||
.replace(/ /g, '\r') | ||
.replace(/ /g, ' ') | ||
}) | ||
export const unsetIgnoreElement = (html, config) => { | ||
const ignore = config.ignore | ||
const ignore_string = config.ignore_with | ||
for (let e = 0; e < ignore.length; e++) { | ||
const regex = new RegExp(`<${ignore[e]}[^>]*>((.|\n)*?)<\/${ignore[e]}>`, "g") | ||
html = html.replace(regex, (/** @type {string} */match, /** @type {any} */capture) => { | ||
return match.replace(capture, (match) => { | ||
return match | ||
.replace(new RegExp('-' + ignore_string + 'lt-', "g"), '<') | ||
.replace(new RegExp('-' + ignore_string + 'gt-', "g"), '>') | ||
.replace(new RegExp('-' + ignore_string + 'nl-', "g"), '\n') | ||
.replace(new RegExp('-' + ignore_string + 'cr-', "g"), '\r') | ||
.replace(new RegExp('-' + ignore_string + 'ws-', "g"), ' ') | ||
}) | ||
}) | ||
} | ||
return html | ||
} | ||
@@ -154,3 +156,5 @@ | ||
Object.hasOwn(config, 'ignore') || | ||
Object.hasOwn(config, 'trim')) | ||
Object.hasOwn(config, 'trim') || | ||
Object.hasOwn(config, 'ignore_with')) | ||
if (config_empty) return CONFIG | ||
@@ -162,2 +166,3 @@ | ||
if (typeof tab_size !== 'number') throw new Error('Tab size must be a number.') | ||
const safe = Number.isSafeInteger(tab_size) | ||
@@ -177,5 +182,10 @@ if (!safe) throw new Error(`Tab size ${tab_size} is not safe. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger for more info.`) | ||
if (Object.hasOwn(config, 'strict') && typeof config.strict !== 'boolean') | ||
throw new Error('Strict config must be a boolean.') | ||
throw new Error(`Strict config must be a boolean, not ${typeof config.strict}.`) | ||
if (Object.hasOwn(config, 'ignore') && (!Array.isArray(config.ignore) || !config.ignore?.every((e) => typeof e === 'string'))) | ||
throw new Error('Ignore config must be an array of strings.') | ||
if (Object.hasOwn(config, 'ignore_with') && typeof config.ignore_with !== 'string') | ||
throw new Error(`Ignore_with config must be a string, not ${typeof config.ignore_with}.`) | ||
if (Object.hasOwn(config, 'trim') && (!Array.isArray(config.trim) || !config.trim?.every((e) => typeof e === 'string'))) | ||
@@ -182,0 +192,0 @@ throw new Error('Trim config must be an array of strings.') |
declare module 'htmlfy' { | ||
export interface UserConfig { | ||
ignore?: string[]; | ||
ignore_with?: string; | ||
strict?: boolean; | ||
@@ -5,0 +6,0 @@ tab_size?: number; |
24890
216
483