Skip to content

Commit 78851bd

Browse files
Add options for manage valid attributes
1 parent 9c26fb2 commit 78851bd

File tree

3 files changed

+35
-6
lines changed

3 files changed

+35
-6
lines changed

src/index.js

+9
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const isNil = require('lodash/isNil'); // value == null
2828
const uniqueId = require('lodash/uniqueId');
2929
const transform = require('lodash/transform');
3030
const assign = require('lodash/assign');
31+
const isPlainObject = require('lodash/isPlainObject');
3132

3233
/* eslint-disable complexity */
3334
module.exports = (options = {}) => tree => {
@@ -61,6 +62,7 @@ module.exports = (options = {}) => tree => {
6162
template,
6263
get,
6364
has,
65+
isPlainObject,
6466
isObject: isObjectLike,
6567
isArray,
6668
isEmpty,
@@ -71,6 +73,13 @@ module.exports = (options = {}) => tree => {
7173
uniqueId,
7274
isEnabled: prop => prop === true || prop === ''
7375
};
76+
// Additional element attributes, in case already exist in valid-attributes.js it will replace all attributes
77+
// It should be an object with key as tag name and as value a function modifier which receive
78+
// the default attributes and return an array of attributes. Example:
79+
// { TAG: (attrsibutes) => { attrsibutes[] = 'attribute-name'; return attributes; } }
80+
options.elementAttributes = isPlainObject(options.elementAttributes) ? options.elementAttributes : {};
81+
options.safelistAttributes = Array.isArray(options.safelistAttributes) ? options.safelistAttributes : [];
82+
options.blacklistAttributes = Array.isArray(options.blacklistAttributes) ? options.blacklistAttributes : [];
7483

7584
// Merge customizer callback passed to lodash mergeWith
7685
// for merge attribute `props` and all attributes starting with `merge:`

src/process-attributes.js

+22-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const {match} = require('posthtml/lib/api');
44
const parseAttrs = require('posthtml-attrs-parser');
55
const styleToObject = require('style-to-object');
6+
const validAttributes = require('./valid-attributes');
67
const keys = require('lodash/keys');
78
const union = require('lodash/union');
89
const pick = require('lodash/pick');
@@ -12,7 +13,7 @@ const has = require('lodash/has');
1213
const extend = require('lodash/extend');
1314
const isString = require('lodash/isString');
1415
const isObject = require('lodash/isObject');
15-
const validAttributes = require('./valid-attributes');
16+
const isEmpty = require('lodash/isEmpty');
1617

1718
/**
1819
* Map component attributes that it's not defined as props to first element of node
@@ -45,10 +46,27 @@ module.exports = (currentNode, attributes, props, options, aware) => {
4546

4647
const nodeAttrs = parseAttrs(mainNode.attrs, options.attrsParserRules);
4748

49+
// Merge elementAttributes and blacklistAttributes with options provided
50+
validAttributes.blacklistAttributes = union(validAttributes.blacklistAttributes, options.blacklistAttributes);
51+
validAttributes.safelistAttributes = union(validAttributes.safelistAttributes, options.safelistAttributes);
52+
53+
// Merge or override elementAttributes from options provided
54+
if (!isEmpty(options.elementAttributes)) {
55+
each(options.elementAttributes, (tagName, modifier) => {
56+
if (typeof modifier === 'function' && isString(tagName)) {
57+
tagName = tagName.toUpperCase();
58+
const attributes = modifier(validAttributes.elementAttributes[tagName]);
59+
if (Array.isArray(attributes)) {
60+
validAttributes.elementAttributes[tagName] = attributes;
61+
}
62+
}
63+
});
64+
}
65+
4866
// Attributes to be excluded
49-
const excludeAttributes = union(validAttributes.blacklist, keys(props), [options.attribute], keys(aware), keys(options.props), ['$slots']);
67+
const excludeAttributes = union(validAttributes.blacklistAttributes, keys(props), [options.attribute], keys(aware), keys(options.props), ['$slots']);
5068
// All valid HTML attributes for the main element
51-
const allValidElementAttributes = validAttributes.elementAttributes[mainNode.tag.toUpperCase()];
69+
const allValidElementAttributes = isString(mainNode.tag) && has(validAttributes.elementAttributes, mainNode.tag.toUpperCase()) ? validAttributes.elementAttributes[mainNode.tag.toUpperCase()] : [];
5270
// Valid HTML attributes without the excluded
5371
const validElementAttributes = difference(allValidElementAttributes, excludeAttributes);
5472
// Add override attributes
@@ -59,7 +77,7 @@ module.exports = (currentNode, attributes, props, options, aware) => {
5977

6078
// Get additional specified attributes
6179
each(attributes, (value, attr) => {
62-
each(validAttributes.additionalAttributes, additionalAttr => {
80+
each(validAttributes.safelistAttributes, additionalAttr => {
6381
if (additionalAttr === attr || (additionalAttr.endsWith('*') && attr.startsWith(additionalAttr.replace('*', '')))) {
6482
mainNodeAttributes[attr] = value;
6583
}

src/valid-attributes.js

+4-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)