Advertisement
Guest User

Untitled

a guest
Jun 17th, 2019
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.   /**
  2.    * Purify HTML using a custom rules set.
  3.    * @param dirtyHTML The dirty HTML.
  4.    * @param rules Array of Rules.
  5.    *
  6.    * Example of rules:
  7.    * [
  8.    *   {
  9.    *     selector: 'p',
  10.    *     allowedAttributes: ['class']
  11.    *   }
  12.    * ]
  13.    * Will only allow <p> tags and will only keep 'class' attribute on those <p> tags.
  14.    */
  15.   purify(dirtyHTML: string, rules: { selector: string, allowedAttributes: string[] }[]) {
  16.     const sandbox: HTMLDivElement = this.renderer2.createElement('div');
  17.     this.renderer2.setProperty(sandbox, 'innerHTML', dirtyHTML);
  18.  
  19.     // First, we remove all elements which does not match with our selectors.
  20.     const blacklistSelector = rules.map(rule => `:not(${rule.selector})`).join(',');
  21.     const blacklistedElements = sandbox.querySelectorAll(blacklistSelector);
  22.     blacklistedElements.forEach((blacklistedElement) => {
  23.       /**
  24.        * outerHTML = innerHTML is equivalent to removing the HTML tag
  25.        * Example: <p>test</p> => test
  26.        */
  27.       this.renderer2.setProperty(blacklistedElement, 'outerHTML', blacklistedElement.innerHTML);
  28.     });
  29.  
  30.  
  31.     // Then, we remove unwanted attributes (those which are not explicitly whitelisted in the rule set)
  32.     rules.forEach(rule => {
  33.       const nodes = sandbox.querySelectorAll(`:not(${rule.selector}`);
  34.  
  35.       nodes.forEach((element: Element) => {
  36.         /**
  37.          * We need to convert element.attributes since it is not an implementation of Array.
  38.          * @see https://www.w3schools.com/jsref/prop_node_attributes.asp
  39.          * @see NamedNodeMap
  40.          */
  41.         const blacklistedAttributes = Array.from(element.attributes)
  42.           .map(attribute => attribute.name)
  43.           .filter(attributeName => !rule.allowedAttributes.includes(attributeName));
  44.         blacklistedAttributes.forEach(blacklistedAttributeName => {
  45.           element.removeAttribute(blacklistedAttributeName);
  46.         });
  47.       });
  48.     });
  49.  
  50.     // Finally, we get the clean HTML and destroy the sandbox
  51.     const cleanHTML = sandbox.innerHTML;
  52.     this.renderer2.destroyNode(sandbox);
  53.  
  54.     return cleanHTML;
  55.   }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement