Skip to content

Commit

Permalink
refactor: remove attributes transformer
Browse files Browse the repository at this point in the history
  • Loading branch information
cossssmin committed Oct 10, 2022
1 parent 0b5b2cf commit 344b2b2
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 9 deletions.
52 changes: 45 additions & 7 deletions src/transformers/removeAttributes.js
@@ -1,18 +1,56 @@
const posthtml = require('posthtml')
const {get, merge} = require('lodash')
const removeAttributes = require('posthtml-remove-attributes')
const defaultConfig = require('../generators/posthtml/defaultConfig')

module.exports = async (html, config = {}, direct = false) => {
const attributes = direct ? (Array.isArray(config) ? [...config] : []) : get(config, 'removeAttributes', [])
const posthtmlOptions = merge(defaultConfig, get(config, 'build.posthtml.options', {}))

attributes.push({name: 'style'}, {name: 'class'})
attributes.push('style', 'class')

// Allow omitting `value` key when removing empty attributes
attributes.forEach(attr => {
attr.value = attr.value || ''
})
html = await posthtml([
removeAttributes(attributes, posthtmlOptions)
]).process(html, posthtmlOptions).then(result => result.html)

return posthtml([removeAttributes(attributes)]).process(html, posthtmlOptions).then(result => result.html)
return html
}

/**
* Remove empty attributes with PostHTML
*
* Condition 1:
* `boolean` is for attributes without ="" (respects `recognizeNoValueAttribute` in PostHTML)
* `''` if the attribute included ="", i.e. style=""
*
* Condition 2: attribute value is a string and matches the one on the node
*
* Condition 3: same as 2, but for regular expressions
*/
const removeAttributes = (attributes = {}, posthtmlOptions = {}) => tree => {
const process = node => {
const normalizedAttrs = attributes.map(attribute => {
return {
name: get(attribute, 'name', typeof attribute === 'string' ? attribute : false),
value: get(attribute, 'value', get(posthtmlOptions, 'recognizeNoValueAttributes', true))
}
})

if (node.attrs) {
normalizedAttrs.forEach(attr => {
const targetAttrValue = get(node.attrs, attr.name)

if (
typeof targetAttrValue === 'boolean' || targetAttrValue === '' ||
(typeof attr.value === 'string' && node.attrs[attr.name] === attr.value) ||
(attr.value instanceof RegExp && attr.value.test(node.attrs[attr.name]))
) {
node.attrs[attr.name] = false
}
})
}

return node
}

return tree.walk(process)
}
11 changes: 9 additions & 2 deletions test/test-transformers.js
Expand Up @@ -163,9 +163,16 @@ test('remove unused CSS (disabled)', async t => {
})

test('remove attributes', async t => {
const html = await Maizzle.removeAttributes(`<div style="" role="article"></div>`, [{name: 'role', value: 'article'}])
const html = await Maizzle.removeAttributes(
`<div style="" remove keep role="article" delete-me="with-regex"></div>`,
[
{name: 'role', value: 'article'},
'remove',
{name: 'delete-me', value: /^with/}
]
)

t.is(html, '<div></div>')
t.is(html, '<div keep></div>')
})

test('extra attributes', async t => {
Expand Down

0 comments on commit 344b2b2

Please sign in to comment.