151 lines
4.9 KiB
JavaScript
151 lines
4.9 KiB
JavaScript
'use strict';
|
|
|
|
exports.type = 'perItem';
|
|
|
|
exports.active = true;
|
|
|
|
exports.description = 'removes unknown elements content and attributes, removes attrs with default values';
|
|
|
|
exports.params = {
|
|
unknownContent: true,
|
|
unknownAttrs: true,
|
|
defaultAttrs: true,
|
|
uselessOverrides: true,
|
|
keepDataAttrs: true,
|
|
keepAriaAttrs: true,
|
|
keepRoleAttr: false
|
|
};
|
|
|
|
var collections = require('./_collections'),
|
|
elems = collections.elems,
|
|
attrsGroups = collections.attrsGroups,
|
|
elemsGroups = collections.elemsGroups,
|
|
attrsGroupsDefaults = collections.attrsGroupsDefaults,
|
|
attrsInheritable = collections.inheritableAttrs,
|
|
applyGroups = collections.presentationNonInheritableGroupAttrs;
|
|
|
|
// collect and extend all references
|
|
for (var elem in elems) {
|
|
elem = elems[elem];
|
|
|
|
if (elem.attrsGroups) {
|
|
elem.attrs = elem.attrs || [];
|
|
|
|
elem.attrsGroups.forEach(function(attrsGroupName) {
|
|
elem.attrs = elem.attrs.concat(attrsGroups[attrsGroupName]);
|
|
|
|
var groupDefaults = attrsGroupsDefaults[attrsGroupName];
|
|
|
|
if (groupDefaults) {
|
|
elem.defaults = elem.defaults || {};
|
|
|
|
for (var attrName in groupDefaults) {
|
|
elem.defaults[attrName] = groupDefaults[attrName];
|
|
}
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
if (elem.contentGroups) {
|
|
elem.content = elem.content || [];
|
|
|
|
elem.contentGroups.forEach(function(contentGroupName) {
|
|
elem.content = elem.content.concat(elemsGroups[contentGroupName]);
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove unknown elements content and attributes,
|
|
* remove attributes with default values.
|
|
*
|
|
* @param {Object} item current iteration item
|
|
* @param {Object} params plugin params
|
|
* @return {Boolean} if false, item will be filtered out
|
|
*
|
|
* @author Kir Belevich
|
|
*/
|
|
exports.fn = function(item, params) {
|
|
|
|
// elems w/o namespace prefix
|
|
if (item.isElem() && !item.prefix) {
|
|
|
|
var elem = item.elem;
|
|
|
|
// remove unknown element's content
|
|
if (
|
|
params.unknownContent &&
|
|
!item.isEmpty() &&
|
|
elems[elem] && // make sure we know of this element before checking its children
|
|
elem !== 'foreignObject' // Don't check foreignObject
|
|
) {
|
|
item.content.forEach(function(content, i) {
|
|
if (
|
|
content.isElem() &&
|
|
!content.prefix &&
|
|
(
|
|
(
|
|
elems[elem].content && // Do we have a record of its permitted content?
|
|
elems[elem].content.indexOf(content.elem) === -1
|
|
) ||
|
|
(
|
|
!elems[elem].content && // we dont know about its permitted content
|
|
!elems[content.elem] // check that we know about the element at all
|
|
)
|
|
)
|
|
) {
|
|
item.content.splice(i, 1);
|
|
}
|
|
});
|
|
}
|
|
|
|
// remove element's unknown attrs and attrs with default values
|
|
if (elems[elem] && elems[elem].attrs) {
|
|
|
|
item.eachAttr(function(attr) {
|
|
|
|
if (
|
|
attr.name !== 'xmlns' &&
|
|
(attr.prefix === 'xml' || !attr.prefix) &&
|
|
(!params.keepDataAttrs || attr.name.indexOf('data-') != 0) &&
|
|
(!params.keepAriaAttrs || attr.name.indexOf('aria-') != 0) &&
|
|
(!params.keepRoleAttr || attr.name != 'role')
|
|
) {
|
|
if (
|
|
// unknown attrs
|
|
(
|
|
params.unknownAttrs &&
|
|
elems[elem].attrs.indexOf(attr.name) === -1
|
|
) ||
|
|
// attrs with default values
|
|
(
|
|
params.defaultAttrs &&
|
|
!item.hasAttr('id') &&
|
|
elems[elem].defaults &&
|
|
elems[elem].defaults[attr.name] === attr.value && (
|
|
attrsInheritable.indexOf(attr.name) < 0 ||
|
|
!item.parentNode.computedAttr(attr.name)
|
|
)
|
|
) ||
|
|
// useless overrides
|
|
(
|
|
params.uselessOverrides &&
|
|
!item.hasAttr('id') &&
|
|
applyGroups.indexOf(attr.name) < 0 &&
|
|
attrsInheritable.indexOf(attr.name) > -1 &&
|
|
item.parentNode.computedAttr(attr.name, attr.value)
|
|
)
|
|
) {
|
|
item.removeAttr(attr.name);
|
|
}
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|