@happeouikit/content-renderer 2.0.0 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.0.3
4
+
5
+ - [Added] Added prop `forceDefaultLinkTarget` that will force external links with `target="_blank"` and removes `target` from internal links.
6
+
7
+ ## 3.0.2
8
+
9
+ - [Fixed] ContentRenderer now applies styling options from Pages
10
+
11
+ ## 3.0.1
12
+
13
+ - [Fixed] ContentRenderer should now deal with all kinds of xss
14
+
15
+ ## 3.0.0
16
+
17
+ - [Fixed] the xss converter now accepts a whiteList for CSS properties that includes vertical-align
18
+ - [Updated] new dependencies updates: React 17 and and Styled Components 5
19
+
20
+ ## 2.0.1
21
+
22
+ - [Added] Changed type to uppercase and to handle both upper and lowercase. Add warning if lowecase is used.
23
+ - [Added] Handle widgetType=`page` by removing forced styles from component.
24
+
3
25
  ## 2.0.0
4
26
 
5
27
  - [Breaking change] Links rendered from markdown content now always open in a new tab (not configurable).
@@ -59,7 +59,7 @@ function _templateObject() {
59
59
  * ContentRenderer
60
60
  *
61
61
  */
62
- import React, { useRef, useEffect, useState, useCallback } from "react";
62
+ import React, { useRef, useEffect, useState, useCallback, useMemo } from "react";
63
63
  import ReactDOM from "react-dom";
64
64
  import PropTypes from "prop-types";
65
65
  import styled, { css } from "styled-components";
@@ -68,8 +68,11 @@ import { CopyToClipboardButton } from "@happeouikit/copy-to-clipboard-button";
68
68
  import { BodyUI, sansFamily } from "@happeouikit/typography";
69
69
  import { margin200, media, padding200 } from "@happeouikit/layout";
70
70
  import { active, gray04, gray07, gray09, lighten, warn } from "@happeouikit/colors";
71
- import { toHtml, toSafeText, loadCodeFont, decodeHtmlEntities, removeSpecialCharacters } from "./utils";
71
+ import { toHtml, loadCodeFont, decodeHtmlEntities, removeSpecialCharacters, toSafeText } from "./utils";
72
72
  import { ELEMENT_TYPE_PRE, ELEMENT_TYPE_CODE, HIGHLIGHJS_CSS, HIGHLIGHJS_JS, CODE_BLOCK_AVAILABLE_LANGUAGES } from "./constants";
73
+ import { jsx as _jsx } from "react/jsx-runtime";
74
+ import { Fragment as _Fragment } from "react/jsx-runtime";
75
+ import { jsxs as _jsxs } from "react/jsx-runtime";
73
76
 
74
77
  var ContentRenderer = function ContentRenderer(_ref) {
75
78
  var content = _ref.content,
@@ -84,7 +87,8 @@ var ContentRenderer = function ContentRenderer(_ref) {
84
87
  useHashAutoscroll = _ref.useHashAutoscroll,
85
88
  _ref$hashAutoscrollTo = _ref.hashAutoscrollTopMargin,
86
89
  hashAutoscrollTopMargin = _ref$hashAutoscrollTo === void 0 ? 0 : _ref$hashAutoscrollTo,
87
- decodeHtmlEntitiesOnRender = _ref.decodeHtmlEntitiesOnRender;
90
+ decodeHtmlEntitiesOnRender = _ref.decodeHtmlEntitiesOnRender,
91
+ forceDefaultLinkTarget = _ref.forceDefaultLinkTarget;
88
92
  var element = useRef({});
89
93
 
90
94
  var _useState = useState([]),
@@ -132,6 +136,21 @@ var ContentRenderer = function ContentRenderer(_ref) {
132
136
  });
133
137
  }
134
138
 
139
+ var linkElems = forceDefaultLinkTarget ? element.current.querySelectorAll("a") : [];
140
+
141
+ if (linkElems.length > 0) {
142
+ var currentOrigin = window.origin;
143
+ linkElems.forEach(function (link) {
144
+ var href = link.href;
145
+
146
+ if (href.startsWith(currentOrigin)) {
147
+ delete link.target;
148
+ } else {
149
+ link.target = "_blank";
150
+ }
151
+ });
152
+ }
153
+
135
154
  var blockElems = element.current.querySelectorAll(ELEMENT_TYPE_PRE);
136
155
 
137
156
  if (blockElems.length > 0) {
@@ -171,46 +190,48 @@ var ContentRenderer = function ContentRenderer(_ref) {
171
190
  if (useHashAutoscroll) {
172
191
  scrollAndHighlightHash();
173
192
  }
174
- }, [element, createAnchors, useHashAutoscroll, scrollAndHighlightHash]);
175
- var transformedContent = toHtml(content, type);
193
+ }, [element, createAnchors, forceDefaultLinkTarget, useHashAutoscroll, scrollAndHighlightHash]);
194
+ var safeText = useMemo(function () {
195
+ var lowercaseType = type && typeof type === "string" ? type.toLowerCase() : "html";
196
+ var transformedContent = lowercaseType === "text" ? toSafeText("<p>".concat(content, "</p>")) : toHtml(content, lowercaseType);
176
197
 
177
- if (type === "text") {
178
- transformedContent = "<p>".concat(transformedContent, "</p>");
179
- }
180
-
181
- if (decodeHtmlEntitiesOnRender) {
182
- transformedContent = decodeHtmlEntities(transformedContent);
183
- }
198
+ if (decodeHtmlEntitiesOnRender) {
199
+ transformedContent = decodeHtmlEntities(transformedContent);
200
+ }
184
201
 
185
- var safeText = toSafeText(transformedContent); // Use dangerouslySetInnerHTML as there might be nested <p>'s header etc
202
+ return transformedContent;
203
+ }, [content, type, decodeHtmlEntitiesOnRender]); // Use dangerouslySetInnerHTML as there might be nested <p>'s header etc
186
204
  // This requires that all content is run through the toSafeText filter
