├── .gitignore ├── .babelrc ├── CHANGELOG.md ├── __tests__ └── render.js ├── LICENSE.md ├── package.json ├── src └── index.js ├── .travis.yml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /lib 2 | /node_modules 3 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "@babel/plugin-proposal-object-rest-spread" 4 | ], 5 | "presets": [ 6 | ["@babel/preset-env", { 7 | "forceAllTransforms": true 8 | }], 9 | "@babel/preset-react" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [Unreleased] 8 | ### Changed 9 | - Updated Babel to `@7.1` 10 | - Support `react@^16.0.0` 11 | - Moved to stateless component 12 | 13 | ## [2.0.0] - 2017-12-08 14 | ### Added 15 | - First documented release 16 | -------------------------------------------------------------------------------- /__tests__/render.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import React from 'react'; 4 | import ReactDOMServer from 'react-dom/server'; 5 | import SanitizedHTML from '../'; 6 | 7 | describe('SanitizedHTML', () => { 8 | test('should render tag correctly', () => { 9 | expect( 10 | ReactDOMServer.renderToStaticMarkup( 11 | Bing' }/> 12 | ) 13 | ).toBe('
Bing
'); 14 | }); 15 | 16 | test('should render only allowed tags', () => { 17 | expect( 18 | ReactDOMServer.renderToStaticMarkup( 19 | Bing' } 22 | /> 23 | ) 24 | ).toBe('
Bing
'); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 William Wong 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-sanitized-html", 3 | "version": "2.0.1-0", 4 | "description": "A React component that will sanitize user-inputted HTML code, using the popular sanitize-html package", 5 | "main": "lib/index.js", 6 | "module": "lib/index.js", 7 | "files": [ 8 | "lib/*" 9 | ], 10 | "scripts": { 11 | "build": "babel ./src --out-dir ./lib --source-maps", 12 | "prepare": "rimraf lib && npm run build", 13 | "test": "jest", 14 | "watch": "npm run build -- --watch" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/compulim/react-sanitized-html.git" 19 | }, 20 | "keywords": [ 21 | "sanitize", 22 | "sanitizer", 23 | "react", 24 | "clean" 25 | ], 26 | "author": "William Wong (https://github.com/compulim)", 27 | "license": "MIT", 28 | "bugs": { 29 | "url": "https://github.com/compulim/react-sanitized-html/issues" 30 | }, 31 | "homepage": "https://github.com/compulim/react-sanitized-html#readme", 32 | "peerDependencies": { 33 | "prop-types": "^15.6.0", 34 | "react": "^16.0.0", 35 | "sanitize-html": "^1.16.1" 36 | }, 37 | "devDependencies": { 38 | "@babel/cli": "^7.1.2", 39 | "@babel/core": "^7.1.2", 40 | "@babel/plugin-proposal-object-rest-spread": "^7.0.0", 41 | "@babel/plugin-transform-runtime": "^7.1.0", 42 | "@babel/preset-env": "^7.1.0", 43 | "@babel/preset-react": "^7.0.0", 44 | "babel-core": "^7.0.0-bridge.0", 45 | "babel-jest": "^23.6.0", 46 | "jest": "^23.6.0", 47 | "prop-types": "^15.6.0", 48 | "react": "^16.0.0", 49 | "react-dom": "^16.2.0", 50 | "rimraf": "^2.6.2", 51 | "sanitize-html": "^1.16.1" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types' 2 | import React from 'react'; 3 | import sanitizeHTML from 'sanitize-html'; 4 | 5 | const SUPPORTED_SANITIZER_OPTIONS = [ 6 | 'allowProtocolRelative', 7 | 'allowedAttributes', 8 | 'allowedClasses', 9 | 'allowedSchemes', 10 | 'allowedSchemesByTag', 11 | 'allowedTags', 12 | 'exclusiveFilter', 13 | 'nonTextTags', 14 | 'parser', 15 | 'selfClosing', 16 | 'transformTags' 17 | ]; 18 | 19 | const SanitizedHTML = props => { 20 | const sanitizerOptions = SUPPORTED_SANITIZER_OPTIONS.reduce((options, name) => { 21 | const value = props[name]; 22 | 23 | if (typeof value !== 'undefined') { 24 | options[name] = value; 25 | } 26 | 27 | return options; 28 | }, {}); 29 | 30 | // TODO: Add memoization 31 | const sanitizedHTML = sanitizeHTML( 32 | props.html, 33 | sanitizerOptions 34 | ); 35 | 36 | return ( 37 |
43 | ); 44 | } 45 | 46 | SanitizedHTML.defaultProps = { 47 | html: '' 48 | }; 49 | 50 | SanitizedHTML.propTypes = { 51 | allowProtocolRelative: PropTypes.bool, 52 | allowedAttributes : PropTypes.objectOf(PropTypes.arrayOf(PropTypes.string)), 53 | allowedClasses : PropTypes.objectOf(PropTypes.arrayOf(PropTypes.string)), 54 | allowedSchemes : PropTypes.arrayOf(PropTypes.string), 55 | allowedSchemesByTag : PropTypes.objectOf(PropTypes.arrayOf(PropTypes.string)), 56 | allowedTags : PropTypes.arrayOf(PropTypes.string), 57 | exclusiveFilter : PropTypes.func, 58 | html : PropTypes.string.isRequired, 59 | nonTextTags : PropTypes.arrayOf(PropTypes.string), 60 | parser : PropTypes.any, 61 | selfClosing : PropTypes.arrayOf(PropTypes.string), 62 | transformTags : PropTypes.objectOf(PropTypes.oneOf([PropTypes.func, PropTypes.string])), 63 | 64 | className: PropTypes.string, 65 | id : PropTypes.string, 66 | style : PropTypes.any 67 | }; 68 | 69 | export default SanitizedHTML 70 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "10" 5 | 6 | before_script: 7 | - npm run build 8 | 9 | before_deploy: 10 | - git config --local user.name "William Wong" 11 | - git config --local user.email "compulim@hotmail.com" 12 | - npx version-from-git --travis 13 | 14 | deploy: 15 | - provider: npm 16 | api_key: 17 | secure: "s6teK2mePMYiChT+PgV4JnUWRhTWwTZjUVuLn30kmEpPBjtSnw2ZgryYIgiH7G7uQ0dxfgtjy6R8fv81iWb1sGNbSGSP6aqlOKKdfWmLViI7ajzmNkDivb1c0GwnllDTRk0R3QZLD5zGCJW8UejlZZ/qB9CNjIqYISOxqiw2YvpeIYGkFozizobVl2FRtACsyHZmSz8c2C2CkvCImggR/zDju3bze04V9haQaVQzTkJhbNsMKZ6B2uuVpGLjftb6nfYavYirwpPaQ9j3lqkbWXtv/pjz8mRKL1tvUTlwiSl9+rwcNGsRIeXs2KVj/+xCs9ZtgbEqtE3/s+gNhN2Gcmgw5LJKrndDcNsRBVhFQx7teG9xOdWmTzDOoHZ5qcNYwbLqYGyI9nCpMHKlH7KHbB3CGwXRCNNnzXcQI14z2DKmLZVKHwv41uZ6vWfzuI+Cp7LhfMbuoVb+bbulpTCeOcuoth670B0zA+6v0Q7emodLE1NTovrwhW7ayM63hlIhf+JDNRRZl35cRJFx7pZ+49Q00oscQ2C2nATcBm7CExCj8hfzU4QwTeb+0xYpt2Q9oTeCqUudg8jRWutz9BfzUBB9tuJOD8bEYQouKR0DR7woyzWf3OGu06frR9hZVnCO4aQ2lArW3GYQsAQPB/nczOZobfmx2BF4YB+r5byxTw8=" 18 | email: "compulim@hotmail.com" 19 | on: 20 | branch: master 21 | skip_cleanup: true 22 | tag: master 23 | - provider: npm 24 | api_key: 25 | secure: "s6teK2mePMYiChT+PgV4JnUWRhTWwTZjUVuLn30kmEpPBjtSnw2ZgryYIgiH7G7uQ0dxfgtjy6R8fv81iWb1sGNbSGSP6aqlOKKdfWmLViI7ajzmNkDivb1c0GwnllDTRk0R3QZLD5zGCJW8UejlZZ/qB9CNjIqYISOxqiw2YvpeIYGkFozizobVl2FRtACsyHZmSz8c2C2CkvCImggR/zDju3bze04V9haQaVQzTkJhbNsMKZ6B2uuVpGLjftb6nfYavYirwpPaQ9j3lqkbWXtv/pjz8mRKL1tvUTlwiSl9+rwcNGsRIeXs2KVj/+xCs9ZtgbEqtE3/s+gNhN2Gcmgw5LJKrndDcNsRBVhFQx7teG9xOdWmTzDOoHZ5qcNYwbLqYGyI9nCpMHKlH7KHbB3CGwXRCNNnzXcQI14z2DKmLZVKHwv41uZ6vWfzuI+Cp7LhfMbuoVb+bbulpTCeOcuoth670B0zA+6v0Q7emodLE1NTovrwhW7ayM63hlIhf+JDNRRZl35cRJFx7pZ+49Q00oscQ2C2nATcBm7CExCj8hfzU4QwTeb+0xYpt2Q9oTeCqUudg8jRWutz9BfzUBB9tuJOD8bEYQouKR0DR7woyzWf3OGu06frR9hZVnCO4aQ2lArW3GYQsAQPB/nczOZobfmx2BF4YB+r5byxTw8=" 26 | email: "compulim@hotmail.com" 27 | on: 28 | tags: true 29 | skip_cleanup: true 30 | - provider: releases 31 | api_key: 32 | secure: "dTUPB0/A//bKkUfwBQEM/OZkooE008judmz0Sd85xxLjy3CXi+Fvx+cwMZ1j4pWrlYyiaSa9RmDPn+1WwXtt3d6nTj8sHj4BFJLFk149lCwUREvScDFRUhyp7nwAdGU7A7LtA9u6vx5mj4zBTn/JoKA6cAYRqmQRNY0YkgBpCIrXjMEMPmm1V8mCd7LYPFqpjzlXbrEgO6izfSDlhsVH8CCpePN/NkDjmAJI5VH6v0Hr9dKAHFO8kbYFTzXZmP3y1HeIDsxCw631B+KpklLyXmwoDEmYerWTADD6L9QrQvDZc9hSckCOqJSDJHJ6/8OiHnDGxU3mhUJH+jZ1eLzxpeAMJoPZuEyrMC8Zzgle5O8OHywDVUUU/gZBiwYnjloDRKa+z5PsxD2IHqRcYEB5KLYz9RE+BWR+e2gH5Z9Nyob+aY0MkfMCZifu+i3TS1WWQJl5Vjg1BmR48K75aBrpPvrGQl1iZIhc2gxUpcADL3YG3nFcX5a+Uauxh941gabzAigCY6WAswHM2BS5OHg5662GtMZ3pj3yZScR9LSjvkgcbVqbmLspovxIZYh95KVr8Fvz44YdFtBlgZdqH9rvdEFhH4t9eBWZhePNMXXAiKZW5AYBVVAk+WRdsFUjAMizqkORi4VVDyuMyYm/cAuUhNmjhV1cU7PxPbh92DNVXts=" 33 | on: 34 | tags: true 35 | skip_cleanup: true 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-sanitized-html 2 | 3 | [![npm version](https://badge.fury.io/js/react-sanitized-html.svg)](https://npmjs.com/package/react-sanitized-html) [![Build Status](https://travis-ci.org/compulim/react-sanitized-html.svg?branch=master)](https://travis-ci.org/compulim/react-sanitized-html) [![Node.js dependencies](https://david-dm.org/compulim/react-sanitized-html.svg)](https://david-dm.org/compulim/react-sanitized-html) [![npm downloads](https://img.shields.io/npm/dm/react-sanitized-html.svg)](https://npmjs.com/package/react-sanitized-html) 4 | 5 | A React component that will sanitize user-inputted HTML code, using the popular [`sanitize-html`](https://npmjs.com/package/sanitize-html) package. 6 | 7 | # Install 8 | 9 | This React component requires both [`react`](https://npmjs.com/package/react) and [`sanitize-html`](https://npmjs.com/package/sanitize-html) to be installed to work. We marked both as peer dependency so you could use the version of React as it fit. 10 | 11 | Run `npm install react-sanitized-html sanitize-html --save` to install this package. 12 | 13 | > Because both [`htmlparser2`](https://npmjs.com/packages/htmlparser2) and [`domhandler`](https://npmjs.com/packages/domhandler) (dependencies of [`sanitize-html`](https://npmjs.com/packages/sanitize-html)) requires [ES2015 Property Accessors](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors) for shorthanded properties. Thus, this component cannot be used in IE8. 14 | 15 | > In [`sanitize-html@1.14.1`](https://npmjs.com/packages/sanitize-html), shorthands are not used. Thus, it is possible to build a workaround for IE8 by customizing both [`htmlparser2`] and [`domhandler`] without shorthands. 16 | 17 | # Example usage 18 | 19 | ```jsx 20 | import SanitizedHTML from 'react-sanitized-html'; 21 | 22 | const HTML_FROM_USER = 'Bing'; 23 | 24 | ReactDOM.render( 25 | , 26 | document.getElementById('reactRoot') 27 | ); 28 | ``` 29 | 30 | It will output as: 31 | 32 | ```html 33 |
34 | Bing 35 |
36 | ``` 37 | 38 | # Options 39 | 40 | You can add [`sanitize-html`](https://npmjs.com/package/sanitize-html) options as props. For example, 41 | 42 | ```html 43 | Bing` } 47 | /> 48 | ``` 49 | 50 | You can find more options [here](https://npmjs.com/package/sanitize-html). 51 | 52 | # Development 53 | 54 | To setup your development environment, after cloning the repository, run the following steps. 55 | 56 | ``` 57 | npm install react sanitize-html 58 | npm install --only=development 59 | ``` 60 | 61 | Then run `npm test` to run all tests. 62 | 63 | # Contribution 64 | 65 | Like us? [Star](https://github.com/compulim/react-sanitized-html/stargazers) us. 66 | 67 | Found an issue? [File](https://github.com/compulim/react-sanitized-html/issues) us an issue. 68 | --------------------------------------------------------------------------------