| '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); | 
|                     } | 
|                 } | 
|   | 
|             }); | 
|   | 
|         } | 
|   | 
|     } | 
|   | 
| }; |