187
205
  // before displaying. This will run it through xss filter.
188
206
 
189
- return React.createElement(React.Fragment, null, React.createElement(Wrapper, {
190
- className: "content-renderer",
191
- ref: element,
192
- widgetType: widgetType,
193
- headerFont: headerFont,
194
- bodyFont: bodyFont,
195
- createAnchors: createAnchors,
196
- dangerouslySetInnerHTML: {
197
- __html: safeText
198
- }
199
- }), copyBtns.map(function (el) {
200
- var clipboardContent = el.textContent || "";
201
-
202
- if (el.tagName !== ELEMENT_TYPE_PRE) {
203
- clipboardContent = "".concat(window.location.href.split("#")[0], "#").concat(el.id);
204
- } // eslint-disable-next-line no-control-regex
205
-
206
-
207
- clipboardContent = removeSpecialCharacters(clipboardContent);
208
- return ReactDOM.createPortal(React.createElement(BtnContainer, {
209
- className: "content-copy-btn"
210
- }, React.createElement(CopyToClipboardButton, {
211
- clipboardContent: clipboardContent
212
- })), el);
213
- }));
207
+ return /*#__PURE__*/_jsxs(_Fragment, {
208
+ children: [/*#__PURE__*/_jsx(Wrapper, {
209
+ className: "content-renderer ".concat(widgetType === "page" ? "fr-view pages-text" : ""),
210
+ ref: element,
211
+ widgetType: widgetType,
212
+ headerFont: headerFont,
213
+ bodyFont: bodyFont,
214
+ createAnchors: createAnchors,
215
+ dangerouslySetInnerHTML: {
216
+ __html: safeText
217
+ }
218
+ }), copyBtns.map(function (el) {
219
+ var clipboardContent = el.textContent || "";
220
+
221
+ if (el.tagName !== ELEMENT_TYPE_PRE) {
222
+ clipboardContent = "".concat(window.location.href.split("#")[0], "#").concat(el.id);
223
+ } // eslint-disable-next-line no-control-regex
224
+
225
+
226
+ clipboardContent = removeSpecialCharacters(clipboardContent);
227
+ return /*#__PURE__*/ReactDOM.createPortal( /*#__PURE__*/_jsx(BtnContainer, {
228
+ className: "content-copy-btn",
229
+ children: /*#__PURE__*/_jsx(CopyToClipboardButton, {
230
+ clipboardContent: clipboardContent
231
+ })
232
+ }), el);
233
+ })]
234
+ });
214
235
  };
215
236
 
216
237
  var BtnContainer = styled.div.withConfig({
@@ -222,23 +243,36 @@ var Wrapper = styled(BodyUI).attrs({
222
243
  }).withConfig({
223
244
  displayName: "ContentRenderer__Wrapper",
224
245
  componentId: "sc-1mleu9k-1"
225
- })(["*{font-family:", " !important;}", " h1.highlight,h2.highlight,h3.highlight,h4.highlight,h5.highlight,h6.highlight{border-radius:6px;position:relative;:after{content:\" \";position:absolute;top:-8px;bottom:-8px;left:-8px;right:-8px;border-radius:6px;border:5px solid ", ";}}h1{font-weight:500;font-size:24px;letter-spacing:-0.5px;line-height:32px;+ h1,+ h2,+ h3,+ h4,+ p{margin-top:16px;}}h2{font-weight:500;font-size:20px;line-height:28px;+ h1,+ h2,+ h3,+ h4,+ p{margin-top:14px;}}h3{font-weight:500;font-size:16px;line-height:24px;+ h1,+ h2,+ h3,+ h4,+ p{margin-top:12px;}}h4{font-size:16px;line-height:24px;+ h1,+ h2,+ h3,+ h4,+ p{margin-top:12px;}}p{font-size:16px;line-height:24px;letter-spacing:0px;+ h1,+ h2,+ h3,+ h4,+ p{margin-top:12px;}}a{color:", ";text-decoration:none;:hover{text-decoration:underline;}}ul{list-style-type:disc;}ol{list-style-type:decimal;counter-reset:item;li{padding-left:12px;text-indent:-33px;list-style-type:none;counter-increment:item;&:before{display:inline-block;width:13px;padding-right:15px;padding-left:5px;font-weight:bold;text-align:right;content:counter(item) \".\";}}}ol,ul{font-size:16px;line-height:24px;margin:18px 16px;display:block;-webkit-margin-before:0.5em;-webkit-margin-after:0.5em;-webkit-padding-start:0.5em;li,li{margin-bottom:5px;padding-left:10px;> ul,> ol{-webkit-margin-before:8px !important;-webkit-margin-after:8px !important;}}&:first-child,&:first-child{-webkit-margin-before:0;}&:last-child,&:last-child{-webkit-margin-after:0;}}hr{-webkit-margin-before:16px;-webkit-margin-after:13px;border-color:@border-color;border-style:solid;height:0px;border-width:1px 0 0 0;}table{width:100%;margin:15px 0;text-align:left;thead th{background:@white;}th,td{border-width:1px;border-style:solid;border-color:@border-color;padding:0.5em;}tr:nth-child(even){background:@almost-white;}tr:nth-child(odd){background:@white;}}table.no-borders{th,td{border:none;}}table.padded-2{th,td{padding:2em;}}table.padded-1{th,td{padding:1em;}}img{max-width:100%;margin:15px 0;& + img{margin-top:0;}}.xl-emoji *{font-size:40px;line-height:1.2;}pre{border-radius:4px;background:", ";padding:8px;margin-bottom:10px;overflow:auto;white-space:pre;position:relative;overflow:visible;*:not(p){font-weight:inherit;font-family:\"IBM Plex Mono\",monospace !important;}.content-copy-btn{position:absolute;top:0;right:0;padding:", " 0;}:hover button{opacity:1;}}blockquote{border-top:2px solid ", ";border-bottom:2px solid ", ";font-size:18px;padding:24px 48px;position:relative;text-align:center;margin:48px 0;}.mention{border-radius:0.2em;background-color:#fff5cc;border:1px solid #fff5cc;color:#0f1621;font-weight:400;&:hover{text-decoration:none;border:1px solid #fabd24;}}.extraMention{cursor:inherit;}", ""], sansFamily, function (_ref2) {
246
+ })(["", " h1.highlight,h2.highlight,h3.highlight,h4.highlight,h5.highlight,h6.highlight{border-radius:6px;position:relative;:after{content:\" \";position:absolute;top:-8px;bottom:-8px;left:-8px;right:-8px;border-radius:6px;border:5px solid ", ";}}pre{border-radius:4px;background:", ";padding:8px;margin-bottom:10px;overflow:auto;white-space:pre;position:relative;overflow:visible;*:not(p){font-weight:inherit;font-family:\"IBM Plex Mono\",monospace !important;}.content-copy-btn{position:absolute;top:0;right:0;padding:", " 0;}:hover button{opacity:1;}}.mention{border-radius:0.2em;background-color:#fff5cc;border:1px solid #fff5cc;color:#0f1621;font-weight:400;&:hover{text-decoration:none;border:1px solid #fabd24;}}.extraMention{cursor:inherit;}", " ", ""], function (_ref2) {
226
247
  var createAnchors = _ref2.createAnchors;
227
248
  return createAnchors ? "\n h1, h2, h3, h4, h5, h6 {\n display: flex;\n align-items: center;\n :hover button {\n opacity: 0.4;\n }\n }\n " : "";
228
- }, lighten(warn, 0.8), active, gray09, padding200, gray07, gray07, function (_ref3) {
229
- var widgetType = _ref3.widgetType,
230
- bodyFont = _ref3.bodyFont,
231
- headerFont = _ref3.headerFont;
249
+ }, lighten(warn, 0.8), gray09, padding200, function (_ref3) {
250
+ var widgetType = _ref3.widgetType;
251
+ return widgetType === "page" ? "" : "\n * {\n font-family: ".concat(sansFamily, " !important;\n }\n\n \n\n h1 {\n font-weight: 500;\n font-size: 24px;\n letter-spacing: -0.5px;\n line-height: 32px;\n + h1,\n + h2,\n + h3,\n + h4,\n + p {\n margin-top: 16px;\n }\n }\n h2 {\n font-weight: 500;\n font-size: 20px;\n line-height: 28px;\n + h1,\n + h2,\n + h3,\n + h4,\n + p {\n margin-top: 14px;\n }\n }\n h3 {\n font-weight: 500;\n font-size: 16px;\n line-height: 24px;\n + h1,\n + h2,\n + h3,\n + h4,\n + p {\n margin-top: 12px;\n }\n }\n h4 {\n font-size: 16px;\n line-height: 24px;\n + h1,\n + h2,\n + h3,\n + h4,\n + p {\n margin-top: 12px;\n }\n }\n p {\n font-size: 16px;\n line-height: 24px;\n letter-spacing: 0px;\n + h1,\n + h2,\n + h3,\n + h4,\n + p {\n margin-top: 12px;\n }\n }\n a {\n color: ").concat(active, ";\n text-decoration: none;\n :hover {\n text-decoration: underline;\n }\n }\n ul {\n list-style-type: disc;\n }\n ol {\n list-style-type: decimal;\n counter-reset: item;\n li {\n padding-left: 12px;\n text-indent: -33px;\n list-style-type: none;\n counter-increment: item;\n &:before {\n display: inline-block;\n width: 13px;\n padding-right: 15px;\n padding-left: 5px;\n font-weight: bold;\n text-align: right;\n content: counter(item) \".\";\n }\n }\n }\n ol,\n ul {\n font-size: 16px;\n line-height: 24px;\n margin: 18px 16px;\n display: block;\n -webkit-margin-before: 0.5em;\n -webkit-margin-after: 0.5em;\n -webkit-padding-start: 0.5em;\n li,\n li {\n margin-bottom: 5px;\n padding-left: 10px;\n > ul,\n > ol {\n -webkit-margin-before: 8px !important;\n -webkit-margin-after: 8px !important;\n }\n }\n\n &:first-child,\n &:first-child {\n -webkit-margin-before: 0;\n }\n &:last-child,\n &:last-child {\n -webkit-margin-after: 0;\n }\n }\n hr {\n -webkit-margin-before: 16px;\n -webkit-margin-after: 13px;\n border-color: @border-color;\n border-style: solid;\n height: 0px;\n border-width: 1px 0 0 0;\n }\n table {\n width: 100%;\n margin: 15px 0;\n text-align: left;\n thead th {\n background: @white;\n }\n th,\n td {\n border-width: 1px;\n border-style: solid;\n border-color: @border-color;\n padding: 0.5em;\n }\n tr:nth-child(even) {\n background: @almost-white;\n }\n tr:nth-child(odd) {\n background: @white;\n }\n }\n table.no-borders {\n th,\n td {\n border: none;\n }\n }\n table.padded-2 {\n th,\n td {\n padding: 2em;\n }\n }\n table.padded-1 {\n th,\n td {\n padding: 1em;\n }\n }\n img {\n max-width: 100%;\n margin: 15px 0;\n & + img {\n margin-top: 0;\n }\n }\n .xl-emoji * {\n font-size: 40px;\n line-height: 1.2;\n }\n \n blockquote {\n border-top: 2px solid ").concat(gray07, ";\n border-bottom: 2px solid ").concat(gray07, ";\n font-size: 18px;\n padding: 24px 48px;\n position: relative;\n text-align: center;\n margin: 48px 0;\n }\n ");
252
+ }, function (_ref4) {
253
+ var widgetType = _ref4.widgetType,
254
+ bodyFont = _ref4.bodyFont,
255
+ headerFont = _ref4.headerFont;
232
256
  return widgetType === "article" && css(["h1,h2,h3{font-family:", " !important;& *{font-family:", " !important;}}h4,h5,h6,p,ul,ol,li,table{font-family:", " !important;& *{font-family:", " !important;}}h1{font-size:32px;line-height:1.13;margin:0 0 20px;letter-spacing:-0.75px;}h2{font-size:24px;line-height:1.17;margin:0 0 16px;letter-spacing:-0.5px;}h3{font-size:20px;line-height:1.2;margin:0 0 14px;}h4,h5,h6,p,ul,ol,li{font-size:18px;line-height:1.56;margin-bottom:13px;margin-top:0;}hr{border-color:", ";}table{width:100% !important;margin:15px 0;font-size:18px !important;text-align:left;border-collapse:collapse;border-spacing:0;thead th{background:@white;}th,td{border-width:1px;border-style:solid;border-color:", ";padding:0.5em;word-wrap:break-word;}tr:nth-child(odd){background:", ";}tr:nth-child(even){background:@white;}}table.no-borders{th,td{border:none;}tr:nth-child(odd){background:", ";}tr:nth-child(even){background:@white;}}pre{position:relative;background-color:", ";padding:1em;margin:1em 0;border-radius:4px;white-space:pre;}img,span.fr-img-caption,span.fr-video{display:block;margin:30px 0;", ";&.article-align-left{margin:30px auto;display:block;max-width:100%;", "}&.article-align-center{margin:30px auto;display:block;}&.article-align-right{margin:30px auto;display:block;max-width:100%;", "}&.article-align-overflow{margin:30px auto;display:block;max-width:100%;", " img{width:100%;}}}img{&.image-border-radius{border-radius:6px;}&.image-box-shadow{box-shadow:0 4px 16px 0 #bacad5;}}span.fr-img-caption{&.image-border-radius img{border-radius:6px;}&.image-box-shadow img{box-shadow:0 4px 16px 0 #bacad5;}}p{img:first-child,span.fr-img-caption:first-child{&.article-align-left,&.article-align-right{", "}}}span.fr-img-caption{text-align:center;img{margin:0;}.fr-inner{font-weight:400;font-size:16px;margin:8px auto 0 auto;padding:0 8px;color:", ";display:block;max-width:671px;}}span.fr-video{position:relative;padding-bottom:56.25%;padding-top:30px;height:0;overflow:hidden;border-radius:6px;&.article-align-overflow{padding-top:170px;}iframe{position:absolute;top:0;left:0;width:100% !important;height:100% !important;}}blockquote{border-left:0 !important;padding-left:0 !important;margin:0 !important;color:inherit !important;p{line-height:30px;font-size:26px;text-align:center;margin:0 auto;}}.content-attachments{width:100%;}"], headerFont, headerFont, bodyFont, bodyFont, gray07, gray07, gray09, gray09, gray09, media.only.xs(_templateObject()), media.min.md(_templateObject2()), media.min.md(_templateObject3()), media.min.md(_templateObject4()), media.min.md(_templateObject5()), gray04);
233
257
  });
234
258
  ContentRenderer.propTypes = {
235
259
  content: PropTypes.string,
236
- type: PropTypes.oneOf(["html", "markdown", "text"]),
260
+ type: function type(props, propName) {
261
+ if (propName === "type" && props[propName] !== props[propName].toUpperCase()) {
262
+ // eslint-disable-next-line no-console
263
+ console.warn("Please use uppercase type 'HTML', 'MARKDOWN' or 'TEXT'");
264
+ }
265
+
266
+ if (propName === "type" && !["HTML", "MARKDOWN", "TEXT"].includes(props[propName].toUpperCase())) {
267
+ throw new Error("Invalid type, use 'HTML', 'MARKDOWN' or 'TEXT'");
268
+ }
269
+ },
237
270
  widgetType: PropTypes.oneOf(["post", "article", "page"]),
238
271
  bodyFont: PropTypes.string,
239
272
  headerFont: PropTypes.string,
240
273
  decodeHtmlEntitiesOnRender: PropTypes.bool,
241
274
  createAnchors: PropTypes.bool,
275
+ forceDefaultLinkTarget: PropTypes.bool,
242
276
  useHashAutoscroll: PropTypes.bool,
243
277
  hashAutoscrollTopMargin: PropTypes.number
244
278
  };
@@ -251,6 +285,7 @@ ContentRenderer.defaultProps = {
251
285
  decodeHtmlEntitiesOnRender: false,
252
286
  createAnchors: false,
253
287
  useHashAutoscroll: true,
288
+ forceDefaultLinkTarget: false,
254
289
  hashAutoscrollTopMargin: 0
255
290
  };
256
291
  export default ContentRenderer;
package/dist/utils.js CHANGED
@@ -1,3 +1,9 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+
3
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
4
+
5
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
6
+
1
7
  import linkifyHtml from "linkifyjs/html";
2
8
  import xss from "xss";
3
9
  import { decode as decodeHtmlEntities } from "html-entities";
@@ -22,6 +28,26 @@ var processMentions = function processMentions() {
22
28
  var str = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
23
29
  return str.replace(mentioningRegexGroupCaseInsensitive, processMatch).replace(mentioningHtmlRegexGroupCaseInsensitive, processMatch);
24
30
  };
31
+ /**
32
+ * @name toSafeText
33
+ * @description Returns filtered text with filterXSS library
34
+ * @author Antero Hanhirova
35
+ * @param {String} - Text to whitelist
36
+ * @returns {String}
37
+ */
38
+
39
+
40
+ var toSafeText = function toSafeText(text) {
41
+ return xss(text, {
42
+ whiteList: safeTagsAndAttributes,
43
+ css: {
44
+ whiteList: _objectSpread({}, xss.getDefaultCSSWhiteList(), {
45
+ "vertical-align": true
46
+ })
47
+ },
48
+ stripIgnoreTag: true
49
+ }).replace(/&nbsp;/g, " ").replace(/\u2060/g, ""); // Replaces a hidden character that resulted in a "?"-character in backend
50
+ };
25
51
  /**
26
52
  * @name toHtml
27
53
  * @description Converts markdown to html, adds space to end of String
@@ -44,26 +70,12 @@ var toHtml = function toHtml() {
44
70
  newString = processMentions(newString);
45
71
  }
46
72
 
73
+ newString = toSafeText(newString);
47
74
  return linkifyHtml(newString, {
48
75
  target: "_blank",
49
76
  ignoreTags: ["pre", "code", "script", "style"]
50
77
  });
51
78
  };
52
- /**
53
- * @name toSafeText
54
- * @description Returns filtered text with filterXSS library
55
- * @author Antero Hanhirova
56
- * @param {String} - Text to whitelist
57
- * @returns {String}
58
- */
59
-
60
-
61
- var toSafeText = function toSafeText(text) {
62
- return xss(text, {
63
- whiteList: safeTagsAndAttributes,
64
- stripIgnoreTag: true
65
- }).replace(/&nbsp;/g, " ").replace(/\u2060/g, ""); // Replaces a hidden character that resulted in a "?"-character in backend
66
- };
67
79
 
68
80
  var loadCodeFont = function loadCodeFont() {
69
81
  var id = "ibmMonoOnDemand";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happeouikit/content-renderer",
3
- "version": "2.0.0",
3
+ "version": "3.0.2",
4
4
  "description": "Rendering html and markdown content",
5
5
  "main": "dist/index.js",
6
6
  "module": "src/index.js",
@@ -29,8 +29,8 @@
29
29
  },
30
30
  "peerDependencies": {
31
31
  "prop-types": "^15.6.2",
32
- "react": "^16.6.3",
33
- "styled-components": "^4.1.1"
32
+ "react": "^17.0.2",
33
+ "styled-components": "^5.3.1"
34
34
  },
35
35
  "publishConfig": {
36
36
  "access": "public"